win32-semaphore 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES ADDED
@@ -0,0 +1,33 @@
1
+ == 0.3.0 - 3-May-2007
2
+ * Now pure Ruby.
3
+ * Added a Rakefile, with test, install and example tasks.
4
+ * Both the Semaphore.new and Semaphore.open methods now accept a block, and
5
+ automatically close the associated handle at the end of the block.
6
+ * The Semaphore.new method now accepts an optional fourth argument that
7
+ controls whether the Event object can be inherited by other processes.
8
+ * Added a gemspec.
9
+ * Removed the doc/semaphore.txt file. The documentation is now inlined via
10
+ RDoc. There is also some documentation in the README file.
11
+
12
+ == 0.2.2 - 10-Jun-2005
13
+ * Now Unicode friendly.
14
+ * Inlined rdoc documentation into the C source code.
15
+ * Made the semaphore.txt file rdoc friendly.
16
+ * Removed the semaphore.rd file.
17
+
18
+ == 0.2.1 - 1-Mar-2005
19
+ * Added a VERSION constant (oops).
20
+ * Moved the 'examples' directory to the toplevel directory.
21
+ * Made the CHANGES and README files rdoc friendly.
22
+ * Removed an unused (and unnecessary) helper function in semaphore.h.
23
+
24
+ == 0.2.0 - 16-Jul-2004
25
+ * Modified to use the newer allocation framework. This means that as of this
26
+ release, this package requires Ruby 1.8.0 or later.
27
+ * Fixed a bug in the constructor where it was possible for the constructor to
28
+ fail, but have no error raised.
29
+ * Moved the test.rb file to the doc/examples directory.
30
+ * Added more tests.
31
+
32
+ == 0.1.0 - 14-May-2004
33
+ * Initial release
data/MANIFEST ADDED
@@ -0,0 +1,8 @@
1
+ * CHANGES
2
+ * MANIFEST
3
+ * README
4
+ * Rakefile
5
+ * win32-semaphore.gemspec
6
+ * examples/semaphore_test.rb
7
+ * lib/win32/semaphore.rb
8
+ * test/tc_semaphore.rb
data/README ADDED
@@ -0,0 +1,58 @@
1
+ == Brief Description
2
+ An interface for MS Windows Semaphores.
3
+
4
+ == Prerequisites
5
+ win32-ipc 0.5.0 or later.
6
+
7
+ == Installation
8
+ rake test (optional)
9
+ rake install
10
+
11
+ == Synopsis
12
+ require "win32/semaphore"
13
+ include Win32
14
+
15
+ Semaphore.new(1, 5, 'test') do |sem|
16
+ puts 'uh, oh' unless sem.wait(10) > 0
17
+ sem.release(2) # 2
18
+ end
19
+
20
+ == Documentation
21
+ The event.rb file contains inline RDoc documentation. If you installed
22
+ this file as a gem, then you have the docs.
23
+
24
+ For more detailed documentation about Semaphores on MS Windows in general,
25
+ please visit http://www.msdn.com/library and lookup the CreateSemaphore(),
26
+ OpenSemaphore() and ReleaseSemaphore() functions.
27
+
28
+ == Notes
29
+ The Semaphore class is a subclass of Win32::Ipc (win32-ipc). This package
30
+ require's the win32-ipc package internally (you don't need to explicitly
31
+ call it).
32
+
33
+ == Acknowledgements
34
+ Adapted originally from the Win32::Semaphore Perl module by Christopher
35
+ J. Madsen.
36
+
37
+ == Known Bugs
38
+ None known. Any bugs should be reported on the project page at
39
+ http://rubyforge.org/projects/win32utils.
40
+
41
+ == Future Plans
42
+ Suggestions welcome.
43
+
44
+ == License
45
+ Ruby's
46
+
47
+ == Copyright
48
+ (C) 2003-2007 Daniel J. Berger
49
+ All Rights Reserved
50
+
51
+ == Warranty
52
+ This package is provided "as is" and without any express or
53
+ implied warranties, including, without limitation, the implied
54
+ warranties of merchantability and fitness for a particular purpose.
55
+
56
+ == Author(s)
57
+ Daniel J. Berger
58
+ Park Heesob
data/Rakefile ADDED
@@ -0,0 +1,26 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rbconfig'
4
+ include Config
5
+
6
+ desc 'Install the win32-semaphore package (non-gem)'
7
+ task :install do
8
+ sitelibdir = CONFIG['sitelibdir']
9
+ installdir = File.join(sitelibdir, 'win32')
10
+ file = 'lib\win32\semaphore.rb'
11
+
12
+ Dir.mkdir(installdir) unless File.exists?(installdir)
13
+ FileUtils.cp(file, installdir, :verbose => true)
14
+ end
15
+
16
+ desc 'Run the example program'
17
+ task :example do
18
+ ruby '-Ilib examples/semaphore_test.rb'
19
+ end
20
+
21
+ Rake::TestTask.new do |t|
22
+ t.libs << 'test'
23
+ t.verbose = true
24
+ t.warning = true
25
+ t.test_files = FileList['test/tc_semaphore.rb']
26
+ end
@@ -0,0 +1,135 @@
1
+ require 'win32/ipc'
2
+
3
+ module Win32
4
+ class Semaphore < Ipc
5
+
6
+ # This is the error raised if any of the Semaphore methods fail.
7
+ class Error < StandardError; end
8
+
9
+ extend Windows::Synchronize
10
+ extend Windows::Error
11
+ extend Windows::Handle
12
+
13
+ VERSION = '0.3.0'
14
+
15
+ # The initial count for the semaphore object. This value must be greater
16
+ # than or equal to zero and less than or equal to +max_count+. The state
17
+ # of a semaphore is signaled when its count is greater than zero and
18
+ # nonsignaled when it is zero. The count is decreased by one whenever
19
+ # a wait function releases a thread that was waiting for the semaphore.
20
+ # The count is increased by a specified amount by calling
21
+ # Semaphore#release method.
22
+ #
23
+ attr_reader :initial_count
24
+
25
+ # The maximum count for the semaphore object. This value must be
26
+ # greater than zero.
27
+ #
28
+ attr_reader :max_count
29
+
30
+ # The name of the Semaphore object.
31
+ #
32
+ attr_reader :name
33
+
34
+ # Creates and returns new Semaphore object. If +name+ is omitted, the
35
+ # Semaphore object is created without a name, i.e. it's anonymous.
36
+ #
37
+ # If +name+ is provided and it already exists, then it is opened
38
+ # instead, and the +initial_count+ and +max_count+ parameters are
39
+ # ignored.
40
+ #
41
+ # The +initial_count+ and +max_count+ parameters set the initial count
42
+ # and maximum count for the Semaphore object, respectively. See the
43
+ # documentation for the corresponding accessor for more information.
44
+ #
45
+ # The +inherit+ attribute determines whether or not the semaphore can
46
+ # be inherited by child processes.
47
+ #
48
+ def initialize(initial_count, max_count, name=nil, inherit=true)
49
+ @initial_count = initial_count
50
+ @max_count = max_count
51
+ @name = name
52
+ @inherit = inherit
53
+
54
+ # Used to prevent potential segfaults.
55
+ if name && !name.is_a?(String)
56
+ raise TypeError, 'name must be a string'
57
+ end
58
+
59
+ if inherit
60
+ sec = 0.chr * 12 # sizeof(SECURITY_ATTRIBUTES)
61
+ sec[0,4] = [12].pack('L')
62
+ sec[8,4] = [1].pack('L') # 1 == TRUE
63
+ else
64
+ sec = 0
65
+ end
66
+
67
+ handle = CreateSemaphore(sec, initial_count, max_count, name)
68
+
69
+ if handle == 0 || handle == INVALID_HANDLE_VALUE
70
+ raise Error, get_last_error
71
+ end
72
+
73
+ super(handle)
74
+
75
+ if block_given?
76
+ begin
77
+ yield self
78
+ ensure
79
+ close
80
+ end
81
+ end
82
+ end
83
+
84
+ # Open an existing Semaphore by +name+. The +inherit+ argument sets
85
+ # whether or not the object was opened such that a process created by the
86
+ # CreateProcess() function (a Windows API function) can inherit the
87
+ # handle. The default is true.
88
+ #
89
+ # This method is essentially identical to Semaphore.new, except that the
90
+ # options for +initial_count+ and +max_count+ cannot be set (since they
91
+ # are already set). Also, this method will raise a Semaphore::Error if
92
+ # the semaphore doesn't already exist.
93
+ #
94
+ # If you want "open or create" semantics, then use Semaphore.new.
95
+ #--
96
+ # The OpenSemaphore() call here is strictly to force an error if the user
97
+ # tries to open a semaphore that doesn't already exist.
98
+ #
99
+ def self.open(name, inherit=true, &block)
100
+ if name && !name.is_a?(String)
101
+ raise TypeError, 'name must be a string'
102
+ end
103
+
104
+ bool = inherit ? 1 : 0
105
+ handle = OpenSemaphore(EVENT_ALL_ACCESS, bool, name)
106
+ if handle == 0 || handle == INVALID_HANDLE_VALUE
107
+ raise Error, get_last_error
108
+ end
109
+ CloseHandle(handle)
110
+
111
+ self.new(0, 1, name, inherit, &block)
112
+ end
113
+
114
+ # Increases the count of the specified semaphore object by +amount+.
115
+ # The default is 1. Returns the previous count of the semaphore if
116
+ # successful. If the +amount+ exceeds the +max_count+ specified when
117
+ # the semaphore was created then a Semaphore::Error is raised.
118
+ #
119
+ def release(amount = 1)
120
+ pcount = [0].pack('L')
121
+ unless ReleaseSemaphore(@handle, amount, pcount)
122
+ raise Error, get_last_error
123
+ end
124
+ pcount.unpack('L').first
125
+ end
126
+
127
+ # Returns whether or not the object was opened such that a process
128
+ # created by the CreateProcess() function (a Windows API function) can
129
+ # inherit the handle. The default is true.
130
+ #
131
+ def inheritable?
132
+ @inherit
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,70 @@
1
+ ################################################################
2
+ # tc_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
+ def test_version
17
+ assert_equal('0.3.0', Semaphore::VERSION)
18
+ end
19
+
20
+ def test_max_semaphore_name
21
+ name = "foobar" * 500
22
+ assert_raises(Semaphore::Error){ Semaphore.new(1, 1, name){} }
23
+ end
24
+
25
+ def test_open
26
+ assert_respond_to(Semaphore, :open)
27
+ assert_nothing_raised{ Semaphore.open('test'){} }
28
+ assert_raises(Semaphore::Error){ Semaphore.open('bogus'){} }
29
+ end
30
+
31
+ def test_inheritable
32
+ assert_respond_to(@sem, :inheritable?)
33
+ assert_equal(true, @sem.inheritable?)
34
+ end
35
+
36
+ def test_release
37
+ assert_respond_to(@sem, :release)
38
+ assert_equal(1, @sem.release(1))
39
+ assert_equal(2, @sem.release(1))
40
+ assert_raises(Semaphore::Error){ @sem.release(99) }
41
+ end
42
+
43
+ def test_wait
44
+ assert_respond_to(@sem, :wait)
45
+ end
46
+
47
+ def test_wait_any
48
+ assert_respond_to(@sem, :wait_any)
49
+ end
50
+
51
+ def test_wait_all
52
+ assert_respond_to(@sem, :wait_all)
53
+ end
54
+
55
+ def test_valid_constructor
56
+ assert_nothing_raised{ Semaphore.new(0, 1){} }
57
+ assert_nothing_raised{ Semaphore.new(0, 1, "foo"){} }
58
+ assert_nothing_raised{ Semaphore.new(0, 1, "foo", false){} }
59
+ end
60
+
61
+ def test_invalid_constructor
62
+ assert_raises(TypeError){ Semaphore.new("foo", "bar"){} }
63
+ assert_raises(ArgumentError){ Semaphore.new(1, 1, "test", 1, 1){} }
64
+ end
65
+
66
+ def teardown
67
+ @sem.close
68
+ @sem = nil
69
+ end
70
+ end
@@ -0,0 +1,24 @@
1
+ require "rubygems"
2
+
3
+ spec = Gem::Specification.new do |gem|
4
+ gem.name = "win32-semaphore"
5
+ gem.version = "0.3.0"
6
+ gem.author = "Daniel J. Berger"
7
+ gem.email = "djberg96@gmail.com"
8
+ gem.homepage = "http://www.rubyforge.org/projects/win32utils"
9
+ gem.platform = Gem::Platform::RUBY
10
+ gem.summary = "Interface to MS Windows Semaphore objects."
11
+ gem.description = "Interface to MS Windows Semaphore objects."
12
+ gem.test_file = "test/tc_semaphore.rb"
13
+ gem.has_rdoc = true
14
+ gem.files = Dir["lib/win32/*.rb"] + Dir["test/*"] + Dir["[A-Z]*"]
15
+ gem.files.reject! { |fn| fn.include? "CVS" }
16
+ gem.require_path = "lib"
17
+ gem.extra_rdoc_files = ["README", "CHANGES", "MANIFEST"]
18
+ gem.add_dependency("win32-ipc", ">= 0.5.0")
19
+ end
20
+
21
+ if $0 == __FILE__
22
+ Gem.manage_gems
23
+ Gem::Builder.new(spec).build
24
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.2
3
+ specification_version: 1
4
+ name: win32-semaphore
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.3.0
7
+ date: 2007-05-03 00:00:00 -06:00
8
+ summary: Interface to MS Windows Semaphore objects.
9
+ require_paths:
10
+ - lib
11
+ email: djberg96@gmail.com
12
+ homepage: http://www.rubyforge.org/projects/win32utils
13
+ rubyforge_project:
14
+ description: Interface to MS Windows Semaphore objects.
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Daniel J. Berger
31
+ files:
32
+ - lib/win32/semaphore.rb
33
+ - test/CVS
34
+ - test/tc_semaphore.rb
35
+ - CHANGES
36
+ - CVS
37
+ - doc
38
+ - examples
39
+ - lib
40
+ - MANIFEST
41
+ - Rakefile
42
+ - README
43
+ - test
44
+ - win32-semaphore.gemspec
45
+ test_files:
46
+ - test/tc_semaphore.rb
47
+ rdoc_options: []
48
+
49
+ extra_rdoc_files:
50
+ - README
51
+ - CHANGES
52
+ - MANIFEST
53
+ executables: []
54
+
55
+ extensions: []
56
+
57
+ requirements: []
58
+
59
+ dependencies:
60
+ - !ruby/object:Gem::Dependency
61
+ name: win32-ipc
62
+ version_requirement:
63
+ version_requirements: !ruby/object:Gem::Version::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: 0.5.0
68
+ version: