ffi-rzmq 1.0.3 → 2.0.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.
- checksums.yaml +7 -0
- data/.travis.yml +1 -1
- data/AUTHORS.txt +5 -1
- data/History.txt +19 -0
- data/README.rdoc +2 -4
- data/examples/README.rdoc +1 -3
- data/examples/{v3api/latency_measurement.rb → latency_measurement.rb} +1 -2
- data/examples/{v3api/local_lat.rb → local_lat.rb} +1 -1
- data/examples/{v3api/local_lat_poll.rb → local_lat_poll.rb} +4 -4
- data/examples/{v3api/local_throughput.rb → local_throughput.rb} +1 -1
- data/examples/{v3api/pub.rb → pub.rb} +1 -1
- data/examples/{v2api/publish_subscribe.rb → publish_subscribe.rb} +2 -2
- data/examples/{v2api/remote_lat.rb → remote_lat.rb} +1 -1
- data/examples/{v3api/remote_throughput.rb → remote_throughput.rb} +4 -3
- data/examples/{v2api/reqrep_poll.rb → reqrep_poll.rb} +3 -4
- data/examples/{v2api/request_response.rb → request_response.rb} +1 -2
- data/examples/{v3api/sub.rb → sub.rb} +1 -2
- data/examples/{v3api/throughput_measurement.rb → throughput_measurement.rb} +1 -1
- data/examples/{v3api/xreqxrep_poll.rb → xreqxrep_poll.rb} +6 -7
- data/ffi-rzmq.gemspec +4 -4
- data/lib/ffi-rzmq.rb +2 -3
- data/lib/ffi-rzmq/context.rb +25 -53
- data/lib/ffi-rzmq/device.rb +8 -4
- data/lib/ffi-rzmq/message.rb +24 -30
- data/lib/ffi-rzmq/poll.rb +5 -16
- data/lib/ffi-rzmq/socket.rb +129 -278
- data/lib/ffi-rzmq/util.rb +11 -36
- data/lib/ffi-rzmq/version.rb +1 -1
- data/spec/context_spec.rb +3 -8
- data/spec/device_spec.rb +10 -9
- data/spec/nonblocking_recv_spec.rb +7 -7
- data/spec/pushpull_spec.rb +8 -7
- data/spec/reqrep_spec.rb +6 -6
- data/spec/socket_spec.rb +43 -130
- data/spec/spec_helper.rb +3 -11
- metadata +77 -104
- data/examples/v2api/latency_measurement.rb +0 -139
- data/examples/v2api/local_lat.rb +0 -58
- data/examples/v2api/local_lat_poll.rb +0 -66
- data/examples/v2api/local_throughput.rb +0 -58
- data/examples/v2api/pub.rb +0 -46
- data/examples/v2api/remote_throughput.rb +0 -39
- data/examples/v2api/sub.rb +0 -74
- data/examples/v2api/throughput_measurement.rb +0 -138
- data/examples/v2api/xreqxrep_poll.rb +0 -93
- data/examples/v3api/publish_subscribe.rb +0 -82
- data/examples/v3api/remote_lat.rb +0 -71
- data/examples/v3api/reqrep_poll.rb +0 -62
- data/examples/v3api/request_response.rb +0 -40
- data/lib/ffi-rzmq/constants.rb +0 -187
- data/lib/ffi-rzmq/libc.rb +0 -19
- data/lib/ffi-rzmq/libzmq.rb +0 -283
data/lib/ffi-rzmq/libzmq.rb
DELETED
@@ -1,283 +0,0 @@
|
|
1
|
-
module ZMQ
|
2
|
-
|
3
|
-
# Wraps the libzmq library and attaches to the functions that are
|
4
|
-
# common across the 2.x and 3.x APIs.
|
5
|
-
#
|
6
|
-
module LibZMQ
|
7
|
-
extend FFI::Library
|
8
|
-
|
9
|
-
begin
|
10
|
-
# bias the library discovery to a path inside the gem first, then
|
11
|
-
# to the usual system paths
|
12
|
-
inside_gem = File.join(File.dirname(__FILE__), '..', '..', 'ext')
|
13
|
-
local_path = FFI::Platform::IS_WINDOWS ? ENV['PATH'].split(';') : ENV['PATH'].split(':')
|
14
|
-
|
15
|
-
# Search for libzmq in the following order...
|
16
|
-
ZMQ_LIB_PATHS =([inside_gem] + local_path + [
|
17
|
-
'/usr/local/lib', '/opt/local/lib', '/usr/local/homebrew/lib', '/usr/lib64'
|
18
|
-
]).map{|path| "#{path}/libzmq.#{FFI::Platform::LIBSUFFIX}"}
|
19
|
-
ffi_lib(ZMQ_LIB_PATHS + %w{libzmq})
|
20
|
-
rescue LoadError => e
|
21
|
-
if ZMQ_LIB_PATHS.any? {|path| File.file?(path) }
|
22
|
-
warn "Unable to load this gem. The libzmq library exists, but cannot be loaded."
|
23
|
-
warn "If this is Windows:"
|
24
|
-
warn "- Check that you have MSVC runtime installed or statically linked"
|
25
|
-
warn "- Check that your DLL is compiled for #{FFI::Platform::ADDRESS_SIZE} bit"
|
26
|
-
else
|
27
|
-
warn "Unable to load this gem. The libzmq library (or DLL) could not be found."
|
28
|
-
warn "If this is a Windows platform, make sure libzmq.dll is on the PATH."
|
29
|
-
warn "If the DLL was built with mingw, make sure the other two dependent DLLs,"
|
30
|
-
warn "libgcc_s_sjlj-1.dll and libstdc++6.dll, are also on the PATH."
|
31
|
-
warn "For non-Windows platforms, make sure libzmq is located in this search path:"
|
32
|
-
warn ZMQ_LIB_PATHS.inspect
|
33
|
-
end
|
34
|
-
raise LoadError, e.message
|
35
|
-
end
|
36
|
-
# Size_t not working properly on Windows
|
37
|
-
find_type(:size_t) rescue typedef(:ulong, :size_t)
|
38
|
-
|
39
|
-
# Context and misc api
|
40
|
-
#
|
41
|
-
# @blocking = true is a hint to FFI that the following (and only the following)
|
42
|
-
# function may block, therefore it should release the GIL before calling it.
|
43
|
-
# This can aid in situations where the function call will/may block and another
|
44
|
-
# thread within the lib may try to call back into the ruby runtime. Failure to
|
45
|
-
# release the GIL will result in a hang; the hint *may* allow things to run
|
46
|
-
# smoothly for Ruby runtimes hampered by a GIL.
|
47
|
-
#
|
48
|
-
# This is really only honored by the MRI implementation but it *is* necessary
|
49
|
-
# otherwise the runtime hangs (and requires a kill -9 to terminate)
|
50
|
-
#
|
51
|
-
@blocking = true
|
52
|
-
attach_function :zmq_version, [:pointer, :pointer, :pointer], :void
|
53
|
-
@blocking = true
|
54
|
-
attach_function :zmq_errno, [], :int
|
55
|
-
@blocking = true
|
56
|
-
attach_function :zmq_strerror, [:int], :pointer
|
57
|
-
|
58
|
-
def self.version
|
59
|
-
if @version.nil?
|
60
|
-
major = FFI::MemoryPointer.new :int
|
61
|
-
minor = FFI::MemoryPointer.new :int
|
62
|
-
patch = FFI::MemoryPointer.new :int
|
63
|
-
LibZMQ.zmq_version major, minor, patch
|
64
|
-
@version = {:major => major.read_int, :minor => minor.read_int, :patch => patch.read_int}
|
65
|
-
end
|
66
|
-
|
67
|
-
@version
|
68
|
-
end
|
69
|
-
|
70
|
-
def self.version2?() version[:major] == 2 && version[:minor] >= 1 end
|
71
|
-
|
72
|
-
def self.version3?() version[:major] == 3 && version[:minor] >= 2 end
|
73
|
-
|
74
|
-
# Context initialization and destruction
|
75
|
-
@blocking = true
|
76
|
-
attach_function :zmq_init, [:int], :pointer
|
77
|
-
@blocking = true
|
78
|
-
attach_function :zmq_term, [:pointer], :int
|
79
|
-
|
80
|
-
# Message API
|
81
|
-
@blocking = true
|
82
|
-
attach_function :zmq_msg_init, [:pointer], :int
|
83
|
-
@blocking = true
|
84
|
-
attach_function :zmq_msg_init_size, [:pointer, :size_t], :int
|
85
|
-
@blocking = true
|
86
|
-
attach_function :zmq_msg_init_data, [:pointer, :pointer, :size_t, :pointer, :pointer], :int
|
87
|
-
@blocking = true
|
88
|
-
attach_function :zmq_msg_close, [:pointer], :int
|
89
|
-
@blocking = true
|
90
|
-
attach_function :zmq_msg_data, [:pointer], :pointer
|
91
|
-
@blocking = true
|
92
|
-
attach_function :zmq_msg_size, [:pointer], :size_t
|
93
|
-
@blocking = true
|
94
|
-
attach_function :zmq_msg_copy, [:pointer, :pointer], :int
|
95
|
-
@blocking = true
|
96
|
-
attach_function :zmq_msg_move, [:pointer, :pointer], :int
|
97
|
-
|
98
|
-
# Used for casting pointers back to the struct
|
99
|
-
#
|
100
|
-
class Msg < FFI::Struct
|
101
|
-
layout :content, :pointer,
|
102
|
-
:flags, :uint8,
|
103
|
-
:vsm_size, :uint8,
|
104
|
-
:vsm_data, [:uint8, 30]
|
105
|
-
end # class Msg
|
106
|
-
|
107
|
-
# Socket API
|
108
|
-
@blocking = true
|
109
|
-
attach_function :zmq_socket, [:pointer, :int], :pointer
|
110
|
-
@blocking = true
|
111
|
-
attach_function :zmq_setsockopt, [:pointer, :int, :pointer, :int], :int
|
112
|
-
@blocking = true
|
113
|
-
attach_function :zmq_getsockopt, [:pointer, :int, :pointer, :pointer], :int
|
114
|
-
@blocking = true
|
115
|
-
attach_function :zmq_bind, [:pointer, :string], :int
|
116
|
-
@blocking = true
|
117
|
-
attach_function :zmq_connect, [:pointer, :string], :int
|
118
|
-
@blocking = true
|
119
|
-
attach_function :zmq_close, [:pointer], :int
|
120
|
-
|
121
|
-
# Device API
|
122
|
-
@blocking = true
|
123
|
-
attach_function :zmq_device, [:int, :pointer, :pointer], :int
|
124
|
-
|
125
|
-
# Poll API
|
126
|
-
@blocking = true
|
127
|
-
attach_function :zmq_poll, [:pointer, :int, :long], :int
|
128
|
-
|
129
|
-
module PollItemLayout
|
130
|
-
def self.included(base)
|
131
|
-
if FFI::Platform::IS_WINDOWS && FFI::Platform::ADDRESS_SIZE==64
|
132
|
-
# On Windows, zmq.h defines fd as a SOCKET, which is 64 bits on x64.
|
133
|
-
fd_type=:uint64
|
134
|
-
else
|
135
|
-
fd_type=:int
|
136
|
-
end
|
137
|
-
base.class_eval do
|
138
|
-
layout :socket, :pointer,
|
139
|
-
:fd, fd_type,
|
140
|
-
:events, :short,
|
141
|
-
:revents, :short
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end # module PollItemLayout
|
145
|
-
|
146
|
-
class PollItem < FFI::Struct
|
147
|
-
include PollItemLayout
|
148
|
-
|
149
|
-
def socket() self[:socket]; end
|
150
|
-
|
151
|
-
def fd() self[:fd]; end
|
152
|
-
|
153
|
-
def readable?
|
154
|
-
(self[:revents] & ZMQ::POLLIN) > 0
|
155
|
-
end
|
156
|
-
|
157
|
-
def writable?
|
158
|
-
(self[:revents] & ZMQ::POLLOUT) > 0
|
159
|
-
end
|
160
|
-
|
161
|
-
def both_accessible?
|
162
|
-
readable? && writable?
|
163
|
-
end
|
164
|
-
|
165
|
-
def inspect
|
166
|
-
"socket [#{socket}], fd [#{fd}], events [#{self[:events]}], revents [#{self[:revents]}]"
|
167
|
-
end
|
168
|
-
|
169
|
-
def to_s; inspect; end
|
170
|
-
end # class PollItem
|
171
|
-
|
172
|
-
end
|
173
|
-
|
174
|
-
|
175
|
-
# Attaches to those functions specific to the 2.x API
|
176
|
-
#
|
177
|
-
if LibZMQ.version2?
|
178
|
-
|
179
|
-
module LibZMQ
|
180
|
-
# Socket api
|
181
|
-
@blocking = true
|
182
|
-
attach_function :zmq_recv, [:pointer, :pointer, :int], :int
|
183
|
-
@blocking = true
|
184
|
-
attach_function :zmq_send, [:pointer, :pointer, :int], :int
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
|
189
|
-
# Attaches to those functions specific to the 3.x API
|
190
|
-
#
|
191
|
-
if LibZMQ.version3?
|
192
|
-
|
193
|
-
module LibZMQ
|
194
|
-
# New Context API
|
195
|
-
@blocking = true
|
196
|
-
attach_function :zmq_ctx_new, [], :pointer
|
197
|
-
@blocking = true
|
198
|
-
attach_function :zmq_ctx_destroy, [:pointer], :int
|
199
|
-
@blocking = true
|
200
|
-
attach_function :zmq_ctx_set, [:pointer, :int, :int], :int
|
201
|
-
@blocking = true
|
202
|
-
attach_function :zmq_ctx_get, [:pointer, :int], :int
|
203
|
-
|
204
|
-
# Message API
|
205
|
-
@blocking = true
|
206
|
-
attach_function :zmq_msg_send, [:pointer, :pointer, :int], :int
|
207
|
-
@blocking = true
|
208
|
-
attach_function :zmq_msg_recv, [:pointer, :pointer, :int], :int
|
209
|
-
@blocking = true
|
210
|
-
attach_function :zmq_msg_more, [:pointer], :int
|
211
|
-
@blocking = true
|
212
|
-
attach_function :zmq_msg_get, [:pointer, :int], :int
|
213
|
-
@blocking = true
|
214
|
-
attach_function :zmq_msg_set, [:pointer, :int, :int], :int
|
215
|
-
|
216
|
-
# Monitoring API
|
217
|
-
# zmq_ctx_set_monitor is no longer supported as of version >= 3.2.1
|
218
|
-
# replaced by zmq_socket_monitor
|
219
|
-
if LibZMQ.version[:minor] > 2 || (LibZMQ.version[:minor] == 2 && LibZMQ.version[:patch] >= 1)
|
220
|
-
@blocking = true
|
221
|
-
attach_function :zmq_socket_monitor, [:pointer, :pointer, :int], :int
|
222
|
-
else
|
223
|
-
@blocking = true
|
224
|
-
attach_function :zmq_ctx_set_monitor, [:pointer, :pointer], :int
|
225
|
-
end
|
226
|
-
|
227
|
-
# Socket API
|
228
|
-
@blocking = true
|
229
|
-
attach_function :zmq_unbind, [:pointer, :string], :int
|
230
|
-
@blocking = true
|
231
|
-
attach_function :zmq_disconnect, [:pointer, :string], :int
|
232
|
-
@blocking = true
|
233
|
-
attach_function :zmq_recvmsg, [:pointer, :pointer, :int], :int
|
234
|
-
@blocking = true
|
235
|
-
attach_function :zmq_recv, [:pointer, :pointer, :size_t, :int], :int
|
236
|
-
@blocking = true
|
237
|
-
attach_function :zmq_sendmsg, [:pointer, :pointer, :int], :int
|
238
|
-
@blocking = true
|
239
|
-
attach_function :zmq_send, [:pointer, :pointer, :size_t, :int], :int
|
240
|
-
|
241
|
-
module EventDataLayout
|
242
|
-
def self.included(base)
|
243
|
-
base.class_eval do
|
244
|
-
layout :event, :int,
|
245
|
-
:addr, :string,
|
246
|
-
:field2, :int
|
247
|
-
end
|
248
|
-
end
|
249
|
-
end # module EventDataLayout
|
250
|
-
|
251
|
-
class EventData < FFI::Struct
|
252
|
-
include EventDataLayout
|
253
|
-
|
254
|
-
def event() self[:event]; end
|
255
|
-
|
256
|
-
def addr() self[:addr]; end
|
257
|
-
alias :address :addr
|
258
|
-
|
259
|
-
def fd() self[:field2]; end
|
260
|
-
alias :err :fd
|
261
|
-
alias :interval :fd
|
262
|
-
|
263
|
-
def inspect
|
264
|
-
"event [#{event}], addr [#{addr}], fd [#{fd}], field2 [#{fd}]"
|
265
|
-
end
|
266
|
-
|
267
|
-
def to_s; inspect; end
|
268
|
-
end # class EventData
|
269
|
-
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
|
274
|
-
# Sanity check; print an error and exit if we are trying to load an unsupported
|
275
|
-
# version of libzmq.
|
276
|
-
#
|
277
|
-
unless LibZMQ.version2? || LibZMQ.version3?
|
278
|
-
hash = LibZMQ.version
|
279
|
-
version = "#{hash[:major]}.#{hash[:minor]}.#{hash[:patch]}"
|
280
|
-
raise LoadError, "The libzmq version #{version} is incompatible with ffi-rzmq."
|
281
|
-
end
|
282
|
-
|
283
|
-
end # module ZMQ
|