win32-semaphore 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9f9238e3788d95d1f36ffaf34a294a449d3f5cf1
4
+ data.tar.gz: 936daceae5621a20ec60ceee6c0d37bde279268a
5
+ SHA512:
6
+ metadata.gz: 256d91d371a994a456f00707e03c2e09e5ed6c63570a98a51db535b77b6d3c09ef62a04899cd42cf24fe2ee06f45657e3a67bc99d3b0bed402b552c22c0ec3ba
7
+ data.tar.gz: 47217dc543048157a8a5d6b61c40203ca05f9526d2e5333c5bf01597cb64e4c623e385de9394a26ffeada6cf3708eb9b79f5bbf61fd5b986bdce8ca3485ab1ff
data/CHANGES CHANGED
@@ -1,54 +1,59 @@
1
- == 0.4.1 - 10-Apr-2013
2
- * Fixed the HANDLE type in the underlying FFI code. This affects
3
- 64 bit versions of Ruby.
4
-
5
- == 0.4.0 - 10-Jul-2012
6
- * Converted source to use FFI.
7
- * Refactored tests.
8
- * Now requires Ruby 1.9 or later.
9
- * Removed the Error class. Now uses SystemCallError (Errno::) internally if
10
- a Windows function fails.
11
-
12
- == 0.3.2 - 23-Mar-2012
13
- * Refactored the Rakefile and cleaned up the gemspec.
14
- * Removed one test that was originally designed for the C version.
15
-
16
- == 0.3.1 - 11-Aug-2009
17
- * Changed license to Artistic 2.0.
18
- * The Semaphore.open method is now slightly more robust.
19
- * Renamed the test and example files.
20
- * Some gemspec updates, including license and description.
21
-
22
- == 0.3.0 - 3-May-2007
23
- * Now pure Ruby.
24
- * Added a Rakefile, with test, install and example tasks.
25
- * Both the Semaphore.new and Semaphore.open methods now accept a block, and
26
- automatically close the associated handle at the end of the block.
27
- * The Semaphore.new method now accepts an optional fourth argument that
28
- controls whether the Event object can be inherited by other processes.
29
- * Added a gemspec.
30
- * Removed the doc/semaphore.txt file. The documentation is now inlined via
31
- RDoc. There is also some documentation in the README file.
32
-
33
- == 0.2.2 - 10-Jun-2005
34
- * Now Unicode friendly.
35
- * Inlined rdoc documentation into the C source code.
36
- * Made the semaphore.txt file rdoc friendly.
37
- * Removed the semaphore.rd file.
38
-
39
- == 0.2.1 - 1-Mar-2005
40
- * Added a VERSION constant (oops).
41
- * Moved the 'examples' directory to the toplevel directory.
42
- * Made the CHANGES and README files rdoc friendly.
43
- * Removed an unused (and unnecessary) helper function in semaphore.h.
44
-
45
- == 0.2.0 - 16-Jul-2004
46
- * Modified to use the newer allocation framework. This means that as of this
47
- release, this package requires Ruby 1.8.0 or later.
48
- * Fixed a bug in the constructor where it was possible for the constructor to
49
- fail, but have no error raised.
50
- * Moved the test.rb file to the doc/examples directory.
51
- * Added more tests.
52
-
53
- == 0.1.0 - 14-May-2004
54
- * Initial release
1
+ == 0.4.2 - 21-Oct-2013
2
+ * Fixed the INVALID_HANDLE_VALUE constant for 64-bit Ruby.
3
+ * Added Rake as a development dependency.
4
+ * Fixed gem:create task for Rubygems 2.
5
+
6
+ == 0.4.1 - 10-Apr-2013
7
+ * Fixed the HANDLE type in the underlying FFI code. This affects
8
+ 64 bit versions of Ruby.
9
+
10
+ == 0.4.0 - 10-Jul-2012
11
+ * Converted source to use FFI.
12
+ * Refactored tests.
13
+ * Now requires Ruby 1.9 or later.
14
+ * Removed the Error class. Now uses SystemCallError (Errno::) internally if
15
+ a Windows function fails.
16
+
17
+ == 0.3.2 - 23-Mar-2012
18
+ * Refactored the Rakefile and cleaned up the gemspec.
19
+ * Removed one test that was originally designed for the C version.
20
+
21
+ == 0.3.1 - 11-Aug-2009
22
+ * Changed license to Artistic 2.0.
23
+ * The Semaphore.open method is now slightly more robust.
24
+ * Renamed the test and example files.
25
+ * Some gemspec updates, including license and description.
26
+
27
+ == 0.3.0 - 3-May-2007
28
+ * Now pure Ruby.
29
+ * Added a Rakefile, with test, install and example tasks.
30
+ * Both the Semaphore.new and Semaphore.open methods now accept a block, and
31
+ automatically close the associated handle at the end of the block.
32
+ * The Semaphore.new method now accepts an optional fourth argument that
33
+ controls whether the Event object can be inherited by other processes.
34
+ * Added a gemspec.
35
+ * Removed the doc/semaphore.txt file. The documentation is now inlined via
36
+ RDoc. There is also some documentation in the README file.
37
+
38
+ == 0.2.2 - 10-Jun-2005
39
+ * Now Unicode friendly.
40
+ * Inlined rdoc documentation into the C source code.
41
+ * Made the semaphore.txt file rdoc friendly.
42
+ * Removed the semaphore.rd file.
43
+
44
+ == 0.2.1 - 1-Mar-2005
45
+ * Added a VERSION constant (oops).
46
+ * Moved the 'examples' directory to the toplevel directory.
47
+ * Made the CHANGES and README files rdoc friendly.
48
+ * Removed an unused (and unnecessary) helper function in semaphore.h.
49
+
50
+ == 0.2.0 - 16-Jul-2004
51
+ * Modified to use the newer allocation framework. This means that as of this
52
+ release, this package requires Ruby 1.8.0 or later.
53
+ * Fixed a bug in the constructor where it was possible for the constructor to
54
+ fail, but have no error raised.
55
+ * Moved the test.rb file to the doc/examples directory.
56
+ * Added more tests.
57
+
58
+ == 0.1.0 - 14-May-2004
59
+ * Initial release
data/MANIFEST CHANGED
@@ -1,8 +1,8 @@
1
- * CHANGES
2
- * MANIFEST
3
- * README
4
- * Rakefile
5
- * win32-semaphore.gemspec
6
- * examples/example_semaphore.rb
7
- * lib/win32/semaphore.rb
1
+ * CHANGES
2
+ * MANIFEST
3
+ * README
4
+ * Rakefile
5
+ * win32-semaphore.gemspec
6
+ * examples/example_semaphore.rb
7
+ * lib/win32/semaphore.rb
8
8
  * test/test_win32_semaphore.rb
data/README CHANGED
@@ -1,57 +1,57 @@
1
- == Brief Description
2
- An interface for MS Windows Semaphores.
3
-
4
- == Prerequisites
5
- win32-ipc 0.6.0 or later.
6
-
7
- == Installation
8
- gem install win32-semaphore
9
-
10
- == Synopsis
11
- require 'win32/semaphore'
12
- include Win32
13
-
14
- Semaphore.new(1, 5, 'test') do |sem|
15
- puts 'uh, oh' unless sem.wait(10) > 0
16
- sem.release(2) # 2
17
- end
18
-
19
- == Documentation
20
- The semaphore.rb file contains inline RDoc documentation. If you installed
21
- this file as a gem, then you have the docs.
22
-
23
- For more detailed documentation about Semaphores on MS Windows in general,
24
- please visit http://www.msdn.com/library and lookup the CreateSemaphore(),
25
- OpenSemaphore() and ReleaseSemaphore() functions.
26
-
27
- == Notes
28
- The Semaphore class is a subclass of Win32::Ipc (win32-ipc). This package
29
- require's the win32-ipc package internally (you don't need to explicitly
30
- call it).
31
-
32
- == Acknowledgements
33
- Adapted originally from the Win32::Semaphore Perl module by Christopher
34
- J. Madsen.
35
-
36
- == Known Bugs
37
- None known. Any bugs should be reported on the project page at
38
- https://github.com/djberg96/win32-semaphore.
39
-
40
- == Future Plans
41
- Suggestions welcome.
42
-
43
- == License
44
- Artistic 2.0
45
-
46
- == Copyright
47
- (C) 2003-2013 Daniel J. Berger
48
- All Rights Reserved
49
-
50
- == Warranty
51
- This package is provided "as is" and without any express or
52
- implied warranties, including, without limitation, the implied
53
- warranties of merchantability and fitness for a particular purpose.
54
-
55
- == Authors
56
- Daniel J. Berger
57
- Park Heesob
1
+ == Brief Description
2
+ An interface for MS Windows Semaphores.
3
+
4
+ == Prerequisites
5
+ win32-ipc 0.6.0 or later.
6
+
7
+ == Installation
8
+ gem install win32-semaphore
9
+
10
+ == Synopsis
11
+ require 'win32/semaphore'
12
+ include Win32
13
+
14
+ Semaphore.new(1, 5, 'test') do |sem|
15
+ puts 'uh, oh' unless sem.wait(10) > 0
16
+ sem.release(2) # 2
17
+ end
18
+
19
+ == Documentation
20
+ The semaphore.rb file contains inline RDoc documentation. If you installed
21
+ this file as a gem, then you have the docs.
22
+
23
+ For more detailed documentation about Semaphores on MS Windows in general,
24
+ please visit http://www.msdn.com/library and lookup the CreateSemaphore(),
25
+ OpenSemaphore() and ReleaseSemaphore() functions.
26
+
27
+ == Notes
28
+ The Semaphore class is a subclass of Win32::Ipc (win32-ipc). This package
29
+ require's the win32-ipc package internally (you don't need to explicitly
30
+ call it).
31
+
32
+ == Acknowledgements
33
+ Adapted originally from the Win32::Semaphore Perl module by Christopher
34
+ J. Madsen.
35
+
36
+ == Known Bugs
37
+ None known. Any bugs should be reported on the project page at
38
+ https://github.com/djberg96/win32-semaphore.
39
+
40
+ == Future Plans
41
+ Suggestions welcome.
42
+
43
+ == License
44
+ Artistic 2.0
45
+
46
+ == Copyright
47
+ (C) 2003-2013 Daniel J. Berger
48
+ All Rights Reserved
49
+
50
+ == Warranty
51
+ This package is provided "as is" and without any express or
52
+ implied warranties, including, without limitation, the implied
53
+ warranties of merchantability and fitness for a particular purpose.
54
+
55
+ == Authors
56
+ Daniel J. Berger
57
+ Park Heesob
data/Rakefile CHANGED
@@ -1,31 +1,36 @@
1
- require 'rake'
2
- require 'rake/clean'
3
- require 'rake/testtask'
4
-
5
- CLEAN.include("**/*.gem")
6
-
7
- namespace :gem do
8
- desc 'Create the win32-semaphore gem'
9
- task :create => [:clean] do
10
- spec = eval(IO.read('win32-semaphore.gemspec'))
11
- Gem::Builder.new(spec).build
12
- end
13
-
14
- desc 'Install the win32-semaphore gem'
15
- task :install => [:create] do
16
- file = Dir["*.gem"].first
17
- sh "gem install #{file}"
18
- end
19
- end
20
-
21
- desc 'Run the example program'
22
- task :example do
23
- ruby '-Ilib examples/example_semaphore.rb'
24
- end
25
-
26
- Rake::TestTask.new do |t|
27
- t.verbose = true
28
- t.warning = true
29
- end
30
-
31
- task :default => :test
1
+ require 'rake'
2
+ require 'rake/clean'
3
+ require 'rake/testtask'
4
+
5
+ CLEAN.include("**/*.gem")
6
+
7
+ namespace :gem do
8
+ desc 'Create the win32-semaphore gem'
9
+ task :create => [:clean] do
10
+ spec = eval(IO.read('win32-semaphore.gemspec'))
11
+ if Gem::VERSION < "2.0.0"
12
+ Gem::Builder.new(spec).build
13
+ else
14
+ require 'rubygems/package'
15
+ Gem::Package.build(spec)
16
+ end
17
+ end
18
+
19
+ desc 'Install the win32-semaphore gem'
20
+ task :install => [:create] do
21
+ file = Dir["*.gem"].first
22
+ sh "gem install #{file}"
23
+ end
24
+ end
25
+
26
+ desc 'Run the example program'
27
+ task :example do
28
+ ruby '-Ilib examples/example_semaphore.rb'
29
+ end
30
+
31
+ Rake::TestTask.new do |t|
32
+ t.verbose = true
33
+ t.warning = true
34
+ end
35
+
36
+ task :default => :test
@@ -1,40 +1,40 @@
1
- ##############################################################
2
- # example_semaphore.rb
3
- #
4
- # A test script for general futzing. Modify as you see fit.
5
- #
6
- # Note that you can run this via the 'rake example' task.
7
- ##############################################################
8
- require "win32/semaphore"
9
- include Win32
10
-
11
- test = 1
12
- s = Semaphore.new(3,3,"test")
13
- test += 1
14
- puts "ok #{test}"
15
-
16
- print 'not ' unless s.wait(10) > 0
17
- test += 1
18
- puts "ok #{test}"
19
-
20
- print 'not ' unless s.wait(0) > 0
21
- test += 1
22
- puts "ok #{test}"
23
-
24
- printf "If you don't see 'ok %d' immediately, you'd better hit Ctrl-C\n", test+1
25
- print 'not ' unless s.wait > 0
26
- test += 1
27
- puts "ok #{test}"
28
-
29
- print 'not ' if s.wait(0) > 0
30
- test += 1
31
- puts "ok #{test}"
32
-
33
- s.release
34
- s.release(1)
35
-
36
- print 'not ' unless (result = s.release(1)) == 2
37
- test += 1
38
- puts "ok #{test}\t(result is #{result})"
39
-
1
+ ##############################################################
2
+ # example_semaphore.rb
3
+ #
4
+ # A test script for general futzing. Modify as you see fit.
5
+ #
6
+ # Note that you can run this via the 'rake example' task.
7
+ ##############################################################
8
+ require "win32/semaphore"
9
+ include Win32
10
+
11
+ test = 1
12
+ s = Semaphore.new(3,3,"test")
13
+ test += 1
14
+ puts "ok #{test}"
15
+
16
+ print 'not ' unless s.wait(10) > 0
17
+ test += 1
18
+ puts "ok #{test}"
19
+
20
+ print 'not ' unless s.wait(0) > 0
21
+ test += 1
22
+ puts "ok #{test}"
23
+
24
+ printf "If you don't see 'ok %d' immediately, you'd better hit Ctrl-C\n", test+1
25
+ print 'not ' unless s.wait > 0
26
+ test += 1
27
+ puts "ok #{test}"
28
+
29
+ print 'not ' if s.wait(0) > 0
30
+ test += 1
31
+ puts "ok #{test}"
32
+
33
+ s.release
34
+ s.release(1)
35
+
36
+ print 'not ' unless (result = s.release(1)) == 2
37
+ test += 1
38
+ puts "ok #{test}\t(result is #{result})"
39
+
40
40
  s.close
@@ -1,165 +1,165 @@
1
- require 'win32/ipc'
2
-
3
- # The Win32 module serves as a namespace only.
4
- module Win32
5
-
6
- # The Semaphore class encapsulates semaphore objects on Windows.
7
- class Semaphore < Ipc
8
- typedef :ulong, :dword
9
- typedef :uintptr_t, :handle
10
-
11
- ffi_lib :kernel32
12
-
13
- private
14
-
15
- class SecurityAttributes < FFI::Struct
16
- layout(
17
- :nLength, :dword,
18
- :lpSecurityDescriptor, :pointer,
19
- :bInheritHandle, :bool
20
- )
21
- end
22
-
23
- attach_function :CreateSemaphoreW, [:pointer, :long, :long, :buffer_in], :handle
24
- attach_function :OpenSemaphoreW, [:dword, :bool, :buffer_in], :handle
25
- attach_function :ReleaseSemaphore, [:handle, :long, :pointer], :bool
26
-
27
- private_class_method :CreateSemaphoreW, :OpenSemaphoreW, :ReleaseSemaphore
28
-
29
- SEMAPHORE_ALL_ACCESS = 0x1F0003
30
- INVALID_HANDLE_VALUE = 0xFFFFFFFF
31
-
32
- public
33
-
34
- # The version of the win32-semaphore library
35
- VERSION = '0.4.1'
36
-
37
- # The initial count for the semaphore object. This value must be greater
38
- # than or equal to zero and less than or equal to +max_count+. The state
39
- # of a semaphore is signaled when its count is greater than zero and
40
- # nonsignaled when it is zero. The count is decreased by one whenever
41
- # a wait function releases a thread that was waiting for the semaphore.
42
- # The count is increased by a specified amount by calling
43
- # Semaphore#release method.
44
- #
45
- attr_reader :initial_count
46
-
47
- # The maximum count for the semaphore object. This value must be
48
- # greater than zero.
49
- #
50
- attr_reader :max_count
51
-
52
- # The name of the Semaphore object.
53
- #
54
- attr_reader :name
55
-
56
- # Creates and returns new Semaphore object. If +name+ is omitted, the
57
- # Semaphore object is created without a name, i.e. it's anonymous.
58
- #
59
- # If +name+ is provided and it already exists, then it is opened
60
- # instead, and the +initial_count+ and +max_count+ parameters are
61
- # ignored.
62
- #
63
- # The +initial_count+ and +max_count+ parameters set the initial count
64
- # and maximum count for the Semaphore object, respectively. See the
65
- # documentation for the corresponding accessor for more information.
66
- #
67
- # The +inherit+ attribute determines whether or not the semaphore can
68
- # be inherited by child processes.
69
- #
70
- def initialize(initial_count, max_count, name=nil, inherit=true)
71
- @initial_count = initial_count
72
- @max_count = max_count
73
- @name = name
74
- @inherit = inherit
75
-
76
- if name && name.encoding.to_s != 'UTF-16LE'
77
- name = name + 0.chr
78
- name.encode!('UTF-16LE')
79
- end
80
-
81
- if inherit
82
- sec = SecurityAttributes.new
83
- sec[:nLength] = SecurityAttributes.size
84
- sec[:bInheritHandle] = true
85
- else
86
- sec = nil
87
- end
88
-
89
- handle = CreateSemaphoreW(sec, initial_count, max_count, name)
90
-
91
- if handle == 0 || handle == INVALID_HANDLE_VALUE
92
- raise SystemCallError.new("CreateSemaphore", FFI.errno)
93
- end
94
-
95
- super(handle)
96
-
97
- if block_given?
98
- begin
99
- yield self
100
- ensure
101
- close
102
- end
103
- end
104
- end
105
-
106
- # Open an existing Semaphore by +name+. The +inherit+ argument sets
107
- # whether or not the object was opened such that a process created by the
108
- # CreateProcess() function (a Windows API function) can inherit the
109
- # handle. The default is true.
110
- #
111
- # This method is essentially identical to Semaphore.new, except that the
112
- # options for +initial_count+ and +max_count+ cannot be set (since they
113
- # are already set). Also, this method will raise a Semaphore::Error if
114
- # the semaphore doesn't already exist.
115
- #
116
- # If you want "open or create" semantics, then use Semaphore.new.
117
- #
118
- def self.open(name, inherit=true, &block)
119
- if name && name.encoding.to_s != 'UTF-16LE'
120
- name = name + 0.chr
121
- name.encode!('UTF-16LE')
122
- end
123
-
124
- begin
125
- # The OpenSemaphore() call here is strictly to force an error if the
126
- # user tries to open a semaphore that doesn't already exist.
127
- handle = OpenSemaphoreW(SEMAPHORE_ALL_ACCESS, inherit, name)
128
-
129
- if handle == 0 || handle == INVALID_HANDLE_VALUE
130
- raise SystemCallError.new("OpenSemaphore", FFI.errno)
131
- end
132
- ensure
133
- CloseHandle(handle)
134
- end
135
-
136
- self.new(0, 1, name, inherit, &block)
137
- end
138
-
139
- # Increases the count of the specified semaphore object by +amount+.
140
- # The default is 1. Returns the previous count of the semaphore if
141
- # successful. If the +amount+ exceeds the +max_count+ specified when
142
- # the semaphore was created then an error is raised.
143
- #
144
- def release(amount = 1)
145
- pcount = FFI::MemoryPointer.new(:long)
146
-
147
- # Ruby doesn't translate error 298, so we treat it as an EINVAL
148
- unless ReleaseSemaphore(@handle, amount, pcount)
149
- errno = FFI.errno
150
- errno = 22 if errno == 298 # 22 is EINVAL
151
- raise SystemCallError.new("ReleaseSemaphore", errno)
152
- end
153
-
154
- pcount.read_long
155
- end
156
-
157
- # Returns whether or not the object was opened such that a process
158
- # created by the CreateProcess() function (a Windows API function) can
159
- # inherit the handle. The default is true.
160
- #
161
- def inheritable?
162
- @inherit
163
- end
164
- end
165
- end
1
+ require 'win32/ipc'
2
+
3
+ # The Win32 module serves as a namespace only.
4
+ module Win32
5
+
6
+ # The Semaphore class encapsulates semaphore objects on Windows.
7
+ class Semaphore < Ipc
8
+ typedef :ulong, :dword
9
+ typedef :uintptr_t, :handle
10
+
11
+ ffi_lib :kernel32
12
+
13
+ private
14
+
15
+ class SecurityAttributes < FFI::Struct
16
+ layout(
17
+ :nLength, :dword,
18
+ :lpSecurityDescriptor, :pointer,
19
+ :bInheritHandle, :bool
20
+ )
21
+ end
22
+
23
+ attach_function :CreateSemaphoreW, [:pointer, :long, :long, :buffer_in], :handle
24
+ attach_function :OpenSemaphoreW, [:dword, :bool, :buffer_in], :handle
25
+ attach_function :ReleaseSemaphore, [:handle, :long, :pointer], :bool
26
+
27
+ private_class_method :CreateSemaphoreW, :OpenSemaphoreW, :ReleaseSemaphore
28
+
29
+ SEMAPHORE_ALL_ACCESS = 0x1F0003
30
+ INVALID_HANDLE_VALUE = FFI::Pointer.new(-1).address
31
+
32
+ public
33
+
34
+ # The version of the win32-semaphore library
35
+ VERSION = '0.4.2'
36
+
37
+ # The initial count for the semaphore object. This value must be greater
38
+ # than or equal to zero and less than or equal to +max_count+. The state
39
+ # of a semaphore is signaled when its count is greater than zero and
40
+ # nonsignaled when it is zero. The count is decreased by one whenever
41
+ # a wait function releases a thread that was waiting for the semaphore.
42
+ # The count is increased by a specified amount by calling
43
+ # Semaphore#release method.
44
+ #
45
+ attr_reader :initial_count
46
+
47
+ # The maximum count for the semaphore object. This value must be
48
+ # greater than zero.
49
+ #
50
+ attr_reader :max_count
51
+
52
+ # The name of the Semaphore object.
53
+ #
54
+ attr_reader :name
55
+
56
+ # Creates and returns new Semaphore object. If +name+ is omitted, the
57
+ # Semaphore object is created without a name, i.e. it's anonymous.
58
+ #
59
+ # If +name+ is provided and it already exists, then it is opened
60
+ # instead, and the +initial_count+ and +max_count+ parameters are
61
+ # ignored.
62
+ #
63
+ # The +initial_count+ and +max_count+ parameters set the initial count
64
+ # and maximum count for the Semaphore object, respectively. See the
65
+ # documentation for the corresponding accessor for more information.
66
+ #
67
+ # The +inherit+ attribute determines whether or not the semaphore can
68
+ # be inherited by child processes.
69
+ #
70
+ def initialize(initial_count, max_count, name=nil, inherit=true)
71
+ @initial_count = initial_count
72
+ @max_count = max_count
73
+ @name = name
74
+ @inherit = inherit
75
+
76
+ if name && name.encoding.to_s != 'UTF-16LE'
77
+ name = name + 0.chr
78
+ name.encode!('UTF-16LE')
79
+ end
80
+
81
+ if inherit
82
+ sec = SecurityAttributes.new
83
+ sec[:nLength] = SecurityAttributes.size
84
+ sec[:bInheritHandle] = true
85
+ else
86
+ sec = nil
87
+ end
88
+
89
+ handle = CreateSemaphoreW(sec, initial_count, max_count, name)
90
+
91
+ if handle == 0 || handle == INVALID_HANDLE_VALUE
92
+ raise SystemCallError.new("CreateSemaphore", FFI.errno)
93
+ end
94
+
95
+ super(handle)
96
+
97
+ if block_given?
98
+ begin
99
+ yield self
100
+ ensure
101
+ close
102
+ end
103
+ end
104
+ end
105
+
106
+ # Open an existing Semaphore by +name+. The +inherit+ argument sets
107
+ # whether or not the object was opened such that a process created by the
108
+ # CreateProcess() function (a Windows API function) can inherit the
109
+ # handle. The default is true.
110
+ #
111
+ # This method is essentially identical to Semaphore.new, except that the
112
+ # options for +initial_count+ and +max_count+ cannot be set (since they
113
+ # are already set). Also, this method will raise a Semaphore::Error if
114
+ # the semaphore doesn't already exist.
115
+ #
116
+ # If you want "open or create" semantics, then use Semaphore.new.
117
+ #
118
+ def self.open(name, inherit=true, &block)
119
+ if name && name.encoding.to_s != 'UTF-16LE'
120
+ name = name + 0.chr
121
+ name.encode!('UTF-16LE')
122
+ end
123
+
124
+ begin
125
+ # The OpenSemaphore() call here is strictly to force an error if the
126
+ # user tries to open a semaphore that doesn't already exist.
127
+ handle = OpenSemaphoreW(SEMAPHORE_ALL_ACCESS, inherit, name)
128
+
129
+ if handle == 0 || handle == INVALID_HANDLE_VALUE
130
+ raise SystemCallError.new("OpenSemaphore", FFI.errno)
131
+ end
132
+ ensure
133
+ CloseHandle(handle)
134
+ end
135
+
136
+ self.new(0, 1, name, inherit, &block)
137
+ end
138
+
139
+ # Increases the count of the specified semaphore object by +amount+.
140
+ # The default is 1. Returns the previous count of the semaphore if
141
+ # successful. If the +amount+ exceeds the +max_count+ specified when
142
+ # the semaphore was created then an error is raised.
143
+ #
144
+ def release(amount = 1)
145
+ pcount = FFI::MemoryPointer.new(:long)
146
+
147
+ # Ruby doesn't translate error 298, so we treat it as an EINVAL
148
+ unless ReleaseSemaphore(@handle, amount, pcount)
149
+ errno = FFI.errno
150
+ errno = 22 if errno == 298 # 22 is EINVAL
151
+ raise SystemCallError.new("ReleaseSemaphore", errno)
152
+ end
153
+
154
+ pcount.read_long
155
+ end
156
+
157
+ # Returns whether or not the object was opened such that a process
158
+ # created by the CreateProcess() function (a Windows API function) can
159
+ # inherit the handle. The default is true.
160
+ #
161
+ def inheritable?
162
+ @inherit
163
+ end
164
+ end
165
+ end
@@ -1,126 +1,126 @@
1
- ################################################################
2
- # test_win32_semaphore.rb
3
- #
4
- # Test suite for the win32-semaphore package. This test should
5
- # be run via the 'rake test' task.
6
- ################################################################
7
- require 'win32/semaphore'
8
- require 'test-unit'
9
- include Win32
10
-
11
- class TC_Semaphore < Test::Unit::TestCase
12
- def setup
13
- @sem = Semaphore.new(1, 3, 'test')
14
- end
15
-
16
- test "version is set to expected value" do
17
- assert_equal('0.4.1', Semaphore::VERSION)
18
- end
19
-
20
- test "initial_count basic functionality" do
21
- assert_respond_to(@sem, :initial_count)
22
- end
23
-
24
- test "initial count is set to value passed to constructor" do
25
- assert_equal(1, @sem.initial_count)
26
- end
27
-
28
- test "max_count basic functionality" do
29
- assert_respond_to(@sem, :max_count)
30
- end
31
-
32
- test "max_count is set to value passed to constructor" do
33
- assert_equal(3, @sem.max_count)
34
- end
35
-
36
- test "name method basic functionality" do
37
- assert_respond_to(@sem, :name)
38
- end
39
-
40
- test "name returns value passed in constructor" do
41
- assert_equal('test', @sem.name)
42
- end
43
-
44
- test "default name is nil" do
45
- sem = Semaphore.new(0,1)
46
- assert_nil(sem.name)
47
- sem.close
48
- end
49
-
50
- test "inheritable? method is defined and true by default" do
51
- assert_respond_to(@sem, :inheritable?)
52
- assert_true(@sem.inheritable?)
53
- end
54
-
55
- test "inheritable? method returns value passed to constructor" do
56
- sem = Semaphore.new(0,1,nil,false)
57
- assert_false(sem.inheritable?)
58
- sem.close
59
- end
60
-
61
- test "release method basic functionality" do
62
- assert_respond_to(@sem, :release)
63
- assert_kind_of(Fixnum, @sem.release)
64
- end
65
-
66
- test "release accepts an optional amount" do
67
- assert_equal(1, @sem.release(1))
68
- end
69
-
70
- test "release returns the total number of releases" do
71
- assert_equal(1, @sem.release(1))
72
- assert_equal(2, @sem.release(1))
73
- end
74
-
75
- test "attempting to release more than the total count raises an error" do
76
- assert_raise(Errno::EINVAL){ @sem.release(99) }
77
- end
78
-
79
- test "release only accepts one argument" do
80
- assert_raise(ArgumentError){ @sem.release(1,2) }
81
- end
82
-
83
- test "open method basic functionality" do
84
- assert_respond_to(Semaphore, :open)
85
- assert_nothing_raised{ Semaphore.open('test'){} }
86
- end
87
-
88
- test "open method fails is semaphore name is invalid" do
89
- assert_raise(Errno::ENOENT){ Semaphore.open('bogus'){} }
90
- end
91
-
92
- test "wait method was inherited" do
93
- assert_respond_to(@sem, :wait)
94
- end
95
-
96
- test "wait_any method was inherited" do
97
- assert_respond_to(@sem, :wait_any)
98
- end
99
-
100
- test "wait_all method was inherited" do
101
- assert_respond_to(@sem, :wait_all)
102
- end
103
-
104
- test "first argument to constructor must be a number" do
105
- assert_raise(TypeError){ Semaphore.new('foo', 1){} }
106
- end
107
-
108
- test "second argument to constructor must be a number" do
109
- assert_raise(TypeError){ Semaphore.new(1, 'bar'){} }
110
- end
111
-
112
- test "constructor accepts a maximum of four arguments" do
113
- assert_raise(ArgumentError){ Semaphore.new(1, 2, 'test', true, 1){} }
114
- end
115
-
116
- test "ffi functions are private" do
117
- assert_not_respond_to(Semaphore, :CreateSemaphoreW)
118
- assert_not_respond_to(Semaphore, :OpenSemaphoreW)
119
- assert_not_respond_to(Semaphore, :ReleaseSemaphore)
120
- end
121
-
122
- def teardown
123
- @sem.close if @sem
124
- @sem = nil
125
- end
126
- end
1
+ ################################################################
2
+ # test_win32_semaphore.rb
3
+ #
4
+ # Test suite for the win32-semaphore package. This test should
5
+ # be run via the 'rake test' task.
6
+ ################################################################
7
+ require 'win32/semaphore'
8
+ require 'test-unit'
9
+ include Win32
10
+
11
+ class TC_Semaphore < Test::Unit::TestCase
12
+ def setup
13
+ @sem = Semaphore.new(1, 3, 'test')
14
+ end
15
+
16
+ test "version is set to expected value" do
17
+ assert_equal('0.4.2', Semaphore::VERSION)
18
+ end
19
+
20
+ test "initial_count basic functionality" do
21
+ assert_respond_to(@sem, :initial_count)
22
+ end
23
+
24
+ test "initial count is set to value passed to constructor" do
25
+ assert_equal(1, @sem.initial_count)
26
+ end
27
+
28
+ test "max_count basic functionality" do
29
+ assert_respond_to(@sem, :max_count)
30
+ end
31
+
32
+ test "max_count is set to value passed to constructor" do
33
+ assert_equal(3, @sem.max_count)
34
+ end
35
+
36
+ test "name method basic functionality" do
37
+ assert_respond_to(@sem, :name)
38
+ end
39
+
40
+ test "name returns value passed in constructor" do
41
+ assert_equal('test', @sem.name)
42
+ end
43
+
44
+ test "default name is nil" do
45
+ sem = Semaphore.new(0,1)
46
+ assert_nil(sem.name)
47
+ sem.close
48
+ end
49
+
50
+ test "inheritable? method is defined and true by default" do
51
+ assert_respond_to(@sem, :inheritable?)
52
+ assert_true(@sem.inheritable?)
53
+ end
54
+
55
+ test "inheritable? method returns value passed to constructor" do
56
+ sem = Semaphore.new(0,1,nil,false)
57
+ assert_false(sem.inheritable?)
58
+ sem.close
59
+ end
60
+
61
+ test "release method basic functionality" do
62
+ assert_respond_to(@sem, :release)
63
+ assert_kind_of(Fixnum, @sem.release)
64
+ end
65
+
66
+ test "release accepts an optional amount" do
67
+ assert_equal(1, @sem.release(1))
68
+ end
69
+
70
+ test "release returns the total number of releases" do
71
+ assert_equal(1, @sem.release(1))
72
+ assert_equal(2, @sem.release(1))
73
+ end
74
+
75
+ test "attempting to release more than the total count raises an error" do
76
+ assert_raise(Errno::EINVAL){ @sem.release(99) }
77
+ end
78
+
79
+ test "release only accepts one argument" do
80
+ assert_raise(ArgumentError){ @sem.release(1,2) }
81
+ end
82
+
83
+ test "open method basic functionality" do
84
+ assert_respond_to(Semaphore, :open)
85
+ assert_nothing_raised{ Semaphore.open('test'){} }
86
+ end
87
+
88
+ test "open method fails is semaphore name is invalid" do
89
+ assert_raise(Errno::ENOENT){ Semaphore.open('bogus'){} }
90
+ end
91
+
92
+ test "wait method was inherited" do
93
+ assert_respond_to(@sem, :wait)
94
+ end
95
+
96
+ test "wait_any method was inherited" do
97
+ assert_respond_to(@sem, :wait_any)
98
+ end
99
+
100
+ test "wait_all method was inherited" do
101
+ assert_respond_to(@sem, :wait_all)
102
+ end
103
+
104
+ test "first argument to constructor must be a number" do
105
+ assert_raise(TypeError){ Semaphore.new('foo', 1){} }
106
+ end
107
+
108
+ test "second argument to constructor must be a number" do
109
+ assert_raise(TypeError){ Semaphore.new(1, 'bar'){} }
110
+ end
111
+
112
+ test "constructor accepts a maximum of four arguments" do
113
+ assert_raise(ArgumentError){ Semaphore.new(1, 2, 'test', true, 1){} }
114
+ end
115
+
116
+ test "ffi functions are private" do
117
+ assert_not_respond_to(Semaphore, :CreateSemaphoreW)
118
+ assert_not_respond_to(Semaphore, :OpenSemaphoreW)
119
+ assert_not_respond_to(Semaphore, :ReleaseSemaphore)
120
+ end
121
+
122
+ def teardown
123
+ @sem.close if @sem
124
+ @sem = nil
125
+ end
126
+ end
@@ -1,27 +1,29 @@
1
- require 'rubygems'
2
-
3
- Gem::Specification.new do |spec|
4
- spec.name = 'win32-semaphore'
5
- spec.version = '0.4.1'
6
- spec.author = 'Daniel J. Berger'
7
- spec.license = 'Artistic 2.0'
8
- spec.email = 'djberg96@gmail.com'
9
- spec.homepage = 'http://www.github.com/djberg96/win32-semaphore'
10
- spec.summary = 'Interface to MS Windows Semaphore objects.'
11
- spec.test_file = 'test/test_win32_semaphore.rb'
12
- spec.files = Dir['**/*'].reject{ |f| f.include?('git') }
13
-
14
- spec.rubyforge_project = 'win32utils'
15
- spec.extra_rdoc_files = ['README', 'CHANGES', 'MANIFEST']
16
- spec.required_ruby_version = '> 1.9.0'
17
-
18
- spec.add_dependency('win32-ipc')
19
- spec.add_development_dependency('test-unit')
20
-
21
- spec.description = <<-EOF
22
- The win32-semaphore library provides an interface to semaphore objects
23
- on MS Windows. A semaphore is a kernel object used for resource counting.
24
- This allows threads to query the number of resources available, and wait
25
- if there aren't any available.
26
- EOF
27
- end
1
+ require 'rubygems'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = 'win32-semaphore'
5
+ spec.version = '0.4.2'
6
+ spec.author = 'Daniel J. Berger'
7
+ spec.license = 'Artistic 2.0'
8
+ spec.email = 'djberg96@gmail.com'
9
+ spec.homepage = 'http://www.github.com/djberg96/win32-semaphore'
10
+ spec.summary = 'Interface to MS Windows Semaphore objects.'
11
+ spec.test_file = 'test/test_win32_semaphore.rb'
12
+ spec.files = Dir['**/*'].reject{ |f| f.include?('git') }
13
+
14
+ spec.rubyforge_project = 'win32utils'
15
+ spec.extra_rdoc_files = ['README', 'CHANGES', 'MANIFEST']
16
+ spec.required_ruby_version = '> 1.9.0'
17
+
18
+ spec.add_dependency('win32-ipc')
19
+
20
+ spec.add_development_dependency('rake')
21
+ spec.add_development_dependency('test-unit')
22
+
23
+ spec.description = <<-EOF
24
+ The win32-semaphore library provides an interface to semaphore objects
25
+ on MS Windows. A semaphore is a kernel object used for resource counting.
26
+ This allows threads to query the number of resources available, and wait
27
+ if there aren't any available.
28
+ EOF
29
+ end
metadata CHANGED
@@ -1,52 +1,62 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: win32-semaphore
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
5
- prerelease:
4
+ version: 0.4.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Daniel J. Berger
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-04-10 00:00:00.000000000 Z
11
+ date: 2013-10-21 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: win32-ipc
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
28
39
  - !ruby/object:Gem::Version
29
40
  version: '0'
30
41
  - !ruby/object:Gem::Dependency
31
42
  name: test-unit
32
43
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
44
  requirements:
35
- - - ! '>='
45
+ - - '>='
36
46
  - !ruby/object:Gem::Version
37
47
  version: '0'
38
48
  type: :development
39
49
  prerelease: false
40
50
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
51
  requirements:
43
- - - ! '>='
52
+ - - '>='
44
53
  - !ruby/object:Gem::Version
45
54
  version: '0'
46
- description: ! " The win32-semaphore library provides an interface to semaphore
47
- objects\n on MS Windows. A semaphore is a kernel object used for resource counting.\n
48
- \ This allows threads to query the number of resources available, and wait\n if
49
- there aren't any available.\n"
55
+ description: |2
56
+ The win32-semaphore library provides an interface to semaphore objects
57
+ on MS Windows. A semaphore is a kernel object used for resource counting.
58
+ This allows threads to query the number of resources available, and wait
59
+ if there aren't any available.
50
60
  email: djberg96@gmail.com
51
61
  executables: []
52
62
  extensions: []
@@ -66,27 +76,26 @@ files:
66
76
  homepage: http://www.github.com/djberg96/win32-semaphore
67
77
  licenses:
68
78
  - Artistic 2.0
79
+ metadata: {}
69
80
  post_install_message:
70
81
  rdoc_options: []
71
82
  require_paths:
72
83
  - lib
73
84
  required_ruby_version: !ruby/object:Gem::Requirement
74
- none: false
75
85
  requirements:
76
- - - ! '>'
86
+ - - '>'
77
87
  - !ruby/object:Gem::Version
78
88
  version: 1.9.0
79
89
  required_rubygems_version: !ruby/object:Gem::Requirement
80
- none: false
81
90
  requirements:
82
- - - ! '>='
91
+ - - '>='
83
92
  - !ruby/object:Gem::Version
84
93
  version: '0'
85
94
  requirements: []
86
95
  rubyforge_project: win32utils
87
- rubygems_version: 1.8.24
96
+ rubygems_version: 2.1.9
88
97
  signing_key:
89
- specification_version: 3
98
+ specification_version: 4
90
99
  summary: Interface to MS Windows Semaphore objects.
91
100
  test_files:
92
101
  - test/test_win32_semaphore.rb