SysVIPC 0.9

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.
Files changed (4) hide show
  1. data/ext/SysVIPC.c +5090 -0
  2. data/ext/extconf.rb +8 -0
  3. data/lib/SysVIPC.rb +366 -0
  4. metadata +55 -0
@@ -0,0 +1,8 @@
1
+ require 'mkmf'
2
+
3
+ if have_header('sys/types.h') and have_header('sys/ipc.h') and
4
+ have_header('sys/msg.h') and have_func('msgget') and
5
+ have_header('sys/sem.h') and have_func('semget') and
6
+ have_header('sys/shm.h') and have_func('shmget')
7
+ create_makefile('SysVIPC')
8
+ end
@@ -0,0 +1,366 @@
1
+ require 'SysVIPC.so'
2
+
3
+ # Document-class: SysVIPC
4
+ #
5
+ # = SysVIPC
6
+ #
7
+ # Ruby module for System V Inter-Process Communication:
8
+ # message queues, semaphores, and shared memory.
9
+ #
10
+ # Hosted as project sysvipc[http://rubyforge.org/projects/sysvipc/]
11
+ # on RubyForge[http://rubyforge.org/].
12
+ #
13
+ # Copyright (C) 2001, 2006, 2007 Daiki Ueno
14
+ # Copyright (C) 2006, 2007, 2009 James Steven Jenkins
15
+ #
16
+ # == Usage Synopsis
17
+ # === Common Code
18
+ #
19
+ # All programs using this module must include
20
+ #
21
+ # require 'SysVIPC'
22
+ #
23
+ # It may be convenient to add
24
+ #
25
+ # include SysVIPC
26
+ #
27
+ # All IPC objects are identified by a key. SysVIPC includes a
28
+ # convenience function for mapping file names and integer IDs into a
29
+ # key:
30
+ #
31
+ # key = ftok('/a/file/that/must/exist', 0)
32
+ #
33
+ # === Message Queues
34
+ #
35
+ # Get (create if necessary) a message queue:
36
+ #
37
+ # mq = MessageQueue.new(key, IPC_CREAT | 0600)
38
+ #
39
+ # Send a message of type 0:
40
+ #
41
+ # mq.send(0, 'message')
42
+ #
43
+ # Receive up to 100 bytes from the first message of type 0:
44
+ #
45
+ # msg = mq.receive(0, 100)
46
+ #
47
+ # === Semaphores
48
+ #
49
+ # Get (create if necessary) a set of 5 semaphores:
50
+ #
51
+ # sm = Semaphore.new(key, 5, IPC_CREAT | 0600)
52
+ #
53
+ # Initialize semaphores if newly created:
54
+ #
55
+ # sm.setall(Array.new(5, 1)) if sm.pid(0) == 0
56
+ #
57
+ # Acquire semaphore 2 (waiting if necessary):
58
+ #
59
+ # sm.op([Sembuf.new(2, -1)])
60
+ #
61
+ # Release semaphore 2:
62
+ #
63
+ # sm.op([Sembuf.new(2, 1)])
64
+ #
65
+ # === Shared Memory
66
+ #
67
+ # Get (create if necessary) an 8192-byte shared memory region:
68
+ #
69
+ # sh = SharedMemory(key, 8192, IPC_CREAT | 0660)
70
+ #
71
+ # Attach shared memory:
72
+ #
73
+ # shmaddr = sh.attach
74
+ #
75
+ # Write data:
76
+ #
77
+ # shmaddr.write('testing')
78
+ #
79
+ # Read 100 bytes of data:
80
+ #
81
+ # data = shmaddr.read(100);
82
+ #
83
+ # Detach shared memory:
84
+ #
85
+ # sh.detach(shmaddr)
86
+ #
87
+ # == Installation
88
+ #
89
+ # 1. <tt>ruby setup.rb config</tt>
90
+ # 2. <tt>ruby setup.rb setup</tt>
91
+ # 3. <tt>ruby setup.rb install</tt> (requires appropriate privilege)
92
+ #
93
+ # == Testing
94
+ #
95
+ # 1. <tt>./test_sysvipc_l</tt> (low-level interface)
96
+ # 2. <tt>./test_sysvipc_h</tt> (high-level interface)
97
+
98
+ module SysVIPC
99
+
100
+ def check_result(res) # :nodoc:
101
+ raise SystemCallError.new(SysVIPC.errno), nil, caller if res == -1
102
+ end
103
+
104
+ class MessageQueue
105
+
106
+ private
107
+
108
+ # Return a MessageQueue object encapsuating a message queue
109
+ # associated with +key+. See msgget(2).
110
+
111
+ def initialize(key, flags = 0)
112
+ @msgid = msgget(key, flags)
113
+ check_result(@msgid)
114
+ end
115
+
116
+ public
117
+
118
+ # Return the Msqid_ds object. See msgctl(2).
119
+
120
+ def ipc_stat
121
+ res, msqid_ds = msgctl(@msgid, IPC_STAT)
122
+ check_result(res)
123
+ msqid_ds
124
+ end
125
+ alias :msqid_ds :ipc_stat
126
+
127
+ # Set the Msqid_ds object. See msgctl(2).
128
+
129
+ def ipc_set(msqid_ds)
130
+ unless Msqid_ds === msqid_ds
131
+ raise ArgumentError,
132
+ "argument to ipc_set must be a Msqid_ds"
133
+ end
134
+ check_result(msgctl(@msgid, IPC_SET, msqid_ds))
135
+ end
136
+ alias :msqid_ds= :ipc_set
137
+
138
+ # Remove. See msgctl(2).
139
+
140
+ def ipc_rmid
141
+ check_result(msgctl(@msgid, IPC_RMID, nil))
142
+ end
143
+ alias :rm :ipc_rmid
144
+
145
+ # Send a message with type +type+ and text +text+. See msgsnd(2).
146
+
147
+ def snd(type, text, flags = 0)
148
+ check_result(msgsnd(@msgid, type, text, flags))
149
+ end
150
+ alias :send :snd
151
+
152
+ # Receive a message of type +type+, limited to +len+ bytes or fewer.
153
+ # See msgsnd(2).
154
+
155
+ def rcv(type, size, flags = 0)
156
+ res, mtype, mtext = msgrcv(@msgid, size, type, flags)
157
+ check_result(res)
158
+ mtext
159
+ end
160
+ alias :receive :rcv
161
+
162
+ end
163
+
164
+ class Sembuf
165
+
166
+ alias :orig_initialize :initialize
167
+
168
+ # Create a new Sembuf object for semaphore number +sem_num+,
169
+ # operation +sem_op+, and flags +sem_flg+. See semop(2).
170
+
171
+ def initialize(sem_num, sem_op, sem_flg = 0)
172
+ orig_initialize
173
+ self.sem_num = sem_num
174
+ self.sem_op = sem_op
175
+ self.sem_flg = sem_flg
176
+ end
177
+
178
+ end
179
+
180
+ class Semaphore
181
+
182
+ private
183
+
184
+ # Return a Sempahore object encapsulating a
185
+ # set of +nsems+ semaphores associated with +key+. See semget(2).
186
+
187
+ def initialize(key, nsems, flags)
188
+ @nsems = nsems
189
+ @semid = semget(key, nsems, flags)
190
+ check_result(@semid)
191
+ end
192
+
193
+ public
194
+
195
+ # Set each value in the semaphore set to the corresponding value
196
+ # in the Array +values+. See semctl(2).
197
+
198
+ def setall(values)
199
+ if values.length > @nsems
200
+ raise ArgumentError,
201
+ "too many values(#{values.length} for semaphore set (#{@nsems})"
202
+ end
203
+ check_result(semctl(@semid, 0, SETALL, values))
204
+ end
205
+
206
+ # Return an Array containing the value of each semaphore in the
207
+ # set. See semctl(2).
208
+
209
+ def getall
210
+ res, array = semctl(@semid, 0, GETALL)
211
+ check_result(res)
212
+ array
213
+ end
214
+
215
+ # Set the value of semaphore +semnum+ to +val+. See semctl(2).
216
+
217
+ def setval(semnum, val)
218
+ check_result(semctl(@semid, semnum, SETVAL, val))
219
+ end
220
+
221
+ # Get the value of semaphore +semnum+. See semctl(2).
222
+
223
+ def getval(semnum)
224
+ semctl(@semid, semnum, GETVAL)
225
+ end
226
+ alias :val :getval
227
+
228
+ # Get the process ID of the last semaphore operation. See
229
+ # semctl(2).
230
+
231
+ def getpid
232
+ semctl(@semid, 0, GETPID)
233
+ end
234
+ alias :pid :getpid
235
+
236
+ # Get the number of processes waiting for a semaphore to become
237
+ # non-zero. See semctl(2).
238
+
239
+ def getncnt
240
+ semctl(@semid, 0, GETNCNT)
241
+ end
242
+ alias :ncnt :getncnt
243
+
244
+ # Get the number of processes waiting for a semaphore to become
245
+ # zero. See semctl(2).
246
+
247
+ def getzcnt
248
+ semctl(@semid, 0, GETZCNT)
249
+ end
250
+ alias :zcnt :getzcnt
251
+
252
+ # Return the Semid_ds object. See semctl(2).
253
+
254
+ def ipc_stat
255
+ res, semid_ds = semctl(@semid, 0, IPC_STAT)
256
+ check_result(res)
257
+ semid_ds
258
+ end
259
+ alias :semid_ds :ipc_stat
260
+
261
+ # Set the Semid_ds object. See semctl(2).
262
+
263
+ def ipc_set(semid_ds)
264
+ unless Semid_ds === semid_ds
265
+ raise ArgumentError,
266
+ "argument to ipc_set must be a Semid_ds"
267
+ end
268
+ check_result(semctl(@semid, 0, IPC_SET, semid_ds))
269
+ end
270
+ alias :semid_ds= :ipc_set
271
+
272
+ # Remove. See semctl(2).
273
+
274
+ def ipc_rmid
275
+ check_result(semctl(@semid, 0, IPC_RMID))
276
+ end
277
+ alias :rm :ipc_rmid
278
+
279
+ # Perform a set of semaphore operations. The argument +array+ is
280
+ # an Array of Sembuf objects. See semop(2).
281
+
282
+ def op(array)
283
+ check_result(semop(@semid, array, array.length))
284
+ end
285
+
286
+ end
287
+
288
+ class SharedMemory
289
+
290
+ private
291
+
292
+ # Return a SharedMemory object encapsulating a
293
+ # shared memory segment of +size+ bytes associated with
294
+ # +key+. See shmget(2).
295
+
296
+ def initialize(key, size, flags = 0)
297
+ @shmid = shmget(key, size, flags)
298
+ check_result(@shmid)
299
+ end
300
+
301
+ public
302
+
303
+ # Return the Shmid_ds object. See shmctl(2).
304
+
305
+ def ipc_stat
306
+ res, shmid_ds = shmctl(@shmid, IPC_STAT)
307
+ check_result(res)
308
+ shmid_ds
309
+ end
310
+ alias :shmid_ds :ipc_stat
311
+
312
+ # Set the Shmid_ds object. See shmctl(2).
313
+
314
+ def ipc_set(shmid_ds)
315
+ unless Shmid_ds === shmid_ds
316
+ raise ArgumentError,
317
+ "argument to ipc_set must be a Shmid_ds"
318
+ end
319
+ check_result(shmctl(@shmid, IPC_SET, shmid_ds))
320
+ end
321
+ alias shmid_ds= :ipc_set
322
+
323
+ # Remove. See shmctl(2).
324
+
325
+ def ipc_rmid
326
+ check_result(shmctl(@shmid, IPC_RMID, nil))
327
+ end
328
+ alias :rm :ipc_rmid
329
+
330
+ # Attach to a shared memory address object and return it.
331
+ # See shmat(2). If +shmaddr+ is nil, the shared memory is attached
332
+ # at the first available address as selected by the system. See
333
+ # shmat(2).
334
+
335
+ def attach(shmaddr = nil, flags = 0)
336
+ shmaddr = shmat(@shmid, shmaddr, flags)
337
+ check_result(shmaddr)
338
+ shmaddr
339
+ end
340
+
341
+ # Detach the +Shmaddr+ object +shmaddr+. See shmdt(2).
342
+
343
+ def detach(shmaddr)
344
+ check_result(shmdt(shmaddr))
345
+ end
346
+
347
+ end
348
+
349
+ class Shmaddr
350
+
351
+ # Write the string +text+ to offset +offset+.
352
+
353
+ def write(text, offset = 0)
354
+ shmwrite(self, text, offset)
355
+ end
356
+ alias :<< :write
357
+
358
+ # Read +len+ bytes at offset +offset+ and return them in a String.
359
+
360
+ def read(len, offset = 0)
361
+ shmread(self, len, offset)
362
+ end
363
+
364
+ end
365
+
366
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: SysVIPC
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.9"
5
+ platform: ruby
6
+ authors:
7
+ - Steven Jenkins
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-11 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: "System V Inter-Process Communication: message queues, semaphores, and shared memory."
17
+ email: sjenkins@rubyforge.org
18
+ executables: []
19
+
20
+ extensions:
21
+ - ./ext/extconf.rb
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/SysVIPC.rb
26
+ - ext/SysVIPC.c
27
+ has_rdoc: true
28
+ homepage: http://rubyforge.org/projects/sysvipc/
29
+ post_install_message:
30
+ rdoc_options:
31
+ - --title
32
+ - SysVIPC
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: "0"
40
+ version:
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ version:
47
+ requirements: []
48
+
49
+ rubyforge_project: sysvipc
50
+ rubygems_version: 1.3.1
51
+ signing_key:
52
+ specification_version: 2
53
+ summary: Builders for MarkUp.
54
+ test_files: []
55
+