process_shared 0.0.4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/helper/extconf.rb +14 -0
- data/ext/helper/helper.c +70 -0
- data/lib/mach.rb +12 -0
- data/lib/mach/clock.rb +24 -0
- data/lib/mach/error.rb +56 -0
- data/lib/mach/functions.rb +342 -0
- data/lib/mach/host.rb +28 -0
- data/lib/mach/port.rb +143 -0
- data/lib/mach/semaphore.rb +74 -0
- data/lib/mach/task.rb +42 -0
- data/lib/mach/time_spec.rb +16 -0
- data/lib/process_shared.rb +17 -1
- data/lib/process_shared/binary_semaphore.rb +18 -7
- data/lib/process_shared/mach.rb +93 -0
- data/lib/process_shared/mach/semaphore.rb +39 -0
- data/lib/process_shared/posix/errno.rb +40 -0
- data/lib/process_shared/posix/libc.rb +78 -0
- data/lib/process_shared/posix/semaphore.rb +125 -0
- data/lib/process_shared/posix/shared_array.rb +71 -0
- data/lib/process_shared/posix/shared_memory.rb +82 -0
- data/lib/process_shared/posix/time_spec.rb +13 -0
- data/lib/process_shared/posix/time_val.rb +23 -0
- data/lib/process_shared/semaphore.rb +26 -73
- data/lib/process_shared/shared_array.rb +3 -1
- data/lib/process_shared/shared_memory.rb +10 -52
- data/lib/process_shared/time_spec.rb +22 -0
- data/spec/mach/port_spec.rb +21 -0
- data/spec/mach/scratch.rb +67 -0
- data/spec/mach/scratch2.rb +78 -0
- data/spec/mach/semaphore_spec.rb +60 -0
- data/spec/mach/task_spec.rb +31 -0
- data/spec/process_shared/scratch.rb +21 -0
- data/spec/process_shared/semaphore_spec.rb +12 -11
- data/spec/process_shared/shared_memory_spec.rb +1 -1
- metadata +46 -36
- data/ext/libpsem/bsem.c +0 -188
- data/ext/libpsem/bsem.h +0 -32
- data/ext/libpsem/constants.c +0 -22
- data/ext/libpsem/constants.h +0 -18
- data/ext/libpsem/extconf.rb +0 -40
- data/ext/libpsem/mempcpy.c +0 -7
- data/ext/libpsem/mempcpy.h +0 -13
- data/ext/libpsem/mutex.c +0 -15
- data/ext/libpsem/mutex.h +0 -14
- data/ext/libpsem/psem.c +0 -15
- data/ext/libpsem/psem.h +0 -45
- data/ext/libpsem/psem_error.c +0 -46
- data/ext/libpsem/psem_error.h +0 -11
- data/ext/libpsem/psem_posix.c +0 -160
- data/ext/libpsem/psem_posix.h +0 -10
- data/lib/process_shared/bounded_semaphore.rb +0 -46
- data/lib/process_shared/libc.rb +0 -36
- data/lib/process_shared/libpsem.bundle +0 -0
- data/lib/process_shared/libpsem.so +0 -0
- data/lib/process_shared/psem.rb +0 -113
- data/spec/process_shared/bounded_semaphore_spec.rb +0 -48
- data/spec/process_shared/libc_spec.rb +0 -9
- data/spec/process_shared/psem_spec.rb +0 -136
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
|
3
|
+
have_header('fcntl.h')
|
4
|
+
|
5
|
+
have_header('sys/mman.h')
|
6
|
+
|
7
|
+
have_header('semaphore.h')
|
8
|
+
have_type('sem_t', 'semaphore.h')
|
9
|
+
|
10
|
+
have_header('pthread.h')
|
11
|
+
have_type('pthread_mutex_t', 'pthread.h')
|
12
|
+
have_type('pthread_mutexattr_t', 'pthread.h')
|
13
|
+
|
14
|
+
create_makefile('helper')
|
data/ext/helper/helper.c
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
/****************************/
|
2
|
+
/* File descriptor controls */
|
3
|
+
/****************************/
|
4
|
+
|
5
|
+
#ifdef HAVE_FCNTL_H
|
6
|
+
#include <fcntl.h>
|
7
|
+
extern int o_rdwr;
|
8
|
+
int o_rdwr = O_RDWR;
|
9
|
+
extern int o_creat;
|
10
|
+
int o_creat = O_CREAT;
|
11
|
+
extern int o_excl;
|
12
|
+
int o_excl = O_EXCL;
|
13
|
+
#endif
|
14
|
+
|
15
|
+
/************************/
|
16
|
+
/* Memory Map constants */
|
17
|
+
/************************/
|
18
|
+
|
19
|
+
#ifdef HAVE_SYS_MMAN_H
|
20
|
+
#include <sys/mman.h>
|
21
|
+
|
22
|
+
extern int prot_read;
|
23
|
+
extern int prot_write;
|
24
|
+
extern int prot_exec;
|
25
|
+
extern int prot_none;
|
26
|
+
|
27
|
+
extern void * map_failed;
|
28
|
+
extern int map_shared;
|
29
|
+
extern int map_private;
|
30
|
+
|
31
|
+
int prot_read = PROT_READ;
|
32
|
+
int prot_write = PROT_WRITE;
|
33
|
+
int prot_exec = PROT_EXEC;
|
34
|
+
int prot_none = PROT_NONE;
|
35
|
+
|
36
|
+
void * map_failed = MAP_FAILED;
|
37
|
+
int map_shared = MAP_SHARED;
|
38
|
+
int map_private = MAP_PRIVATE;
|
39
|
+
#endif
|
40
|
+
|
41
|
+
/****************************************/
|
42
|
+
/* PThread and related types and macros */
|
43
|
+
/****************************************/
|
44
|
+
|
45
|
+
#ifdef HAVE_PTHREAD_H
|
46
|
+
#include <pthread.h>
|
47
|
+
extern int pthread_process_shared;
|
48
|
+
int pthread_process_shared = PTHREAD_PROCESS_SHARED;
|
49
|
+
#endif
|
50
|
+
|
51
|
+
#ifdef HAVE_TYPE_PTHREAD_MUTEX_T
|
52
|
+
extern size_t sizeof_pthread_mutex_t;
|
53
|
+
size_t sizeof_pthread_mutex_t = sizeof (pthread_mutex_t);
|
54
|
+
size_t sizeof_pthread_mutexattr_t = sizeof (pthread_mutexattr_t);
|
55
|
+
#endif
|
56
|
+
|
57
|
+
#ifdef HAVE_TYPE_PTHREAD_MUTEXATTR_T
|
58
|
+
extern size_t sizeof_pthread_mutexattr_t;
|
59
|
+
#endif
|
60
|
+
|
61
|
+
/******************/
|
62
|
+
/* Semaphore type */
|
63
|
+
/******************/
|
64
|
+
|
65
|
+
#ifdef HAVE_TYPE_SEM_T
|
66
|
+
#include <semaphore.h>
|
67
|
+
extern size_t sizeof_sem_t;
|
68
|
+
size_t sizeof_sem_t = sizeof (sem_t);
|
69
|
+
#endif
|
70
|
+
|
data/lib/mach.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'mach/port'
|
2
|
+
require 'mach/semaphore'
|
3
|
+
require 'mach/task'
|
4
|
+
require 'mach/functions'
|
5
|
+
|
6
|
+
module Mach
|
7
|
+
# @return [Port] the original bootstrap port; different from that
|
8
|
+
# affected by {get,set}_special_port
|
9
|
+
def self.bootstrap_port
|
10
|
+
@bootstrap_port ||= Mach::Port.new(:port => Mach::Functions::bootstrap_port)
|
11
|
+
end
|
12
|
+
end
|
data/lib/mach/clock.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'mach/functions'
|
2
|
+
require 'mach/port'
|
3
|
+
require 'mach/time_spec'
|
4
|
+
|
5
|
+
module Mach
|
6
|
+
class Clock
|
7
|
+
include Functions
|
8
|
+
|
9
|
+
def initialize(clock_id)
|
10
|
+
@clock_id = clock_id
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
"#<#{self.class} #{@clock_id.to_i}>"
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_time
|
18
|
+
time = TimeSpec.new
|
19
|
+
clock_get_time(@clock_id.to_i, time)
|
20
|
+
time
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
data/lib/mach/error.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
require 'mach/functions'
|
4
|
+
|
5
|
+
module Mach
|
6
|
+
class Error < StandardError
|
7
|
+
class INVALID_ADDRESS < Error; end
|
8
|
+
class PROTECTION_FAILURE < Error; end
|
9
|
+
class NO_SPACE < Error; end
|
10
|
+
class INVALID_ARGUMENT < Error; end
|
11
|
+
class FAILURE < Error; end
|
12
|
+
class ABORTED < Error; end
|
13
|
+
class INVALID_NAME < Error; end
|
14
|
+
class OPERATION_TIMED_OUT < Error; end
|
15
|
+
|
16
|
+
include Functions
|
17
|
+
|
18
|
+
def self.new(msg, errno)
|
19
|
+
klass = case errno
|
20
|
+
when 1; then INVALID_ADDRESS
|
21
|
+
when 2; then PROTECTION_FAILURE
|
22
|
+
when 3; then NO_SPACE
|
23
|
+
when 4; then INVALID_ARGUMENT
|
24
|
+
when 5; then FAILURE
|
25
|
+
when 14; then ABORTED
|
26
|
+
when 15; then INVALID_NAME
|
27
|
+
when 49; then OPERATION_TIMED_OUT
|
28
|
+
else FAILURE
|
29
|
+
end
|
30
|
+
|
31
|
+
e = klass.allocate
|
32
|
+
e.send(:initialize, msg, errno)
|
33
|
+
e
|
34
|
+
end
|
35
|
+
|
36
|
+
attr_reader :errno
|
37
|
+
|
38
|
+
def initialize(msg, errno)
|
39
|
+
super(msg)
|
40
|
+
@errno = errno
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_s
|
44
|
+
"#{super}: #{error_string(errno)}"
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
|
49
|
+
# NOTE: api does not say this string must be freed; assuming it
|
50
|
+
# does not
|
51
|
+
def error_string(errno)
|
52
|
+
ptr = mach_error_string(errno)
|
53
|
+
ptr.null? ? nil : ptr.read_string()
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,342 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
require 'mach/time_spec'
|
4
|
+
|
5
|
+
module Mach
|
6
|
+
# FFI wrapper around a subset of the Mach API (likely Mac OS X
|
7
|
+
# specific).
|
8
|
+
module Functions
|
9
|
+
extend FFI::Library
|
10
|
+
|
11
|
+
ffi_lib 'c'
|
12
|
+
|
13
|
+
typedef :__darwin_mach_port_t, :mach_port_t
|
14
|
+
typedef :__darwin_natural_t, :natural_t
|
15
|
+
|
16
|
+
typedef :int, :integer_t
|
17
|
+
typedef :int, :kern_return_t # true for 64 bit??
|
18
|
+
typedef :int, :mach_error_t
|
19
|
+
typedef :int, :sync_policy_t # SyncPolicy
|
20
|
+
typedef :int, :clock_id_t
|
21
|
+
typedef :int, :clock_res_t
|
22
|
+
|
23
|
+
typedef :string, :name_t
|
24
|
+
|
25
|
+
typedef :mach_port_t, :host_t
|
26
|
+
typedef :mach_port_t, :task_t
|
27
|
+
typedef :mach_port_t, :ipc_space_t
|
28
|
+
typedef :mach_port_t, :semaphore_t
|
29
|
+
typedef :pointer, :mach_port_pointer_t
|
30
|
+
|
31
|
+
typedef :natural_t, :mach_port_name_t
|
32
|
+
typedef :natural_t, :mach_port_right_t # MachPortRight
|
33
|
+
typedef :pointer, :mach_port_name_array_t
|
34
|
+
typedef :pointer, :mach_port_name_pointer_t
|
35
|
+
|
36
|
+
typedef :uint, :mach_msg_type_name_t
|
37
|
+
typedef :uint, :mach_msg_bits_t
|
38
|
+
typedef :uint, :mach_msg_trailer_type_t
|
39
|
+
typedef :uint, :mach_msg_trailer_size_t
|
40
|
+
typedef :uint, :mach_msg_descriptor_type_t
|
41
|
+
typedef :natural_t, :mach_msg_timeout_t
|
42
|
+
|
43
|
+
typedef :natural_t, :mach_msg_size_t
|
44
|
+
typedef :integer_t, :mach_msg_id_t
|
45
|
+
typedef :integer_t, :mach_msg_options_t
|
46
|
+
typedef :integer_t, :mach_msg_option_t
|
47
|
+
|
48
|
+
class MsgHeader < FFI::Struct
|
49
|
+
layout(:bits, :mach_msg_bits_t,
|
50
|
+
:size, :mach_msg_size_t,
|
51
|
+
:remote_port, :mach_port_t,
|
52
|
+
:local_port, :mach_port_t,
|
53
|
+
:reserved, :mach_msg_size_t,
|
54
|
+
:id, :mach_msg_id_t)
|
55
|
+
end
|
56
|
+
|
57
|
+
class MsgBody < FFI::Struct
|
58
|
+
layout(:descriptor_count, :mach_msg_size_t)
|
59
|
+
end
|
60
|
+
|
61
|
+
class MsgBase < FFI::Struct
|
62
|
+
layout(:header, MsgHeader,
|
63
|
+
:body, MsgBody)
|
64
|
+
end
|
65
|
+
|
66
|
+
class MsgTrailer < FFI::Struct
|
67
|
+
layout(:type, :mach_msg_trailer_type_t,
|
68
|
+
:size, :mach_msg_trailer_size_t)
|
69
|
+
end
|
70
|
+
|
71
|
+
class MsgPortDescriptor < FFI::Struct
|
72
|
+
layout(:name, :mach_port_t,
|
73
|
+
:pad1, :mach_msg_size_t, # FIXME: leave oout on __LP64__
|
74
|
+
:pad2, :uint16, # :uint
|
75
|
+
:disposition, :uint8, # :mach_msg_type_name_t
|
76
|
+
:type, :uint8) # :mach_msg_descriptor_type_t
|
77
|
+
end
|
78
|
+
|
79
|
+
SyncPolicy = enum( :fifo, 0x0,
|
80
|
+
:fixed_priority, 0x1,
|
81
|
+
:reversed, 0x2,
|
82
|
+
:order_mask, 0x3,
|
83
|
+
:lifo, 0x0 | 0x2, # um...
|
84
|
+
:max, 0x7 )
|
85
|
+
|
86
|
+
MachPortRight = enum( :send, 0,
|
87
|
+
:receive,
|
88
|
+
:send_once,
|
89
|
+
:port_set,
|
90
|
+
:dead_name,
|
91
|
+
:labelh,
|
92
|
+
:number )
|
93
|
+
|
94
|
+
# port type
|
95
|
+
def self.pt(*syms)
|
96
|
+
acc = 0
|
97
|
+
syms.each do |sym|
|
98
|
+
acc |= (1 << (MachPortRight[sym] + 16))
|
99
|
+
end
|
100
|
+
acc
|
101
|
+
end
|
102
|
+
|
103
|
+
MACH_PORT_NULL = 0
|
104
|
+
MACH_MSG_TIMEOUT_NONE = 0
|
105
|
+
|
106
|
+
MachPortType =
|
107
|
+
enum(:none, 0,
|
108
|
+
:send, pt(:send),
|
109
|
+
:receive, pt(:receive),
|
110
|
+
:send_once, pt(:send_once),
|
111
|
+
:port_set, pt(:port_set),
|
112
|
+
:dead_name, pt(:dead_name),
|
113
|
+
:labelh, pt(:labelh),
|
114
|
+
|
115
|
+
:send_receive, pt(:send, :receive),
|
116
|
+
:send_rights, pt(:send, :send_once),
|
117
|
+
:port_rights, pt(:send, :send_once, :receive),
|
118
|
+
:port_or_dead, pt(:send, :send_once, :receive, :dead_name),
|
119
|
+
:all_rights, pt(:send, :send_once, :receive, :dead_name, :port_set))
|
120
|
+
|
121
|
+
MachMsgType =
|
122
|
+
enum( :move_receive, 16, # must hold receive rights
|
123
|
+
:move_send, # must hold send rights
|
124
|
+
:move_send_once, # must hold sendonce rights
|
125
|
+
:copy_send, # must hold send rights
|
126
|
+
:make_send, # must hold receive rights
|
127
|
+
:make_send_once, # must hold receive rights
|
128
|
+
:copy_receive ) # must hold receive rights
|
129
|
+
|
130
|
+
MachSpecialPort =
|
131
|
+
enum( :kernel, 1,
|
132
|
+
:host,
|
133
|
+
:name,
|
134
|
+
:bootstrap )
|
135
|
+
|
136
|
+
KERN_SUCCESS = 0
|
137
|
+
|
138
|
+
# Replace methods in +syms+ with error checking wrappers that
|
139
|
+
# invoke the original method and raise a {SystemCallError}.
|
140
|
+
#
|
141
|
+
# The original method is invoked, and it's return value is passed
|
142
|
+
# to the block (or a default check). The block should return true
|
143
|
+
# if the return value indicates an error state.
|
144
|
+
def self.error_check(*syms, &is_err)
|
145
|
+
unless block_given?
|
146
|
+
is_err = lambda { |v| (v != KERN_SUCCESS) }
|
147
|
+
end
|
148
|
+
|
149
|
+
syms.each do |sym|
|
150
|
+
method = self.method(sym)
|
151
|
+
|
152
|
+
new_method_body = proc do |*args|
|
153
|
+
ret = method.call(*args)
|
154
|
+
if is_err.call(ret)
|
155
|
+
raise Error.new("error in #{sym}", ret)
|
156
|
+
else
|
157
|
+
ret
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
define_singleton_method(sym, &new_method_body)
|
162
|
+
define_method(sym, &new_method_body)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# Replace methods in +syms+ with error checking wrappers that
|
167
|
+
# invoke the original method and raise a {SystemCallError}.
|
168
|
+
#
|
169
|
+
# The original method is invoked, and it's return value is passed
|
170
|
+
# to the block (or a default check). The block should return true
|
171
|
+
# if the return value indicates an error state.
|
172
|
+
def self.error_check_bootstrap(*syms, &is_err)
|
173
|
+
unless block_given?
|
174
|
+
is_err = lambda { |v| (v != KERN_SUCCESS) }
|
175
|
+
end
|
176
|
+
|
177
|
+
syms.each do |sym|
|
178
|
+
method = self.method(sym)
|
179
|
+
|
180
|
+
new_method_body = proc do |*args|
|
181
|
+
ret = method.call(*args)
|
182
|
+
if is_err.call(ret)
|
183
|
+
ptr = bootstrap_strerror(ret)
|
184
|
+
msg = ptr.null? ? nil : ptr.read_string()
|
185
|
+
raise "error in #{sym}: #{msg}"
|
186
|
+
else
|
187
|
+
ret
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
define_singleton_method(sym, &new_method_body)
|
192
|
+
define_method(sym, &new_method_body)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
# Attach a function as with +attach_function+, but check the
|
197
|
+
# return value and raise an exception on errors.
|
198
|
+
def self.attach_mach_function(sym, argtypes, rettype)
|
199
|
+
attach_function(sym, argtypes, rettype)
|
200
|
+
error_check(sym)
|
201
|
+
end
|
202
|
+
|
203
|
+
def self.new_memory_pointer(type)
|
204
|
+
FFI::MemoryPointer.new(find_type(type))
|
205
|
+
end
|
206
|
+
|
207
|
+
def new_memory_pointer(type)
|
208
|
+
Mach::Functions.new_memory_pointer(type)
|
209
|
+
end
|
210
|
+
|
211
|
+
attach_function :mach_task_self, [], :task_t
|
212
|
+
attach_function :mach_error_string, [:mach_error_t], :pointer
|
213
|
+
|
214
|
+
#######################
|
215
|
+
# Bootstrap functions #
|
216
|
+
#######################
|
217
|
+
|
218
|
+
attach_variable :bootstrap_port, :mach_port_t
|
219
|
+
|
220
|
+
attach_function(:bootstrap_strerror,
|
221
|
+
[:kern_return_t],
|
222
|
+
:pointer)
|
223
|
+
|
224
|
+
attach_function(:bootstrap_register,
|
225
|
+
[:mach_port_t, :name_t, :mach_port_t],
|
226
|
+
:kern_return_t)
|
227
|
+
error_check_bootstrap :bootstrap_register
|
228
|
+
|
229
|
+
##################
|
230
|
+
# Port functions #
|
231
|
+
##################
|
232
|
+
|
233
|
+
attach_mach_function(:mach_port_allocate,
|
234
|
+
[:ipc_space_t,
|
235
|
+
MachPortRight,
|
236
|
+
:mach_port_name_pointer_t],
|
237
|
+
:kern_return_t)
|
238
|
+
|
239
|
+
attach_mach_function(:mach_port_destroy,
|
240
|
+
[:ipc_space_t,
|
241
|
+
:mach_port_name_t],
|
242
|
+
:kern_return_t)
|
243
|
+
|
244
|
+
attach_mach_function(:mach_port_deallocate,
|
245
|
+
[:ipc_space_t,
|
246
|
+
:mach_port_name_t],
|
247
|
+
:kern_return_t)
|
248
|
+
|
249
|
+
attach_mach_function(:mach_port_insert_right,
|
250
|
+
[:ipc_space_t,
|
251
|
+
:mach_port_name_t,
|
252
|
+
:mach_port_t,
|
253
|
+
MachMsgType],
|
254
|
+
:kern_return_t)
|
255
|
+
|
256
|
+
##################
|
257
|
+
# Host functions #
|
258
|
+
##################
|
259
|
+
|
260
|
+
attach_function :mach_host_self, [], :mach_port_t
|
261
|
+
|
262
|
+
attach_mach_function(:host_get_clock_service,
|
263
|
+
[:host_t,
|
264
|
+
:clock_id_t,
|
265
|
+
:pointer],
|
266
|
+
:kern_return_t)
|
267
|
+
|
268
|
+
##################
|
269
|
+
# Task functions #
|
270
|
+
##################
|
271
|
+
|
272
|
+
attach_mach_function(:task_get_special_port,
|
273
|
+
[:task_t,
|
274
|
+
MachSpecialPort,
|
275
|
+
:mach_port_pointer_t],
|
276
|
+
:kern_return_t)
|
277
|
+
|
278
|
+
attach_mach_function(:task_set_special_port,
|
279
|
+
[:task_t,
|
280
|
+
MachSpecialPort,
|
281
|
+
:mach_port_t],
|
282
|
+
:kern_return_t)
|
283
|
+
|
284
|
+
###################
|
285
|
+
# Clock functions #
|
286
|
+
###################
|
287
|
+
|
288
|
+
attach_mach_function(:clock_get_time,
|
289
|
+
[:clock_id_t,
|
290
|
+
TimeSpec],
|
291
|
+
:kern_return_t)
|
292
|
+
|
293
|
+
#####################
|
294
|
+
# Message functions #
|
295
|
+
#####################
|
296
|
+
|
297
|
+
attach_mach_function(:mach_msg_send,
|
298
|
+
[:pointer], # msg_header_t
|
299
|
+
:kern_return_t)
|
300
|
+
|
301
|
+
attach_mach_function(:mach_msg,
|
302
|
+
[:pointer, # msg_header_t
|
303
|
+
:mach_msg_option_t,
|
304
|
+
:mach_msg_size_t,
|
305
|
+
:mach_msg_size_t,
|
306
|
+
:mach_port_name_t,
|
307
|
+
:mach_msg_timeout_t,
|
308
|
+
:mach_port_name_t],
|
309
|
+
:kern_return_t)
|
310
|
+
|
311
|
+
attach_mach_function(:mach_msg_receive,
|
312
|
+
[:pointer], # msg_header_t
|
313
|
+
:kern_return_t)
|
314
|
+
|
315
|
+
#######################
|
316
|
+
# Semaphore functions #
|
317
|
+
#######################
|
318
|
+
|
319
|
+
attach_mach_function(:semaphore_create,
|
320
|
+
[:task_t, :pointer, SyncPolicy, :int],
|
321
|
+
:kern_return_t)
|
322
|
+
attach_mach_function(:semaphore_destroy,
|
323
|
+
[:task_t, :semaphore_t],
|
324
|
+
:kern_return_t)
|
325
|
+
|
326
|
+
attach_mach_function(:semaphore_signal,
|
327
|
+
[:semaphore_t],
|
328
|
+
:kern_return_t)
|
329
|
+
attach_mach_function(:semaphore_signal_all,
|
330
|
+
[:semaphore_t],
|
331
|
+
:kern_return_t)
|
332
|
+
attach_mach_function(:semaphore_wait,
|
333
|
+
[:semaphore_t],
|
334
|
+
:kern_return_t)
|
335
|
+
attach_mach_function(:semaphore_timedwait,
|
336
|
+
[:semaphore_t, TimeSpec.val],
|
337
|
+
:kern_return_t)
|
338
|
+
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
require 'mach/error'
|