win32-semaphore 0.3.0

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.
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: