process_shared 0.1.7 → 0.1.8
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/pthread_sync_helper/extconf.rb +9 -0
- data/ext/pthread_sync_helper/pthread_sync_helper.c +43 -0
- data/ext/semaphore.c +623 -0
- data/lib/mach/functions.rb +6 -4
- data/lib/process_shared/posix/semaphore.rb +6 -3
- data/lib/process_shared/posix/shared_array.rb +71 -0
- data/lib/process_shared/thread.rb +30 -0
- data/lib/scratch.rb +300 -0
- data/spec/mach/scratch.rb +67 -0
- data/spec/mach/scratch2.rb +78 -0
- data/spec/process_shared/lock_behavior.rb +0 -1
- data/spec/process_shared/semaphore_spec.rb +59 -0
- metadata +46 -37
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
require 'mach'
|
4
|
+
require 'mach/functions'
|
5
|
+
|
6
|
+
include Mach
|
7
|
+
include Mach::Functions
|
8
|
+
|
9
|
+
def setup_recv_port
|
10
|
+
port = new_memory_pointer :mach_port_t
|
11
|
+
mach_port_allocate(mach_task_self, :receive, port)
|
12
|
+
p = port.get_uint(0)
|
13
|
+
mach_port_insert_right(mach_task_self, p, p, :make_send)
|
14
|
+
p
|
15
|
+
end
|
16
|
+
|
17
|
+
def send_port(remote_port, port)
|
18
|
+
puts "send_port: (in #{mach_task_self}) sending #{port} -> #{remote_port}"
|
19
|
+
msg = FFI::Struct.new(nil,
|
20
|
+
:header, MsgHeader,
|
21
|
+
:body, MsgBody,
|
22
|
+
:task_port, MsgPortDescriptor)
|
23
|
+
msg[:header].tap do |h|
|
24
|
+
h[:remote_port] = remote_port
|
25
|
+
h[:local_port] = 0
|
26
|
+
h[:bits] = (MachMsgType[:copy_send] | (0 << 8)) | 0x80000000 # MACH_MSGH_BITS_COMPLEX
|
27
|
+
h[:size] = msg.size
|
28
|
+
end
|
29
|
+
|
30
|
+
msg[:body][:descriptor_count] = 1
|
31
|
+
|
32
|
+
msg[:task_port].tap do |p|
|
33
|
+
p[:name] = port
|
34
|
+
p[:disposition] = MachMsgType[:copy_send]
|
35
|
+
p[:type] = 0 # MACH_MSG_PORT_DESCRIPTOR;
|
36
|
+
end
|
37
|
+
|
38
|
+
mach_msg_send(msg)
|
39
|
+
end
|
40
|
+
|
41
|
+
def recv_port(recv_port)
|
42
|
+
msg = FFI::Struct.new(nil,
|
43
|
+
:header, MsgHeader,
|
44
|
+
:body, MsgBody,
|
45
|
+
:task_port, MsgPortDescriptor,
|
46
|
+
:trailer, MsgTrailer)
|
47
|
+
|
48
|
+
mach_msg(msg, 2, 0, msg.size, recv_port, 0, 0)
|
49
|
+
|
50
|
+
msg.size.times do |i|
|
51
|
+
print "%02x " % msg.to_ptr.get_uint8(i)
|
52
|
+
end
|
53
|
+
puts
|
54
|
+
|
55
|
+
msg[:task_port][:name]
|
56
|
+
end
|
57
|
+
|
58
|
+
def sampling_fork
|
59
|
+
parent_recv_port = setup_recv_port
|
60
|
+
task_set_special_port(mach_task_self, :bootstrap, parent_recv_port)
|
61
|
+
|
62
|
+
fork do
|
63
|
+
parent_recv_port_p = new_memory_pointer :mach_port_t
|
64
|
+
task_get_special_port(mach_task_self, :bootstrap, parent_recv_port_p)
|
65
|
+
parent_recv_port = parent_recv_port_p.get_uint(0)
|
66
|
+
puts "child self:#{mach_task_self} parent_recv:#{parent_recv_port}"
|
67
|
+
|
68
|
+
child_recv_port = setup_recv_port
|
69
|
+
puts "child sending #{mach_task_self}"
|
70
|
+
send_port(parent_recv_port, mach_task_self)
|
71
|
+
end
|
72
|
+
|
73
|
+
task_set_special_port(mach_task_self, :bootstrap, Mach::Functions::bootstrap_port)
|
74
|
+
child_task = recv_port(parent_recv_port)
|
75
|
+
puts "parent received #{child_task}"
|
76
|
+
end
|
77
|
+
|
78
|
+
sampling_fork
|
@@ -91,6 +91,32 @@ module ProcessShared
|
|
91
91
|
end
|
92
92
|
end
|
93
93
|
end
|
94
|
+
|
95
|
+
it 'allows other threads in a process to continue while waiting' do
|
96
|
+
sem = Semaphore.new
|
97
|
+
was_set = false
|
98
|
+
t2 = nil
|
99
|
+
|
100
|
+
sem.synchronize do
|
101
|
+
t1 = Thread.new do
|
102
|
+
# give t2 a chance to wait on the lock, then set the flag
|
103
|
+
sleep 0.01
|
104
|
+
was_set = true
|
105
|
+
end
|
106
|
+
|
107
|
+
t2 = Thread.new do
|
108
|
+
sem.synchronize { }
|
109
|
+
end
|
110
|
+
|
111
|
+
# t1 should set the flag and die while t2 is still waiting on the lock
|
112
|
+
t1.join
|
113
|
+
end
|
114
|
+
|
115
|
+
was_set.must_equal true
|
116
|
+
|
117
|
+
t2.join
|
118
|
+
end
|
119
|
+
|
94
120
|
end
|
95
121
|
|
96
122
|
describe '#try_wait' do
|
@@ -131,6 +157,39 @@ module ProcessShared
|
|
131
157
|
::Process.wait(pid)
|
132
158
|
end
|
133
159
|
end
|
160
|
+
|
161
|
+
unless RUBY_VERSION == '1.8.7'
|
162
|
+
it 'allows other threads in a process to continue while waiting' do
|
163
|
+
start = Time.now.to_f
|
164
|
+
sem = Semaphore.new
|
165
|
+
was_set = false
|
166
|
+
t2 = nil
|
167
|
+
|
168
|
+
sem.synchronize do
|
169
|
+
t1 = Thread.new do
|
170
|
+
# give t2 a chance to wait on the lock, then set the flag
|
171
|
+
sleep 0.01
|
172
|
+
was_set = true
|
173
|
+
end
|
174
|
+
|
175
|
+
t2 = Thread.new do
|
176
|
+
begin
|
177
|
+
sem.try_wait(10.0)
|
178
|
+
rescue Errno::ETIMEDOUT
|
179
|
+
# success
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# t1 should set the flag and die while t2 is still waiting on the lock
|
184
|
+
t1.join
|
185
|
+
end
|
186
|
+
|
187
|
+
was_set.must_equal true
|
188
|
+
(Time.now.to_f - start).must be_lt(0.1)
|
189
|
+
|
190
|
+
t2.join
|
191
|
+
end
|
192
|
+
end
|
134
193
|
end
|
135
194
|
end
|
136
195
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: process_shared
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-12-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ffi
|
@@ -145,61 +145,70 @@ email: pat@polycrystal.org
|
|
145
145
|
executables: []
|
146
146
|
extensions:
|
147
147
|
- ext/helper/extconf.rb
|
148
|
+
- ext/pthread_sync_helper/extconf.rb
|
148
149
|
extra_rdoc_files:
|
149
150
|
- README.rdoc
|
150
151
|
- ChangeLog
|
151
152
|
- COPYING
|
152
153
|
files:
|
153
|
-
- lib/
|
154
|
-
- lib/mach/error.rb
|
155
|
-
- lib/mach/functions.rb
|
156
|
-
- lib/mach/host.rb
|
154
|
+
- lib/process_shared.rb
|
157
155
|
- lib/mach/port.rb
|
158
|
-
- lib/mach/
|
156
|
+
- lib/mach/host.rb
|
159
157
|
- lib/mach/task.rb
|
158
|
+
- lib/mach/error.rb
|
160
159
|
- lib/mach/time_spec.rb
|
160
|
+
- lib/mach/clock.rb
|
161
161
|
- lib/mach/types.rb
|
162
|
-
- lib/mach.rb
|
163
|
-
- lib/
|
164
|
-
- lib/process_shared/binary_semaphore.rb
|
165
|
-
- lib/process_shared/condition_variable.rb
|
166
|
-
- lib/process_shared/define_singleton_method.rb
|
167
|
-
- lib/process_shared/mach/semaphore.rb
|
168
|
-
- lib/process_shared/mach.rb
|
169
|
-
- lib/process_shared/monitor.rb
|
170
|
-
- lib/process_shared/monitor_mixin.rb
|
171
|
-
- lib/process_shared/mutex.rb
|
172
|
-
- lib/process_shared/object_buffer.rb
|
173
|
-
- lib/process_shared/open_with_self.rb
|
174
|
-
- lib/process_shared/posix/errno.rb
|
175
|
-
- lib/process_shared/posix/libc.rb
|
176
|
-
- lib/process_shared/posix/semaphore.rb
|
162
|
+
- lib/mach/semaphore.rb
|
163
|
+
- lib/mach/functions.rb
|
177
164
|
- lib/process_shared/posix/shared_memory.rb
|
178
|
-
- lib/process_shared/posix/
|
165
|
+
- lib/process_shared/posix/shared_array.rb
|
179
166
|
- lib/process_shared/posix/time_val.rb
|
167
|
+
- lib/process_shared/posix/errno.rb
|
168
|
+
- lib/process_shared/posix/time_spec.rb
|
169
|
+
- lib/process_shared/posix/semaphore.rb
|
170
|
+
- lib/process_shared/posix/libc.rb
|
180
171
|
- lib/process_shared/posix_call.rb
|
181
|
-
- lib/process_shared/process_error.rb
|
182
|
-
- lib/process_shared/rt.rb
|
183
172
|
- lib/process_shared/shared_array.rb
|
173
|
+
- lib/process_shared/mach/semaphore.rb
|
174
|
+
- lib/process_shared/process_error.rb
|
175
|
+
- lib/process_shared/condition_variable.rb
|
176
|
+
- lib/process_shared/define_singleton_method.rb
|
177
|
+
- lib/process_shared/thread.rb
|
184
178
|
- lib/process_shared/shared_memory_io.rb
|
185
|
-
- lib/process_shared/
|
179
|
+
- lib/process_shared/mach.rb
|
186
180
|
- lib/process_shared/time_spec.rb
|
187
|
-
- lib/process_shared.rb
|
181
|
+
- lib/process_shared/abstract_semaphore.rb
|
182
|
+
- lib/process_shared/binary_semaphore.rb
|
183
|
+
- lib/process_shared/mutex.rb
|
184
|
+
- lib/process_shared/monitor_mixin.rb
|
185
|
+
- lib/process_shared/synchronizable_semaphore.rb
|
186
|
+
- lib/process_shared/rt.rb
|
187
|
+
- lib/process_shared/open_with_self.rb
|
188
|
+
- lib/process_shared/object_buffer.rb
|
189
|
+
- lib/process_shared/monitor.rb
|
190
|
+
- lib/mach.rb
|
191
|
+
- lib/scratch.rb
|
188
192
|
- ext/helper/helper.c
|
193
|
+
- ext/semaphore.c
|
194
|
+
- ext/pthread_sync_helper/pthread_sync_helper.c
|
189
195
|
- ext/helper/extconf.rb
|
196
|
+
- ext/pthread_sync_helper/extconf.rb
|
197
|
+
- spec/spec_helper.rb
|
190
198
|
- spec/mach/port_spec.rb
|
191
|
-
- spec/mach/semaphore_spec.rb
|
192
199
|
- spec/mach/task_spec.rb
|
193
|
-
- spec/
|
194
|
-
- spec/
|
200
|
+
- spec/mach/semaphore_spec.rb
|
201
|
+
- spec/mach/scratch2.rb
|
202
|
+
- spec/mach/scratch.rb
|
203
|
+
- spec/process_shared/shared_memory_spec.rb
|
195
204
|
- spec/process_shared/lock_behavior.rb
|
196
|
-
- spec/process_shared/
|
197
|
-
- spec/process_shared/
|
205
|
+
- spec/process_shared/binary_semaphore_spec.rb
|
206
|
+
- spec/process_shared/shared_array_spec.rb
|
198
207
|
- spec/process_shared/mutex_spec.rb
|
208
|
+
- spec/process_shared/monitor_spec.rb
|
209
|
+
- spec/process_shared/monitor_mixin_spec.rb
|
199
210
|
- spec/process_shared/semaphore_spec.rb
|
200
|
-
- spec/process_shared/
|
201
|
-
- spec/process_shared/shared_memory_spec.rb
|
202
|
-
- spec/spec_helper.rb
|
211
|
+
- spec/process_shared/condition_variable_spec.rb
|
203
212
|
- README.rdoc
|
204
213
|
- ChangeLog
|
205
214
|
- COPYING
|
@@ -217,7 +226,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
217
226
|
version: '0'
|
218
227
|
segments:
|
219
228
|
- 0
|
220
|
-
hash: -
|
229
|
+
hash: -1670336126622666309
|
221
230
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
222
231
|
none: false
|
223
232
|
requirements:
|
@@ -226,7 +235,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
226
235
|
version: '0'
|
227
236
|
segments:
|
228
237
|
- 0
|
229
|
-
hash: -
|
238
|
+
hash: -1670336126622666309
|
230
239
|
requirements: []
|
231
240
|
rubyforge_project:
|
232
241
|
rubygems_version: 1.8.23
|