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.
- checksums.yaml +7 -0
- data/CHANGES +59 -54
- data/MANIFEST +7 -7
- data/README +57 -57
- data/Rakefile +36 -31
- data/examples/example_semaphore.rb +39 -39
- data/lib/win32/semaphore.rb +165 -165
- data/test/test_win32_semaphore.rb +126 -126
- data/win32-semaphore.gemspec +29 -27
- metadata +30 -21
checksums.yaml
ADDED
@@ -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.
|
2
|
-
* Fixed the
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
*
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
*
|
14
|
-
* Removed
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
*
|
19
|
-
*
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
*
|
24
|
-
*
|
25
|
-
*
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
* Added a
|
30
|
-
*
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
*
|
35
|
-
*
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
*
|
41
|
-
*
|
42
|
-
*
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
*
|
47
|
-
|
48
|
-
*
|
49
|
-
|
50
|
-
|
51
|
-
*
|
52
|
-
|
53
|
-
|
54
|
-
|
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::
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
|
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
|
data/lib/win32/semaphore.rb
CHANGED
@@ -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 =
|
31
|
-
|
32
|
-
public
|
33
|
-
|
34
|
-
# The version of the win32-semaphore library
|
35
|
-
VERSION = '0.4.
|
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.
|
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
|
data/win32-semaphore.gemspec
CHANGED
@@ -1,27 +1,29 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
|
3
|
-
Gem::Specification.new do |spec|
|
4
|
-
spec.name = 'win32-semaphore'
|
5
|
-
spec.version = '0.4.
|
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
|
-
|
21
|
-
spec.
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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.
|
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-
|
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:
|
47
|
-
|
48
|
-
|
49
|
-
|
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.
|
96
|
+
rubygems_version: 2.1.9
|
88
97
|
signing_key:
|
89
|
-
specification_version:
|
98
|
+
specification_version: 4
|
90
99
|
summary: Interface to MS Windows Semaphore objects.
|
91
100
|
test_files:
|
92
101
|
- test/test_win32_semaphore.rb
|