win32-mutex 0.3.2 → 0.4.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 +6 -0
- data/MANIFEST +1 -1
- data/README +1 -1
- data/lib/win32/mutex.rb +128 -116
- data/test/test_win32_mutex.rb +34 -17
- data/win32-mutex.gemspec +4 -6
- metadata +14 -26
data/CHANGES
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
== 0.4.0 - 10-Jul-2012
|
2
|
+
* Converted to FFI.
|
3
|
+
* Now requires Ruby 1.9 or later.
|
4
|
+
* Removed the Error class. If a Windows function fails it raises the
|
5
|
+
appropriate SystemCallError (Errno::).
|
6
|
+
|
1
7
|
== 0.3.2 - 18-Mar-2011
|
2
8
|
* Updates to the Rakefile and gemspec.
|
3
9
|
* One test file change for Ruby 1.9.
|
data/MANIFEST
CHANGED
data/README
CHANGED
data/lib/win32/mutex.rb
CHANGED
@@ -3,129 +3,141 @@ require 'win32/ipc'
|
|
3
3
|
# The Win32 module serves as a namespace only.
|
4
4
|
module Win32
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
super(handle)
|
64
|
-
|
65
|
-
if block_given?
|
66
|
-
begin
|
67
|
-
yield self
|
68
|
-
ensure
|
69
|
-
close # From superclass
|
70
|
-
end
|
71
|
-
end
|
6
|
+
# The Mutex class encapsulates Windows mutex objects.
|
7
|
+
class Mutex < Ipc
|
8
|
+
ffi_lib :kernel32
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
class SecurityAttributes < FFI::Struct
|
13
|
+
layout(
|
14
|
+
:nLength, :ulong,
|
15
|
+
:lpSecurityDescriptor, :pointer,
|
16
|
+
:bInheritHandle, :bool
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
attach_function :CreateMutexW, [:pointer, :bool, :buffer_in], :ulong
|
21
|
+
attach_function :OpenMutexW, [:ulong, :bool, :buffer_in], :ulong
|
22
|
+
attach_function :ReleaseMutex, [:ulong], :bool
|
23
|
+
|
24
|
+
private_class_method :CreateMutexW, :OpenMutexW, :ReleaseMutex
|
25
|
+
|
26
|
+
INVALID_HANDLE_VALUE = 0xFFFFFFFF
|
27
|
+
MUTEX_ALL_ACCESS = 0x1F0001
|
28
|
+
|
29
|
+
public
|
30
|
+
|
31
|
+
# The version of the win32-mutex library
|
32
|
+
VERSION = '0.4.0'
|
33
|
+
|
34
|
+
# The name of the mutex object.
|
35
|
+
attr_reader :name
|
36
|
+
|
37
|
+
# Creates and returns new Mutex object. If +name+ is omitted, the
|
38
|
+
# Mutex object is created without a name, i.e. it's anonymous.
|
39
|
+
#
|
40
|
+
# If the +initial_owner+ value is true and the caller created the mutex,
|
41
|
+
# the calling thread obtains initial ownership of the mutex object.
|
42
|
+
# Otherwise, the calling thread does not obtain ownership of the mutex.
|
43
|
+
# This value is false by default.
|
44
|
+
#
|
45
|
+
# If +name+ is provided and it already exists, then it is opened
|
46
|
+
# instead, and the +initial_count+ and +max_count+ parameters are
|
47
|
+
# ignored.
|
48
|
+
#
|
49
|
+
# The +inherit+ attribute determines whether or not the mutex can
|
50
|
+
# be inherited by child processes.
|
51
|
+
#
|
52
|
+
def initialize(initial_owner=false, name=nil, inherit=true)
|
53
|
+
@initial_owner = initial_owner
|
54
|
+
@name = name
|
55
|
+
@inherit = inherit
|
56
|
+
|
57
|
+
if inherit
|
58
|
+
sec = SecurityAttributes.new
|
59
|
+
sec[:nLength] = SecurityAttributes.size
|
60
|
+
sec[:bInheritHandle] = true
|
61
|
+
else
|
62
|
+
sec = nil
|
72
63
|
end
|
73
64
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
# handle. The default is true.
|
78
|
-
#
|
79
|
-
# This method is essentially identical to Mutex.new, except that the
|
80
|
-
# option for +initial_owner+ cannot be set (since it is already set).
|
81
|
-
# Also, this method will raise a Mutex::Error if the mutex doesn't
|
82
|
-
# already exist.
|
83
|
-
#
|
84
|
-
# If you want "open or create" semantics, then use Mutex.new.
|
85
|
-
#
|
86
|
-
def self.open(name, inherit=true, &block)
|
87
|
-
if name && !name.is_a?(String)
|
88
|
-
raise TypeError, 'name must be a string'
|
89
|
-
end
|
90
|
-
|
91
|
-
bool = inherit ? 1 : 0
|
92
|
-
|
93
|
-
# The OpenMutex() call here is strictly to force an error if the user
|
94
|
-
# tries to open a mutex that doesn't already exist.
|
95
|
-
begin
|
96
|
-
handle = OpenMutex(MUTEX_ALL_ACCESS, bool, name)
|
97
|
-
|
98
|
-
if handle == 0 || handle == INVALID_HANDLE_VALUE
|
99
|
-
raise Error, get_last_error
|
100
|
-
end
|
101
|
-
ensure
|
102
|
-
CloseHandle(handle) if handle && handle > 0
|
103
|
-
end
|
104
|
-
|
105
|
-
self.new(false, name, inherit, &block)
|
65
|
+
if name && name.encoding.to_s != 'UTF-16LE'
|
66
|
+
name = name + 0.chr
|
67
|
+
name.encode!('UTF-16LE')
|
106
68
|
end
|
107
69
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
raise Error, get_last_error
|
113
|
-
end
|
70
|
+
handle = CreateMutexW(sec, initial_owner, name)
|
71
|
+
|
72
|
+
if handle == 0 || handle == INVALID_HANDLE_VALUE
|
73
|
+
raise SystemCallError.new("CreateMutex", FFI.errno)
|
114
74
|
end
|
115
75
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
76
|
+
super(handle)
|
77
|
+
|
78
|
+
if block_given?
|
79
|
+
begin
|
80
|
+
yield self
|
81
|
+
ensure
|
82
|
+
close # From superclass
|
83
|
+
end
|
121
84
|
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Open an existing Mutex by +name+. The +inherit+ argument sets
|
88
|
+
# whether or not the object was opened such that a process created by the
|
89
|
+
# CreateProcess() function (a Windows API function) can inherit the
|
90
|
+
# handle. The default is true.
|
91
|
+
#
|
92
|
+
# This method is essentially identical to Mutex.new, except that the
|
93
|
+
# option for +initial_owner+ cannot be set (since it is already set).
|
94
|
+
# Also, this method will raise a Mutex::Error if the mutex doesn't
|
95
|
+
# already exist.
|
96
|
+
#
|
97
|
+
# If you want "open or create" semantics, then use Mutex.new.
|
98
|
+
#
|
99
|
+
def self.open(name, inherit=true, &block)
|
100
|
+
if name.encoding.to_s != 'UTF-16LE'
|
101
|
+
name = name + 0.chr
|
102
|
+
name.encode!('UTF-16LE')
|
103
|
+
end
|
104
|
+
|
105
|
+
begin
|
106
|
+
# The OpenMutex() call here is strictly to force an error if the user
|
107
|
+
# tries to open a mutex that doesn't already exist.
|
108
|
+
handle = OpenMutexW(MUTEX_ALL_ACCESS, inherit, name)
|
109
|
+
|
110
|
+
if handle == 0 || handle == INVALID_HANDLE_VALUE
|
111
|
+
raise SystemCallError.new("OpenMutex", FFI.errno)
|
112
|
+
end
|
113
|
+
ensure
|
114
|
+
CloseHandle(handle) if handle && handle > 0
|
115
|
+
end
|
116
|
+
|
117
|
+
self.new(false, name, inherit, &block)
|
118
|
+
end
|
122
119
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
@inherit
|
120
|
+
# Releases ownership of the mutex.
|
121
|
+
#
|
122
|
+
def release
|
123
|
+
unless ReleaseMutex(@handle)
|
124
|
+
raise SystemCallError.new("ReleaseMutex", FFI.errno)
|
129
125
|
end
|
130
|
-
|
126
|
+
end
|
127
|
+
|
128
|
+
# Returns whether or not the calling thread has initial ownership of
|
129
|
+
# the mutex object.
|
130
|
+
#
|
131
|
+
def initial_owner?
|
132
|
+
@initial_owner
|
133
|
+
end
|
134
|
+
|
135
|
+
# Returns whether or not the object was opened such that a process
|
136
|
+
# created by the CreateProcess() function (a Windows API function) can
|
137
|
+
# inherit the handle. The default is true.
|
138
|
+
#
|
139
|
+
def inheritable?
|
140
|
+
@inherit
|
141
|
+
end
|
142
|
+
end
|
131
143
|
end
|
data/test/test_win32_mutex.rb
CHANGED
@@ -1,14 +1,11 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
#######################################################################
|
3
|
-
#
|
3
|
+
# test_win32_mutex.rb
|
4
4
|
#
|
5
|
-
# Test suite for the win32-
|
6
|
-
#
|
5
|
+
# Test suite for the win32-mutex library. This test suite should be
|
6
|
+
# run via the 'rake test' task.
|
7
7
|
#######################################################################
|
8
|
-
require '
|
9
|
-
gem 'test-unit'
|
10
|
-
|
11
|
-
require 'test/unit'
|
8
|
+
require 'test-unit'
|
12
9
|
require 'win32/mutex'
|
13
10
|
|
14
11
|
class TC_Win32_Mutex < Test::Unit::TestCase
|
@@ -18,47 +15,67 @@ class TC_Win32_Mutex < Test::Unit::TestCase
|
|
18
15
|
end
|
19
16
|
|
20
17
|
def test_version
|
21
|
-
assert_equal('0.
|
18
|
+
assert_equal('0.4.0', Win32::Mutex::VERSION)
|
19
|
+
end
|
20
|
+
|
21
|
+
test "constructor with no arguments works as expected" do
|
22
|
+
mutex = nil
|
23
|
+
assert_nothing_raised{ mutex = Win32::Mutex.new }
|
24
|
+
mutex.close
|
22
25
|
end
|
23
26
|
|
24
|
-
|
27
|
+
test "default attributes are set to expected values" do
|
28
|
+
mutex = Win32::Mutex.new
|
29
|
+
assert_false(mutex.initial_owner?)
|
30
|
+
assert_true(mutex.inheritable?)
|
31
|
+
assert_nil(mutex.name)
|
32
|
+
mutex.close
|
33
|
+
end
|
34
|
+
|
35
|
+
test "open method works as expected" do
|
25
36
|
assert_respond_to(Win32::Mutex, :open)
|
26
37
|
assert_nothing_raised{ Win32::Mutex.open('test'){} }
|
27
38
|
assert_nothing_raised{ Win32::Mutex.open('Ηελλας'){} }
|
28
39
|
end
|
29
40
|
|
30
|
-
|
31
|
-
assert_raise(
|
41
|
+
test "attempting to open an unknown mutex raises an error" do
|
42
|
+
assert_raise(Errno::ENOENT){ Win32::Mutex.open('bogus'){} }
|
32
43
|
end
|
33
44
|
|
34
|
-
|
45
|
+
test "release method works as expected" do
|
35
46
|
assert_respond_to(@mutex, :release)
|
36
47
|
assert_nothing_raised{ @mutex.release }
|
37
48
|
end
|
38
49
|
|
39
|
-
|
50
|
+
test "initial_owner? works as expected and returns expected value" do
|
40
51
|
assert_respond_to(@mutex, :initial_owner?)
|
41
52
|
assert_true(@mutex.initial_owner?)
|
42
53
|
assert_false(@umutex.initial_owner?)
|
43
54
|
end
|
44
55
|
|
45
|
-
|
56
|
+
test "inheritable? works as expected and returns expected value" do
|
46
57
|
assert_respond_to(@mutex, :inheritable?)
|
47
58
|
assert_true(@mutex.inheritable?)
|
48
59
|
end
|
49
60
|
|
50
|
-
|
61
|
+
test "wait method was inherited" do
|
51
62
|
assert_respond_to(@mutex, :wait)
|
52
63
|
end
|
53
64
|
|
54
|
-
|
65
|
+
test "wait_any method was inherited" do
|
55
66
|
assert_respond_to(@mutex, :wait_any)
|
56
67
|
end
|
57
68
|
|
58
|
-
|
69
|
+
test "wait_all method was inherited" do
|
59
70
|
assert_respond_to(@mutex, :wait_all)
|
60
71
|
end
|
61
72
|
|
73
|
+
test "ffi functions are private" do
|
74
|
+
assert_not_respond_to(Win32::Mutex, :CreateMutexW)
|
75
|
+
assert_not_respond_to(Win32::Mutex, :OpenMutexW)
|
76
|
+
assert_not_respond_to(Win32::Mutex, :ReleaseMutex)
|
77
|
+
end
|
78
|
+
|
62
79
|
def teardown
|
63
80
|
@mutex.close
|
64
81
|
@umutex.close
|
data/win32-mutex.gemspec
CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = 'win32-mutex'
|
5
|
-
spec.version = '0.
|
5
|
+
spec.version = '0.4.0'
|
6
6
|
spec.author = 'Daniel J. Berger'
|
7
7
|
spec.license = 'Artistic 2.0'
|
8
8
|
spec.email = 'djberg96@gmail.com'
|
@@ -13,12 +13,10 @@ Gem::Specification.new do |spec|
|
|
13
13
|
|
14
14
|
spec.rubyforge_project = 'win32utils'
|
15
15
|
spec.extra_rdoc_files = ['README', 'CHANGES', 'MANIFEST']
|
16
|
+
spec.required_ruby_version = '> 1.9.0'
|
16
17
|
|
17
|
-
spec.add_dependency('win32-ipc', '>= 0.
|
18
|
-
|
19
|
-
spec.add_development_dependency('test-unit', '>= 2.0.3')
|
20
|
-
spec.add_development_dependency('win32-process', '>= 0.6.1')
|
21
|
-
spec.add_development_dependency('win32-mmap', '>= 0.2.2')
|
18
|
+
spec.add_dependency('win32-ipc', '>= 0.6.0')
|
19
|
+
spec.add_development_dependency('test-unit')
|
22
20
|
|
23
21
|
spec.description = <<-EOF
|
24
22
|
The win32-mutex library provides an interface for creating mutex objects
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: win32-mutex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,52 +9,40 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-07-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: win32-ipc
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 0.
|
21
|
+
version: 0.6.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
name: test-unit
|
27
|
-
requirement: &5841950 !ruby/object:Gem::Requirement
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
25
|
none: false
|
29
26
|
requirements:
|
30
27
|
- - ! '>='
|
31
28
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
33
|
-
type: :development
|
34
|
-
prerelease: false
|
35
|
-
version_requirements: *5841950
|
29
|
+
version: 0.6.0
|
36
30
|
- !ruby/object:Gem::Dependency
|
37
|
-
name:
|
38
|
-
requirement:
|
31
|
+
name: test-unit
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
39
33
|
none: false
|
40
34
|
requirements:
|
41
35
|
- - ! '>='
|
42
36
|
- !ruby/object:Gem::Version
|
43
|
-
version: 0
|
37
|
+
version: '0'
|
44
38
|
type: :development
|
45
39
|
prerelease: false
|
46
|
-
version_requirements:
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
name: win32-mmap
|
49
|
-
requirement: &5840660 !ruby/object:Gem::Requirement
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
41
|
none: false
|
51
42
|
requirements:
|
52
43
|
- - ! '>='
|
53
44
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0
|
55
|
-
type: :development
|
56
|
-
prerelease: false
|
57
|
-
version_requirements: *5840660
|
45
|
+
version: '0'
|
58
46
|
description: ! " The win32-mutex library provides an interface for creating mutex
|
59
47
|
objects\n on MS Windows. A mutex object is a synchronization object whose state\n
|
60
48
|
\ is set to signaled when it is not owned by any thread, and non-signaled\n when
|
@@ -85,9 +73,9 @@ require_paths:
|
|
85
73
|
required_ruby_version: !ruby/object:Gem::Requirement
|
86
74
|
none: false
|
87
75
|
requirements:
|
88
|
-
- - ! '
|
76
|
+
- - ! '>'
|
89
77
|
- !ruby/object:Gem::Version
|
90
|
-
version:
|
78
|
+
version: 1.9.0
|
91
79
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
80
|
none: false
|
93
81
|
requirements:
|
@@ -96,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
96
84
|
version: '0'
|
97
85
|
requirements: []
|
98
86
|
rubyforge_project: win32utils
|
99
|
-
rubygems_version: 1.8.
|
87
|
+
rubygems_version: 1.8.24
|
100
88
|
signing_key:
|
101
89
|
specification_version: 3
|
102
90
|
summary: Interface to MS Windows Mutex objects.
|