ffi-rzmq 0.5.1 → 0.6.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/.gitignore +2 -0
- data/History.txt +35 -0
- data/README.rdoc +14 -30
- data/examples/README.rdoc +163 -0
- data/examples/local_throughput.rb +43 -0
- data/examples/remote_throughput.rb +27 -0
- data/examples/xreqxrep_poll.rb +1 -1
- data/ffi-rzmq.gemspec +8 -8
- data/lib/ffi-rzmq/context.rb +18 -8
- data/lib/ffi-rzmq/message.rb +112 -48
- data/lib/ffi-rzmq/poll_items.rb +1 -1
- data/lib/ffi-rzmq/socket.rb +43 -19
- data/lib/ffi-rzmq/wrapper.rb +4 -7
- data/lib/ffi-rzmq/zmq.rb +16 -3
- data/spec/context_spec.rb +10 -2
- data/spec/message_spec.rb +42 -0
- data/spec/pushpull_spec.rb +70 -0
- data/spec/socket_spec.rb +192 -13
- data/spec/spec_helper.rb +2 -0
- data/version.txt +1 -1
- metadata +75 -68
- data/.bnsignore +0 -22
- data/examples/async_req_rep.rb +0 -42
- data/examples/t +0 -5228
data/lib/ffi-rzmq/message.rb
CHANGED
@@ -15,10 +15,12 @@ module ZMQ
|
|
15
15
|
# calls #copy_in_string.
|
16
16
|
#
|
17
17
|
# Call #close to release buffers when you have *not* passed this on
|
18
|
-
# to Socket#send
|
19
|
-
# behalf.
|
18
|
+
# to Socket#send. That method calls #close on your behalf.
|
20
19
|
#
|
21
|
-
# (This class is not really zero-copy. Ruby makes this near impossible
|
20
|
+
# (This class is not really zero-copy. Ruby makes this near impossible
|
21
|
+
# since Ruby objects can be relocated in memory by the GC at any
|
22
|
+
# time. There is no way to peg them to native memory or have them
|
23
|
+
# use non-movable native memory as backing store.)
|
22
24
|
#
|
23
25
|
# Message represents ruby equivalent of the +zmq_msg_t+ C struct.
|
24
26
|
# Access the underlying memory buffer and the buffer size using the
|
@@ -32,41 +34,54 @@ module ZMQ
|
|
32
34
|
# necessary, so only decode (copy from the 0mq buffer to Ruby) that
|
33
35
|
# which is necessary.
|
34
36
|
#
|
35
|
-
# When you are done using a *received* message object,
|
36
|
-
#
|
37
|
-
# it will call the equivalent of #LibZMQ.zmq_msg_close to release
|
38
|
-
# all buffers. Obviously, this automatic collection of message objects
|
39
|
-
# comes at the price of a larger memory footprint (for the
|
40
|
-
# finalizer proc object) and lower performance. If you wanted blistering
|
41
|
-
# performance, Ruby isn't there just yet.
|
37
|
+
# When you are done using a *received* message object, call #close to
|
38
|
+
# release the associated buffers.
|
42
39
|
#
|
43
40
|
# As noted above, for sent objects the underlying library will call close
|
44
41
|
# for you.
|
45
42
|
#
|
46
43
|
# class MyMessage
|
44
|
+
# class Layout < FFI::Struct
|
45
|
+
# layout :value1, :uint8,
|
46
|
+
# :value2, :uint64,
|
47
|
+
# :value3, :uint32,
|
48
|
+
# :value4, [:char, 30]
|
49
|
+
# end
|
50
|
+
#
|
47
51
|
# def initialize msg_struct = nil
|
48
|
-
#
|
52
|
+
# if msg_struct
|
53
|
+
# @msg_t = msg_struct
|
54
|
+
# @data = Layout.new(@msg_t.data)
|
55
|
+
# else
|
56
|
+
# @pointer = FFI::MemoryPointer.new :byte, Layout.size, true
|
57
|
+
# @data = Layout.new @pointer
|
58
|
+
# end
|
49
59
|
# end
|
50
60
|
#
|
51
61
|
# def size() @size = @msg_t.size; end
|
52
62
|
#
|
53
|
-
# def
|
54
|
-
# @
|
63
|
+
# def value1
|
64
|
+
# @data[:value1]
|
55
65
|
# end
|
56
66
|
#
|
57
|
-
# def
|
58
|
-
# @
|
67
|
+
# def value4
|
68
|
+
# @data[:value4].to_ptr.read_string
|
59
69
|
# end
|
60
70
|
#
|
61
|
-
# def
|
62
|
-
# @
|
71
|
+
# def value1=(val)
|
72
|
+
# @data[:value1] = val
|
63
73
|
# end
|
64
|
-
#
|
74
|
+
#
|
75
|
+
# def create_sendable_message
|
76
|
+
# msg = Message.new
|
77
|
+
# msg.copy_in_bytes @pointer, Layout.size
|
78
|
+
# end
|
79
|
+
#
|
65
80
|
#
|
66
81
|
# message = Message.new
|
67
82
|
# successful_read = socket.recv message
|
68
83
|
# message = MyMessage.new message if successful_read
|
69
|
-
# puts "
|
84
|
+
# puts "value1 is #{message.value1}"
|
70
85
|
#
|
71
86
|
class Message
|
72
87
|
include ZMQ::Util
|
@@ -84,9 +99,8 @@ module ZMQ
|
|
84
99
|
copy_in_string message
|
85
100
|
else
|
86
101
|
# initialize an empty message structure to receive a message
|
87
|
-
result_code = LibZMQ.zmq_msg_init @
|
102
|
+
result_code = LibZMQ.zmq_msg_init @pointer
|
88
103
|
error_check ZMQ_MSG_INIT_STR, result_code
|
89
|
-
@state = :initialized
|
90
104
|
end
|
91
105
|
end
|
92
106
|
|
@@ -94,6 +108,11 @@ module ZMQ
|
|
94
108
|
# that libzmq can send it. The underlying library will handle
|
95
109
|
# deallocation of the native memory buffer.
|
96
110
|
#
|
111
|
+
# Can only be initialized via #copy_in_string or #copy_in_bytes once.
|
112
|
+
#
|
113
|
+
# Can raise a MessageError when #copy_in_string or #copy_in_bytes is
|
114
|
+
# called multiple times on the same instance.
|
115
|
+
#
|
97
116
|
def copy_in_string string
|
98
117
|
copy_in_bytes string, string.size if string
|
99
118
|
end
|
@@ -101,25 +120,23 @@ module ZMQ
|
|
101
120
|
# Makes a copy of +len+ bytes from the ruby string +bytes+. Library
|
102
121
|
# handles deallocation of the native memory buffer.
|
103
122
|
#
|
123
|
+
# Can only be initialized via #copy_in_string or #copy_in_bytes once.
|
124
|
+
#
|
125
|
+
# Can raise a MessageError when #copy_in_string or #copy_in_bytes is
|
126
|
+
# called multiple times on the same instance.
|
127
|
+
#
|
104
128
|
def copy_in_bytes bytes, len
|
105
|
-
#
|
106
|
-
# reused
|
107
|
-
close unless uninitialized? # FIXME: this is a bug waiting to happen
|
129
|
+
raise MessageError.new "#{self}", -1, -1, "This object cannot be reused; allocate a new one!" if initialized?
|
108
130
|
|
109
131
|
data_buffer = LibC.malloc len
|
110
132
|
# writes the exact number of bytes, no null byte to terminate string
|
111
133
|
data_buffer.write_string bytes, len
|
112
134
|
|
113
|
-
#
|
114
|
-
#
|
115
|
-
|
135
|
+
# use libC to call free on the data buffer; earlier versions used an
|
136
|
+
# FFI::Function here that called back into Ruby, but Rubinius won't
|
137
|
+
# support that and there are issues with the other runtimes too
|
138
|
+
result_code = LibZMQ.zmq_msg_init_data @pointer, data_buffer, len, LibC::Free, nil
|
116
139
|
|
117
|
-
unless RBX
|
118
|
-
result_code = LibZMQ.zmq_msg_init_data @struct.pointer, data_buffer, len, LibZMQ::MessageDeallocator, nil
|
119
|
-
else
|
120
|
-
# no callback for freeing up memory; memory leak!
|
121
|
-
result_code = LibZMQ.zmq_msg_init_data @struct.pointer, data_buffer, len, nil, nil
|
122
|
-
end
|
123
140
|
error_check ZMQ_MSG_INIT_DATA_STR, result_code
|
124
141
|
@state = :initialized
|
125
142
|
end
|
@@ -129,18 +146,18 @@ module ZMQ
|
|
129
146
|
# require a real data address.
|
130
147
|
#
|
131
148
|
def address
|
132
|
-
@
|
149
|
+
@pointer
|
133
150
|
end
|
134
151
|
alias :pointer :address
|
135
152
|
|
136
153
|
def copy source
|
137
|
-
result_code = LibZMQ.zmq_msg_copy @
|
154
|
+
result_code = LibZMQ.zmq_msg_copy @pointer, source.address
|
138
155
|
error_check ZMQ_MSG_COPY_STR, result_code
|
139
156
|
@state = :initialized
|
140
157
|
end
|
141
158
|
|
142
159
|
def move source
|
143
|
-
result_code = LibZMQ.zmq_msg_copy @
|
160
|
+
result_code = LibZMQ.zmq_msg_copy @pointer, source.address
|
144
161
|
error_check ZMQ_MSG_MOVE_STR, result_code
|
145
162
|
@state = :initialized
|
146
163
|
end
|
@@ -148,7 +165,7 @@ module ZMQ
|
|
148
165
|
# Provides the size of the data buffer for this +zmq_msg_t+ C struct.
|
149
166
|
#
|
150
167
|
def size
|
151
|
-
LibZMQ.zmq_msg_size @
|
168
|
+
LibZMQ.zmq_msg_size @pointer
|
152
169
|
end
|
153
170
|
|
154
171
|
# Returns a pointer to the data buffer.
|
@@ -157,7 +174,7 @@ module ZMQ
|
|
157
174
|
# collected.
|
158
175
|
#
|
159
176
|
def data
|
160
|
-
LibZMQ.zmq_msg_data @
|
177
|
+
LibZMQ.zmq_msg_data @pointer
|
161
178
|
end
|
162
179
|
|
163
180
|
# Returns the data buffer as a string.
|
@@ -171,22 +188,69 @@ module ZMQ
|
|
171
188
|
# Manually release the message struct and its associated data
|
172
189
|
# buffer.
|
173
190
|
#
|
174
|
-
|
175
|
-
|
191
|
+
def close
|
192
|
+
LibZMQ.zmq_msg_close @pointer
|
193
|
+
end
|
194
|
+
|
195
|
+
|
196
|
+
private
|
197
|
+
|
198
|
+
def initialized?(); :initialized == @state; end
|
199
|
+
|
200
|
+
end # class Message
|
201
|
+
|
202
|
+
|
203
|
+
|
204
|
+
# A subclass of #Message that includes finalizers for deallocating
|
205
|
+
# native memory when this object is garbage collected. Note that on
|
206
|
+
# certain Ruby runtimes the use of finalizers can add 10s of
|
207
|
+
# microseconds of overhead for each message. The convenience comes
|
208
|
+
# at a price.
|
209
|
+
#
|
210
|
+
# The constructor optionally takes a string as an argument. It will
|
211
|
+
# copy this string to native memory in preparation for transmission.
|
212
|
+
# So, don't pass a string unless you intend to send it. Internally it
|
213
|
+
# calls #copy_in_string.
|
214
|
+
#
|
215
|
+
# Call #close to release buffers when you have *not* passed this on
|
216
|
+
# to Socket#send. That method calls #close on your behalf.
|
217
|
+
#
|
218
|
+
# When you are done using a *received* message object, just let it go out of
|
219
|
+
# scope to release the memory. During the next garbage collection run
|
220
|
+
# it will call the equivalent of #LibZMQ.zmq_msg_close to release
|
221
|
+
# all buffers. Obviously, this automatic collection of message objects
|
222
|
+
# comes at the price of a larger memory footprint (for the
|
223
|
+
# finalizer proc object) and lower performance. If you wanted blistering
|
224
|
+
# performance, Ruby isn't there just yet.
|
225
|
+
#
|
226
|
+
# As noted above, for sent objects the underlying library will call close
|
227
|
+
# for you.
|
228
|
+
#
|
229
|
+
class ManagedMessage < Message
|
230
|
+
# Makes a copy of +len+ bytes from the ruby string +bytes+. Library
|
231
|
+
# handles deallocation of the native memory buffer.
|
232
|
+
#
|
233
|
+
def copy_in_bytes bytes, len
|
234
|
+
super
|
235
|
+
|
236
|
+
# make sure we have a way to deallocate this memory if the object goes
|
237
|
+
# out of scope
|
238
|
+
define_finalizer
|
239
|
+
end
|
240
|
+
|
241
|
+
# Manually release the message struct and its associated data
|
242
|
+
# buffer.
|
176
243
|
#
|
177
244
|
def close
|
178
|
-
|
245
|
+
super
|
179
246
|
remove_finalizer
|
180
|
-
@state = :uninitialized
|
181
247
|
end
|
182
248
|
|
183
249
|
|
184
250
|
private
|
185
251
|
|
186
|
-
def uninitialized?(); :uninitialized == @state; end
|
187
|
-
|
188
252
|
def define_finalizer
|
189
|
-
ObjectSpace.define_finalizer(self, self.class.close(@
|
253
|
+
ObjectSpace.define_finalizer(self, self.class.close(@pointer))
|
190
254
|
end
|
191
255
|
|
192
256
|
def remove_finalizer
|
@@ -198,13 +262,13 @@ module ZMQ
|
|
198
262
|
# This is intentional. Since this code runs as a finalizer, there is no
|
199
263
|
# way to catch a raised exception anywhere near where the error actually
|
200
264
|
# occurred in the code, so we just ignore deallocation failures here.
|
201
|
-
def self.close
|
265
|
+
def self.close ptr
|
202
266
|
Proc.new do
|
203
267
|
# release the data buffer
|
204
|
-
LibZMQ.zmq_msg_close
|
268
|
+
LibZMQ.zmq_msg_close ptr
|
205
269
|
end
|
206
270
|
end
|
207
271
|
|
208
|
-
end # class
|
272
|
+
end # class ManagedMessage
|
209
273
|
|
210
274
|
end # module ZMQ
|
data/lib/ffi-rzmq/poll_items.rb
CHANGED
data/lib/ffi-rzmq/socket.rb
CHANGED
@@ -13,29 +13,38 @@ module ZMQ
|
|
13
13
|
class Socket
|
14
14
|
include ZMQ::Util
|
15
15
|
|
16
|
-
attr_reader :socket
|
16
|
+
attr_reader :socket, :name
|
17
17
|
|
18
|
-
#
|
19
|
-
# memory management.
|
18
|
+
# Allocates a socket of type +type+ for sending and receiving data.
|
20
19
|
#
|
21
20
|
# +type+ can be one of ZMQ::REQ, ZMQ::REP, ZMQ::PUB,
|
22
21
|
# ZMQ::SUB, ZMQ::PAIR, ZMQ::PULL, ZMQ::PUSH,
|
23
22
|
# ZMQ::XREQ or ZMQ::XREP.
|
24
23
|
#
|
24
|
+
# By default, this class uses ZMQ::Message for manual
|
25
|
+
# memory management. For automatic garbage collection of received messages,
|
26
|
+
# it is possible to override the :receiver_class to use ZMQ::ManagedMessage.
|
27
|
+
#
|
28
|
+
# sock = Socket.new(Context.new, ZMQ::REQ, :receiver_class => ZMQ::ManagedMessage)
|
29
|
+
#
|
30
|
+
# Advanced users may want to replace the receiver class with their
|
31
|
+
# own custom class. The custom class must conform to the same public API
|
32
|
+
# as ZMQ::Message.
|
33
|
+
#
|
25
34
|
# Can raise two kinds of exceptions depending on the error.
|
26
35
|
# ContextError:: Raised when a socket operation is attempted on a terminated
|
27
36
|
# #Context. See #ContextError.
|
28
37
|
# SocketError:: See all of the possibilities in the docs for #SocketError.
|
29
38
|
#
|
30
|
-
def initialize context_ptr, type
|
31
|
-
#
|
32
|
-
#
|
33
|
-
@
|
34
|
-
@receiver_klass = ZMQ::Message
|
39
|
+
def initialize context_ptr, type, opts = {:receiver_class => ZMQ::Message}
|
40
|
+
# users may override the classes used for receiving; class must conform to the
|
41
|
+
# same public API as ZMQ::Message
|
42
|
+
@receiver_klass = opts[:receiver_class]
|
35
43
|
|
36
44
|
unless context_ptr.null?
|
37
45
|
@socket = LibZMQ.zmq_socket context_ptr, type
|
38
46
|
error_check ZMQ_SOCKET_STR, @socket.null? ? 1 : 0
|
47
|
+
@name = SocketTypeNameMap[type]
|
39
48
|
else
|
40
49
|
raise ContextError.new ZMQ_SOCKET_STR, 0, ETERM, "Context pointer was null"
|
41
50
|
end
|
@@ -64,15 +73,18 @@ module ZMQ
|
|
64
73
|
# SocketError:: See all of the possibilities in the docs for #SocketError.
|
65
74
|
#
|
66
75
|
def setsockopt option_name, option_value, option_len = nil
|
76
|
+
option_value = sanitize_value option_name, option_value
|
77
|
+
option_len ||= option_value.size
|
78
|
+
|
67
79
|
begin
|
68
80
|
case option_name
|
69
|
-
when HWM, SWAP, AFFINITY, RATE, RECOVERY_IVL, MCAST_LOOP
|
70
|
-
option_value_ptr = LibC.malloc
|
81
|
+
when HWM, SWAP, AFFINITY, RATE, RECOVERY_IVL, MCAST_LOOP, SNDBUF, RCVBUF
|
82
|
+
option_value_ptr = LibC.malloc option_len
|
71
83
|
option_value_ptr.write_long option_value
|
72
84
|
|
73
85
|
when IDENTITY, SUBSCRIBE, UNSUBSCRIBE
|
74
86
|
# note: not checking errno for failed memory allocations :(
|
75
|
-
option_value_ptr = LibC.malloc
|
87
|
+
option_value_ptr = LibC.malloc option_len
|
76
88
|
option_value_ptr.write_string option_value
|
77
89
|
|
78
90
|
else
|
@@ -81,7 +93,7 @@ module ZMQ
|
|
81
93
|
error_check ZMQ_SETSOCKOPT_STR, EINVAL
|
82
94
|
end
|
83
95
|
|
84
|
-
result_code = LibZMQ.zmq_setsockopt @socket, option_name, option_value_ptr, option_len
|
96
|
+
result_code = LibZMQ.zmq_setsockopt @socket, option_name, option_value_ptr, option_len
|
85
97
|
error_check ZMQ_SETSOCKOPT_STR, result_code
|
86
98
|
ensure
|
87
99
|
LibC.free option_value_ptr unless option_value_ptr.nil? || option_value_ptr.null?
|
@@ -188,8 +200,8 @@ module ZMQ
|
|
188
200
|
error_check ZMQ_CLOSE_STR, result_code
|
189
201
|
end
|
190
202
|
|
191
|
-
# Queues the message for transmission. Message is assumed to
|
192
|
-
#
|
203
|
+
# Queues the message for transmission. Message is assumed to conform to the
|
204
|
+
# same public API as #Message.
|
193
205
|
#
|
194
206
|
# +flags+ may take two values:
|
195
207
|
# * 0 (default) - blocking operation
|
@@ -197,13 +209,14 @@ module ZMQ
|
|
197
209
|
# * ZMQ::SNDMORE - this message is part of a multi-part message
|
198
210
|
#
|
199
211
|
# Returns true when the message was successfully enqueued.
|
200
|
-
# Returns false
|
201
|
-
#
|
212
|
+
# Returns false under two conditions.
|
213
|
+
# 1. The message could not be enqueued
|
214
|
+
# 2. When +flags+ is set with ZMQ::NOBLOCK and the socket returned EAGAIN.
|
202
215
|
#
|
203
216
|
# The application code is *not* responsible for handling the +message+ object
|
204
|
-
# lifecycle when #send
|
217
|
+
# lifecycle when #send returns successfully or it raises an exception. The
|
205
218
|
# #send method takes ownership of the +message+ and its associated buffers.
|
206
|
-
#
|
219
|
+
# Both successful and failed calls will release the +message+ data buffer.
|
207
220
|
#
|
208
221
|
# Again, once a +message+ object has been passed to this method,
|
209
222
|
# do not try to access its #data buffer anymore. The 0mq library now owns it.
|
@@ -239,7 +252,7 @@ module ZMQ
|
|
239
252
|
# SocketError:: See all of the possibilities in the docs for #SocketError.
|
240
253
|
#
|
241
254
|
def send_string message_string, flags = 0
|
242
|
-
message =
|
255
|
+
message = Message.new
|
243
256
|
message.copy_in_string message_string
|
244
257
|
result = send message, flags
|
245
258
|
result
|
@@ -327,6 +340,17 @@ module ZMQ
|
|
327
340
|
[FFI::MemoryPointer.new(255), length]
|
328
341
|
end
|
329
342
|
end
|
343
|
+
|
344
|
+
def sanitize_value option_name, option_value
|
345
|
+
case option_name
|
346
|
+
when HWM, AFFINITY, SNDBUF, RCVBUF
|
347
|
+
option_value.abs
|
348
|
+
when MCAST_LOOP
|
349
|
+
option_value ? 1 : 0
|
350
|
+
else
|
351
|
+
option_value
|
352
|
+
end
|
353
|
+
end
|
330
354
|
|
331
355
|
def define_finalizer
|
332
356
|
ObjectSpace.define_finalizer(self, self.class.close(@socket))
|
data/lib/ffi-rzmq/wrapper.rb
CHANGED
@@ -3,7 +3,7 @@ require 'ffi' unless RBX # external gem
|
|
3
3
|
module LibC
|
4
4
|
extend FFI::Library
|
5
5
|
# figures out the correct libc for each platform including Windows
|
6
|
-
ffi_lib
|
6
|
+
library = ffi_lib(FFI::Library::LIBC).first
|
7
7
|
|
8
8
|
# memory allocators
|
9
9
|
attach_function :malloc, [:size_t], :pointer
|
@@ -11,6 +11,9 @@ module LibC
|
|
11
11
|
attach_function :valloc, [:size_t], :pointer
|
12
12
|
attach_function :realloc, [:pointer, :size_t], :pointer
|
13
13
|
attach_function :free, [:pointer], :void
|
14
|
+
|
15
|
+
# get a pointer to the free function; used for ZMQ::Message deallocation
|
16
|
+
Free = library.find_symbol('free')
|
14
17
|
|
15
18
|
# memory movers
|
16
19
|
attach_function :memcpy, [:pointer, :pointer, :size_t], :pointer
|
@@ -46,12 +49,6 @@ module LibZMQ
|
|
46
49
|
attach_function :zmq_msg_copy, [:pointer, :pointer], :int
|
47
50
|
attach_function :zmq_msg_move, [:pointer, :pointer], :int
|
48
51
|
|
49
|
-
unless RBX
|
50
|
-
MessageDeallocator = FFI::Function.new(:void, [:pointer, :pointer]) do |data_ptr, hint_ptr|
|
51
|
-
LibC.free data_ptr
|
52
|
-
end
|
53
|
-
MessageDeallocator.autorelease = false
|
54
|
-
end
|
55
52
|
|
56
53
|
# Used for casting pointers back to the struct
|
57
54
|
class Msg < FFI::Struct
|
data/lib/ffi-rzmq/zmq.rb
CHANGED
@@ -11,6 +11,18 @@ module ZMQ
|
|
11
11
|
XREP = 6
|
12
12
|
PULL = UPSTREAM = 7
|
13
13
|
PUSH = DOWNSTREAM = 8
|
14
|
+
|
15
|
+
SocketTypeNameMap = {
|
16
|
+
PAIR => "PAIR",
|
17
|
+
PUB => "PUB",
|
18
|
+
SUB => "SUB",
|
19
|
+
REQ => "REQ",
|
20
|
+
REP => "REP",
|
21
|
+
XREQ => "XREQ",
|
22
|
+
XREP => "XREP",
|
23
|
+
PULL => "PULL",
|
24
|
+
PUSH => "PUSH"
|
25
|
+
}
|
14
26
|
|
15
27
|
# Socket options
|
16
28
|
HWM = 1
|
@@ -120,18 +132,19 @@ module ZMQ
|
|
120
132
|
# send/recv. True only when #errno is EGAIN and +result_code+ is non-zero.
|
121
133
|
#
|
122
134
|
def error_check_nonblock result_code
|
123
|
-
|
124
|
-
queue_operation
|
135
|
+
!result_code.zero? && eagain? ? false : true
|
125
136
|
end
|
126
137
|
|
127
138
|
def raise_error source, result_code
|
128
139
|
case source
|
129
|
-
when ZMQ_SOCKET_STR, ZMQ_SETSOCKOPT_STR, ZMQ_GETSOCKOPT_STR, ZMQ_BIND_STR, ZMQ_CONNECT_STR
|
140
|
+
when ZMQ_SEND_STR, ZMQ_RECV_STR, ZMQ_SOCKET_STR, ZMQ_SETSOCKOPT_STR, ZMQ_GETSOCKOPT_STR, ZMQ_BIND_STR, ZMQ_CONNECT_STR
|
130
141
|
raise SocketError.new source, result_code, errno, error_string
|
131
142
|
when ZMQ_INIT_STR, ZMQ_TERM_STR
|
132
143
|
raise ContextError.new source, result_code, errno, error_string
|
133
144
|
when ZMQ_POLL_STR
|
134
145
|
raise PollError.new source, result_code, errno, error_string
|
146
|
+
when ZMQ_MSG_INIT_STR, ZMQ_MSG_INIT_DATA_STR, ZMQ_MSG_COPY_STR, ZMQ_MSG_MOVE_STR
|
147
|
+
raise MessageError.new source, result_code, errno, error_string
|
135
148
|
else
|
136
149
|
raise ZeroMQError.new source, result_code, -1,
|
137
150
|
"Source [#{source}] does not match any zmq_* strings, rc [#{result_code}], errno [#{errno}], error_string [#{error_string}]"
|