ffi-rzmq 1.0.3 → 2.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +1 -1
  3. data/AUTHORS.txt +5 -1
  4. data/History.txt +45 -0
  5. data/README.rdoc +58 -28
  6. data/Rakefile +15 -0
  7. data/examples/README.rdoc +1 -3
  8. data/examples/{v3api/latency_measurement.rb → latency_measurement.rb} +1 -2
  9. data/examples/{v3api/local_lat.rb → local_lat.rb} +1 -1
  10. data/examples/{v3api/local_lat_poll.rb → local_lat_poll.rb} +4 -4
  11. data/examples/{v3api/local_throughput.rb → local_throughput.rb} +1 -1
  12. data/examples/{v3api/pub.rb → pub.rb} +1 -1
  13. data/examples/{v2api/publish_subscribe.rb → publish_subscribe.rb} +2 -2
  14. data/examples/{v2api/remote_lat.rb → remote_lat.rb} +1 -1
  15. data/examples/{v3api/remote_throughput.rb → remote_throughput.rb} +4 -3
  16. data/examples/repreq_over_curve.rb +60 -0
  17. data/examples/{v2api/reqrep_poll.rb → reqrep_poll.rb} +3 -4
  18. data/examples/{v2api/request_response.rb → request_response.rb} +1 -2
  19. data/examples/{v3api/sub.rb → sub.rb} +1 -2
  20. data/examples/{v3api/throughput_measurement.rb → throughput_measurement.rb} +1 -1
  21. data/examples/{v3api/xreqxrep_poll.rb → xreqxrep_poll.rb} +6 -7
  22. data/ffi-rzmq.gemspec +4 -4
  23. data/lib/ffi-rzmq.rb +2 -3
  24. data/lib/ffi-rzmq/context.rb +25 -53
  25. data/lib/ffi-rzmq/device.rb +8 -4
  26. data/lib/ffi-rzmq/exceptions.rb +3 -0
  27. data/lib/ffi-rzmq/message.rb +24 -30
  28. data/lib/ffi-rzmq/poll.rb +5 -16
  29. data/lib/ffi-rzmq/socket.rb +132 -282
  30. data/lib/ffi-rzmq/util.rb +28 -36
  31. data/lib/ffi-rzmq/version.rb +1 -1
  32. data/spec/context_spec.rb +18 -23
  33. data/spec/device_spec.rb +13 -12
  34. data/spec/message_spec.rb +13 -13
  35. data/spec/multipart_spec.rb +11 -11
  36. data/spec/nonblocking_recv_spec.rb +22 -22
  37. data/spec/poll_spec.rb +49 -49
  38. data/spec/pushpull_spec.rb +12 -11
  39. data/spec/reqrep_spec.rb +11 -11
  40. data/spec/socket_spec.rb +109 -196
  41. data/spec/spec_helper.rb +3 -11
  42. data/spec/util_spec.rb +29 -0
  43. metadata +80 -104
  44. data/examples/v2api/latency_measurement.rb +0 -139
  45. data/examples/v2api/local_lat.rb +0 -58
  46. data/examples/v2api/local_lat_poll.rb +0 -66
  47. data/examples/v2api/local_throughput.rb +0 -58
  48. data/examples/v2api/pub.rb +0 -46
  49. data/examples/v2api/remote_throughput.rb +0 -39
  50. data/examples/v2api/sub.rb +0 -74
  51. data/examples/v2api/throughput_measurement.rb +0 -138
  52. data/examples/v2api/xreqxrep_poll.rb +0 -93
  53. data/examples/v3api/publish_subscribe.rb +0 -82
  54. data/examples/v3api/remote_lat.rb +0 -71
  55. data/examples/v3api/reqrep_poll.rb +0 -62
  56. data/examples/v3api/request_response.rb +0 -40
  57. data/lib/ffi-rzmq/constants.rb +0 -187
  58. data/lib/ffi-rzmq/libc.rb +0 -19
  59. data/lib/ffi-rzmq/libzmq.rb +0 -283
@@ -1,6 +1,5 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ffi-rzmq')
3
-
2
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'ffi-rzmq')
4
3
 
5
4
  def assert(rc)
6
5
  raise "Last API call failed at #{caller(1)}" unless rc >= 0
@@ -38,7 +37,7 @@ until @done do
38
37
  payload = "#{ '3' * 1024 }"
39
38
 
40
39
  puts "sending payload nonblocking"
41
- assert(s1.send_string(payload, ZMQ::NonBlocking))
40
+ assert(s1.send_string(payload, ZMQ::DONTWAIT))
42
41
  @unsent = false
43
42
  end
44
43
 
@@ -46,7 +45,7 @@ until @done do
46
45
  if Time.now - start_time > 1
47
46
  poller.readables.each do |sock|
48
47
  received_msg = ''
49
- assert(sock.recv_string(received_msg, ZMQ::NonBlocking))
48
+ assert(sock.recv_string(received_msg, ZMQ::DONTWAIT))
50
49
 
51
50
  puts "message received [#{received_msg}]"
52
51
  @done = true
@@ -1,6 +1,5 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ffi-rzmq')
3
-
2
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'ffi-rzmq')
4
3
 
5
4
  def assert(rc)
6
5
  raise "Last API call failed at #{caller(1)}" unless rc >= 0
@@ -1,11 +1,10 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ffi-rzmq')
2
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'ffi-rzmq')
3
3
 
4
4
  #if ARGV.length != 3
5
5
  # puts "usage: ruby local_throughtput.rb <bind-to> <message-size> <message-count>"
6
6
  # Process.exit
7
7
  #end
8
- p ZMQ::Util.version
9
8
 
10
9
  def assert(rc)
11
10
  raise "Last API call failed at #{caller(1)}" unless rc >= 0
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ffi-rzmq')
1
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'ffi-rzmq')
2
2
  require 'thread'
3
3
 
4
4
  # Within a single process, we start up five threads. Main thread has a PUB (publisher)
@@ -1,6 +1,5 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ffi-rzmq')
3
-
2
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'ffi-rzmq')
4
3
 
5
4
  def assert(rc)
6
5
  raise "Last API call failed at #{caller(1)}" unless rc >= 0
@@ -43,7 +42,7 @@ until @done do
43
42
 
44
43
  5.times do |i|
45
44
  payload = "#{ i.to_s * 40 }"
46
- assert(s1.send_string(payload, ZMQ::NonBlocking))
45
+ assert(s1.send_string(payload, ZMQ::DONTWAIT))
47
46
  end
48
47
  @unsent = false
49
48
  end
@@ -54,12 +53,12 @@ until @done do
54
53
 
55
54
  if sock.identity =~ /xrep/
56
55
  routing_info = ''
57
- assert(sock.recv_string(routing_info, ZMQ::NonBlocking))
56
+ assert(sock.recv_string(routing_info, ZMQ::DONTWAIT))
58
57
  puts "routing_info received [#{routing_info}] on socket.identity [#{sock.identity}]"
59
58
  else
60
59
  routing_info = nil
61
60
  received_msg = ''
62
- assert(sock.recv_string(received_msg, ZMQ::NonBlocking))
61
+ assert(sock.recv_string(received_msg, ZMQ::DONTWAIT))
63
62
 
64
63
  # skip to the next iteration if received_msg is nil; that means we got an EAGAIN
65
64
  next unless received_msg
@@ -68,13 +67,13 @@ until @done do
68
67
 
69
68
  while sock.more_parts? do
70
69
  received_msg = ''
71
- assert(sock.recv_string(received_msg, ZMQ::NonBlocking))
70
+ assert(sock.recv_string(received_msg, ZMQ::DONTWAIT))
72
71
 
73
72
  puts "message received [#{received_msg}]"
74
73
  end
75
74
 
76
75
  puts "kick back a reply"
77
- assert(sock.send_string(routing_info, ZMQ::SNDMORE | ZMQ::NonBlocking)) if routing_info
76
+ assert(sock.send_string(routing_info, ZMQ::SNDMORE | ZMQ::DONTWAIT)) if routing_info
78
77
  time = Time.now.strftime "%Y-%m-%dT%H:%M:%S.#{Time.now.usec}"
79
78
  reply = "reply " + sock.identity.upcase + " #{time}"
80
79
  puts "sent reply [#{reply}], #{time}"
data/ffi-rzmq.gemspec CHANGED
@@ -11,9 +11,9 @@ Gem::Specification.new do |s|
11
11
  s.summary = %q{This gem wraps the ZeroMQ (0mq) networking library using Ruby FFI (foreign function interface).}
12
12
  s.description = %q{This gem wraps the ZeroMQ networking library using the ruby FFI (foreign
13
13
  function interface). It's a pure ruby wrapper so this gem can be loaded
14
- and run by any ruby runtime that supports FFI. That's all of the major ones -
15
- MRI, Rubinius and JRuby.}
14
+ and run by any ruby runtime that supports FFI. That's all of the major ones - MRI, Rubinius and JRuby.}
16
15
 
16
+ s.license = 'MIT'
17
17
  s.rubyforge_project = "ffi-rzmq"
18
18
 
19
19
  s.files = `git ls-files`.split("\n")
@@ -21,7 +21,7 @@ MRI, Rubinius and JRuby.}
21
21
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
22
  s.require_paths = ["lib"]
23
23
 
24
- s.add_runtime_dependency "ffi"#, [">= 1.0.9"]
25
- s.add_development_dependency "rspec", ["~> 2.6"]
24
+ s.add_runtime_dependency "ffi-rzmq-core", [">= 1.0.1"]
25
+ s.add_development_dependency "rspec", ["~> 2.14"]
26
26
  s.add_development_dependency "rake"
27
27
  end
data/lib/ffi-rzmq.rb CHANGED
@@ -63,10 +63,9 @@ end # module ZMQ
63
63
  # some code is conditionalized based upon what ruby engine we are
64
64
  # executing
65
65
 
66
- require 'ffi'
66
+ require 'ffi-rzmq-core'
67
67
 
68
68
  # the order of files is important
69
- #%w(wrapper zmq exceptions context message socket poll_items poll device).each do |file|
70
- %w(libc libzmq constants util exceptions context message socket poll_items poll_item poll device).each do |file|
69
+ %w(util exceptions context message socket poll_items poll_item poll device version).each do |file|
71
70
  require ZMQ.libpath(['ffi-rzmq', file])
72
71
  end
@@ -47,44 +47,29 @@ module ZMQ
47
47
 
48
48
  # Use the factory method Context#create to make contexts.
49
49
  #
50
- if LibZMQ.version2?
51
- def self.create io_threads = 1
52
- new(io_threads) rescue nil
53
- end
54
-
55
- def initialize io_threads = 1
56
- @io_threads = io_threads
57
- @context = LibZMQ.zmq_init io_threads
58
- ZMQ::Util.error_check 'zmq_init', (@context.nil? || @context.null?) ? -1 : 0
59
-
60
- define_finalizer
61
- end
62
- elsif LibZMQ.version3?
50
+ def self.create(opts = {})
51
+ new(opts) rescue nil
52
+ end
63
53
 
64
- def self.create(opts = {})
65
- new(opts) rescue nil
54
+ def initialize(opts = {})
55
+ if opts.respond_to?(:empty?)
56
+ @io_threads = opts[:io_threads] || IO_THREADS_DFLT
57
+ @max_sockets = opts[:max_sockets] || MAX_SOCKETS_DFLT
58
+ else
59
+ @io_threads = opts || 1
60
+ @max_sockets = MAX_SOCKETS_DFLT
66
61
  end
67
62
 
68
- def initialize(opts = {})
69
- if opts.respond_to?(:empty?)
70
- @io_threads = opts[:io_threads] || IO_THREADS_DFLT
71
- @max_sockets = opts[:max_sockets] || MAX_SOCKETS_DFLT
72
- else
73
- @io_threads = opts || 1
74
- @max_sockets = MAX_SOCKETS_DFLT
75
- end
76
-
77
- @context = LibZMQ.zmq_ctx_new
78
- ZMQ::Util.error_check 'zmq_ctx_new', (@context.nil? || @context.null?) ? -1 : 0
63
+ @context = LibZMQ.zmq_ctx_new
64
+ ZMQ::Util.error_check 'zmq_ctx_new', (@context.nil? || @context.null?) ? -1 : 0
79
65
 
80
- rc = LibZMQ.zmq_ctx_set(@context, ZMQ::IO_THREADS, @io_threads)
81
- ZMQ::Util.error_check 'zmq_ctx_set', rc
66
+ rc = LibZMQ.zmq_ctx_set(@context, ZMQ::IO_THREADS, @io_threads)
67
+ ZMQ::Util.error_check 'zmq_ctx_set', rc
82
68
 
83
- rc = LibZMQ.zmq_ctx_set(@context, ZMQ::MAX_SOCKETS, @max_sockets)
84
- ZMQ::Util.error_check 'zmq_ctx_set', rc
69
+ rc = LibZMQ.zmq_ctx_set(@context, ZMQ::MAX_SOCKETS, @max_sockets)
70
+ ZMQ::Util.error_check 'zmq_ctx_set', rc
85
71
 
86
- define_finalizer
87
- end
72
+ define_finalizer
88
73
  end
89
74
 
90
75
  # Call to release the context and any remaining data associated
@@ -94,27 +79,14 @@ module ZMQ
94
79
  #
95
80
  # Returns 0 for success, -1 for failure.
96
81
  #
97
- if LibZMQ.version2?
98
- def terminate
99
- unless @context.nil? || @context.null?
100
- remove_finalizer
101
- rc = LibZMQ.zmq_term @context
102
- @context = nil
103
- rc
104
- else
105
- 0
106
- end
107
- end
108
- elsif LibZMQ.version3?
109
- def terminate
110
- unless @context.nil? || @context.null?
111
- remove_finalizer
112
- rc = LibZMQ.zmq_ctx_destroy(@context)
113
- @context = nil
114
- rc
115
- else
116
- 0
117
- end
82
+ def terminate
83
+ unless @context.nil? || @context.null?
84
+ remove_finalizer
85
+ rc = LibZMQ.zmq_ctx_destroy(@context)
86
+ @context = nil
87
+ rc
88
+ else
89
+ 0
118
90
  end
119
91
  end
120
92
 
@@ -3,10 +3,10 @@ module ZMQ
3
3
  class Device
4
4
  attr_reader :device
5
5
 
6
- def self.create(device_type, frontend, backend)
6
+ def self.create(frontend, backend, capture=nil)
7
7
  dev = nil
8
8
  begin
9
- dev = new(device_type, frontend, backend)
9
+ dev = new(frontend, backend, capture)
10
10
  rescue ArgumentError
11
11
  dev = nil
12
12
  end
@@ -14,15 +14,19 @@ module ZMQ
14
14
  dev
15
15
  end
16
16
 
17
- def initialize(device_type, frontend, backend)
17
+ def initialize(frontend, backend, capture=nil)
18
18
  [["frontend", frontend], ["backend", backend]].each do |name, socket|
19
19
  unless socket.is_a?(ZMQ::Socket)
20
20
  raise ArgumentError, "Expected a ZMQ::Socket, not a #{socket.class} as the #{name}"
21
21
  end
22
22
  end
23
23
 
24
- LibZMQ.zmq_device(device_type, frontend.socket, backend.socket)
24
+ LibZMQ.zmq_proxy(frontend.socket, backend.socket, capture ? capture.socket : nil)
25
25
  end
26
26
  end
27
+
28
+ # Alias for Device
29
+ #
30
+ class Proxy < Device; end
27
31
 
28
32
  end
@@ -13,6 +13,9 @@ module ZMQ
13
13
  end
14
14
  end # call ZeroMQError
15
15
 
16
+ class NotSupportedError < ZeroMQError
17
+ end
18
+
16
19
 
17
20
  class ContextError < ZeroMQError
18
21
  # True when the exception was raised due to the library
@@ -84,8 +84,8 @@ module ZMQ
84
84
  # puts "value1 is #{message.value1}"
85
85
  #
86
86
  class Message
87
-
88
- # Recommended way to create a standard message. A Message object is
87
+
88
+ # Recommended way to create a standard message. A Message object is
89
89
  # returned upon success, nil when allocation fails.
90
90
  #
91
91
  def self.create message = nil
@@ -129,7 +129,7 @@ module ZMQ
129
129
  data_buffer.write_string bytes, len
130
130
 
131
131
  # use libC to call free on the data buffer; earlier versions used an
132
- # FFI::Function here that called back into Ruby, but Rubinius won't
132
+ # FFI::Function here that called back into Ruby, but Rubinius won't
133
133
  # support that and there are issues with the other runtimes too
134
134
  LibZMQ.zmq_msg_init_data @pointer, data_buffer, len, LibC::Free, nil
135
135
  end
@@ -182,42 +182,36 @@ module ZMQ
182
182
  #
183
183
  def close
184
184
  rc = 0
185
-
185
+
186
186
  if @pointer
187
187
  rc = LibZMQ.zmq_msg_close @pointer
188
188
  @pointer = nil
189
189
  end
190
-
190
+
191
191
  rc
192
192
  end
193
-
193
+
194
194
  # cache the msg size so we don't have to recalculate it when creating
195
195
  # each new instance
196
- @msg_size = LibZMQ::Msg.size
197
-
196
+ @msg_size = LibZMQ::Message.size
197
+
198
198
  def self.msg_size() @msg_size; end
199
199
 
200
200
  end # class Message
201
-
202
- if LibZMQ.version3?
203
- class Message
204
- # Version3 only
205
- #
206
- def get(property)
207
- LibZMQ.zmq_msg_get(@pointer, property)
208
- end
209
-
210
- # Version3 only
211
- #
212
- # Returns true if this message has additional parts coming.
213
- #
214
- def more?
215
- Util.resultcode_ok?(get(MORE))
216
- end
217
-
218
- def set(property, value)
219
- LibZMQ.zmq_msg_set(@pointer, property, value)
220
- end
201
+
202
+ class Message
203
+ def get(property)
204
+ LibZMQ.zmq_msg_get(@pointer, property)
205
+ end
206
+
207
+ # Returns true if this message has additional parts coming.
208
+ #
209
+ def more?
210
+ Util.resultcode_ok?(get(MORE))
211
+ end
212
+
213
+ def set(property, value)
214
+ LibZMQ.zmq_msg_set(@pointer, property, value)
221
215
  end
222
216
  end
223
217
 
@@ -254,7 +248,7 @@ module ZMQ
254
248
  #
255
249
  def copy_in_bytes bytes, len
256
250
  rc = super(bytes, len)
257
-
251
+
258
252
  # make sure we have a way to deallocate this memory if the object goes
259
253
  # out of scope
260
254
  define_finalizer
@@ -296,7 +290,7 @@ module ZMQ
296
290
  # cache the msg size so we don't have to recalculate it when creating
297
291
  # each new instance
298
292
  # need to do this again because ivars are not inheritable
299
- @msg_size = LibZMQ::Msg.size
293
+ @msg_size = LibZMQ::Message.size
300
294
 
301
295
  end # class ManagedMessage
302
296
 
data/lib/ffi-rzmq/poll.rb CHANGED
@@ -150,22 +150,11 @@ module ZMQ
150
150
  # milliseconds, so we need to convert that value to
151
151
  # microseconds for the library.
152
152
  #
153
- if LibZMQ.version2?
154
- def adjust timeout
155
- if :blocking == timeout || -1 == timeout
156
- -1
157
- else
158
- (timeout * 1000).to_i
159
- end
160
- end
161
- else
162
- # version3 changed units from microseconds to milliseconds
163
- def adjust timeout
164
- if :blocking == timeout || -1 == timeout
165
- -1
166
- else
167
- timeout.to_i
168
- end
153
+ def adjust timeout
154
+ if :blocking == timeout || -1 == timeout
155
+ -1
156
+ else
157
+ timeout.to_i
169
158
  end
170
159
  end
171
160
 
@@ -1,8 +1,7 @@
1
1
 
2
2
  module ZMQ
3
3
 
4
- module CommonSocketBehavior
5
-
4
+ class Socket
6
5
  attr_reader :socket, :name
7
6
 
8
7
  # Allocates a socket of type +type+ for sending and receiving data.
@@ -70,15 +69,15 @@ module ZMQ
70
69
 
71
70
  context_ptr = context_ptr.pointer if context_ptr.kind_of?(ZMQ::Context)
72
71
 
73
- unless context_ptr.null?
72
+ if context_ptr.nil? || context_ptr.null?
73
+ raise ContextError.new 'zmq_socket', 0, ETERM, "Context pointer was null"
74
+ else
74
75
  @socket = LibZMQ.zmq_socket context_ptr, type
75
76
  if @socket && !@socket.null?
76
77
  @name = SocketTypeNameMap[type]
77
78
  else
78
79
  raise ContextError.new 'zmq_socket', 0, ETERM, "Socket pointer was null"
79
80
  end
80
- else
81
- raise ContextError.new 'zmq_socket', 0, ETERM, "Context pointer was null"
82
81
  end
83
82
 
84
83
  @longlong_cache = @int_cache = nil
@@ -118,7 +117,7 @@ module ZMQ
118
117
  # Returns 0 when the operation completed successfully.
119
118
  # Returns -1 when this operation failed.
120
119
  #
121
- # With a -1 return code, the user must check ZMQ.errno to determine the
120
+ # With a -1 return code, the user must check ZMQ::Util.errno to determine the
122
121
  # cause.
123
122
  #
124
123
  # rc = socket.setsockopt(ZMQ::LINGER, 1_000)
@@ -136,15 +135,14 @@ module ZMQ
136
135
  pointer.write_int value
137
136
 
138
137
  elsif 2 == @option_lookup[name]
138
+ # Strings are treated as pointers by FFI so we'll just pass it through
139
139
  length ||= value.size
140
+ pointer = value
140
141
 
141
- # note: not checking errno for failed memory allocations :(
142
- pointer = LibC.malloc length
143
- pointer.write_string value
144
142
  end
145
143
 
146
144
  rc = LibZMQ.zmq_setsockopt @socket, name, pointer, length
147
- LibC.free(pointer) unless pointer.nil? || pointer.null?
145
+ LibC.free(pointer) unless pointer.is_a?(String) || pointer.nil? || pointer.null?
148
146
  rc
149
147
  end
150
148
 
@@ -193,7 +191,7 @@ module ZMQ
193
191
  # depending upon the value of the socket option ZMQ::LINGER.
194
192
  #
195
193
  # Returns 0 upon success *or* when the socket has already been closed.
196
- # Returns -1 when the operation fails. Check ZMQ.errno for the error code.
194
+ # Returns -1 when the operation fails. Check ZMQ::Util.errno for the error code.
197
195
  #
198
196
  # rc = socket.close
199
197
  # puts("Given socket was invalid!") unless 0 == rc
@@ -215,15 +213,15 @@ module ZMQ
215
213
  #
216
214
  # +flags+ may take two values:
217
215
  # * 0 (default) - blocking operation
218
- # * ZMQ::NonBlocking - non-blocking operation
216
+ # * ZMQ::DONTWAIT - non-blocking operation
219
217
  # * ZMQ::SNDMORE - this message is part of a multi-part message
220
218
  #
221
219
  # Returns 0 when the message was successfully enqueued.
222
220
  # Returns -1 under two conditions.
223
221
  # 1. The message could not be enqueued
224
- # 2. When +flags+ is set with ZMQ::NonBlocking and the socket returned EAGAIN.
222
+ # 2. When +flags+ is set with ZMQ::DONTWAIT and the socket returned EAGAIN.
225
223
  #
226
- # With a -1 return code, the user must check ZMQ.errno to determine the
224
+ # With a -1 return code, the user must check ZMQ::Util.errno to determine the
227
225
  # cause.
228
226
  #
229
227
  def sendmsg message, flags = 0
@@ -233,14 +231,14 @@ module ZMQ
233
231
  # Helper method to make a new #Message instance out of the +string+ passed
234
232
  # in for transmission.
235
233
  #
236
- # +flags+ may be ZMQ::NonBlocking and ZMQ::SNDMORE.
234
+ # +flags+ may be ZMQ::DONTWAIT and ZMQ::SNDMORE.
237
235
  #
238
236
  # Returns 0 when the message was successfully enqueued.
239
237
  # Returns -1 under two conditions.
240
238
  # 1. The message could not be enqueued
241
- # 2. When +flags+ is set with ZMQ::NonBlocking and the socket returned EAGAIN.
239
+ # 2. When +flags+ is set with ZMQ::DONTWAIT and the socket returned EAGAIN.
242
240
  #
243
- # With a -1 return code, the user must check ZMQ.errno to determine the
241
+ # With a -1 return code, the user must check ZMQ::Util.errno to determine the
244
242
  # cause.
245
243
  #
246
244
  def send_string string, flags = 0
@@ -252,14 +250,14 @@ module ZMQ
252
250
  # passed in for transmission. Every element of +parts+ should be
253
251
  # a String.
254
252
  #
255
- # +flags+ may be ZMQ::NonBlocking.
253
+ # +flags+ may be ZMQ::DONTWAIT.
256
254
  #
257
255
  # Returns 0 when the messages were successfully enqueued.
258
256
  # Returns -1 under two conditions.
259
257
  # 1. A message could not be enqueued
260
- # 2. When +flags+ is set with ZMQ::NonBlocking and the socket returned EAGAIN.
258
+ # 2. When +flags+ is set with ZMQ::DONTWAIT and the socket returned EAGAIN.
261
259
  #
262
- # With a -1 return code, the user must check ZMQ.errno to determine the
260
+ # With a -1 return code, the user must check ZMQ::Util.errno to determine the
263
261
  # cause.
264
262
  #
265
263
  def send_strings parts, flags = 0
@@ -270,14 +268,14 @@ module ZMQ
270
268
  # passed in for transmission. Every element of +parts+ should be
271
269
  # a Message (or subclass).
272
270
  #
273
- # +flags+ may be ZMQ::NonBlocking.
271
+ # +flags+ may be ZMQ::DONTWAIT.
274
272
  #
275
273
  # Returns 0 when the messages were successfully enqueued.
276
274
  # Returns -1 under two conditions.
277
275
  # 1. A message could not be enqueued
278
- # 2. When +flags+ is set with ZMQ::NonBlocking and the socket returned EAGAIN.
276
+ # 2. When +flags+ is set with ZMQ::DONTWAIT and the socket returned EAGAIN.
279
277
  #
280
- # With a -1 return code, the user must check ZMQ.errno to determine the
278
+ # With a -1 return code, the user must check ZMQ::Util.errno to determine the
281
279
  # cause.
282
280
  #
283
281
  def sendmsgs parts, flags = 0
@@ -290,9 +288,9 @@ module ZMQ
290
288
  # Returns 0 when the message was successfully enqueued.
291
289
  # Returns -1 under two conditions.
292
290
  # 1. The message could not be enqueued
293
- # 2. When +flags+ is set with ZMQ::NonBlocking and the socket returned EAGAIN.
291
+ # 2. When +flags+ is set with ZMQ::DONTWAIT and the socket returned EAGAIN.
294
292
  #
295
- # With a -1 return code, the user must check ZMQ.errno to determine the
293
+ # With a -1 return code, the user must check ZMQ::Util.errno to determine the
296
294
  # cause.
297
295
  #
298
296
  def send_and_close message, flags = 0
@@ -305,14 +303,14 @@ module ZMQ
305
303
  #
306
304
  # +flags+ may take two values:
307
305
  # 0 (default) - blocking operation
308
- # ZMQ::NonBlocking - non-blocking operation
306
+ # ZMQ::DONTWAIT - non-blocking operation
309
307
  #
310
308
  # Returns 0 when the message was successfully dequeued.
311
309
  # Returns -1 under two conditions.
312
310
  # 1. The message could not be dequeued
313
- # 2. When +flags+ is set with ZMQ::NonBlocking and the socket returned EAGAIN.
311
+ # 2. When +flags+ is set with ZMQ::DONTWAIT and the socket returned EAGAIN.
314
312
  #
315
- # With a -1 return code, the user must check ZMQ.errno to determine the
313
+ # With a -1 return code, the user must check ZMQ::Util.errno to determine the
316
314
  # cause.
317
315
  #
318
316
  # The application code is responsible for handling the +message+ object lifecycle
@@ -326,14 +324,14 @@ module ZMQ
326
324
  # Helper method to make a new #Message instance and convert its payload
327
325
  # to a string.
328
326
  #
329
- # +flags+ may be ZMQ::NonBlocking.
327
+ # +flags+ may be ZMQ::DONTWAIT.
330
328
  #
331
329
  # Returns 0 when the message was successfully dequeued.
332
330
  # Returns -1 under two conditions.
333
331
  # 1. The message could not be dequeued
334
- # 2. When +flags+ is set with ZMQ::NonBlocking and the socket returned EAGAIN.
332
+ # 2. When +flags+ is set with ZMQ::DONTWAIT and the socket returned EAGAIN.
335
333
  #
336
- # With a -1 return code, the user must check ZMQ.errno to determine the
334
+ # With a -1 return code, the user must check ZMQ::Util.errno to determine the
337
335
  # cause.
338
336
  #
339
337
  # The application code is responsible for handling the +message+ object lifecycle
@@ -349,7 +347,7 @@ module ZMQ
349
347
 
350
348
  # Receive a multipart message as a list of strings.
351
349
  #
352
- # +flag+ may be ZMQ::NonBlocking. Any other flag will be
350
+ # +flag+ may be ZMQ::DONTWAIT. Any other flag will be
353
351
  # removed.
354
352
  #
355
353
  def recv_strings list, flag = 0
@@ -369,11 +367,11 @@ module ZMQ
369
367
  # Receive a multipart message as an array of objects
370
368
  # (by default these are instances of Message).
371
369
  #
372
- # +flag+ may be ZMQ::NonBlocking. Any other flag will be
370
+ # +flag+ may be ZMQ::DONTWAIT. Any other flag will be
373
371
  # removed.
374
372
  #
375
373
  def recvmsgs list, flag = 0
376
- flag = NonBlocking if dontwait?(flag)
374
+ flag = DONTWAIT if dontwait?(flag)
377
375
 
378
376
  message = @receiver_klass.new
379
377
  rc = recvmsg message, flag
@@ -426,24 +424,96 @@ module ZMQ
426
424
  rc
427
425
  end
428
426
 
427
+ # Get the options set on this socket.
428
+ #
429
+ # +name+ determines the socket option to request
430
+ # +array+ should be an empty array; a result of the proper type
431
+ # (numeric, string, boolean) will be inserted into
432
+ # the first position.
433
+ #
434
+ # Valid +option_name+ values:
435
+ # ZMQ::RCVMORE - true or false
436
+ # ZMQ::HWM - integer
437
+ # ZMQ::SWAP - integer
438
+ # ZMQ::AFFINITY - bitmap in an integer
439
+ # ZMQ::IDENTITY - string
440
+ # ZMQ::RATE - integer
441
+ # ZMQ::RECOVERY_IVL - integer
442
+ # ZMQ::SNDBUF - integer
443
+ # ZMQ::RCVBUF - integer
444
+ # ZMQ::FD - fd in an integer
445
+ # ZMQ::EVENTS - bitmap integer
446
+ # ZMQ::LINGER - integer measured in milliseconds
447
+ # ZMQ::RECONNECT_IVL - integer measured in milliseconds
448
+ # ZMQ::BACKLOG - integer
449
+ # ZMQ::RECOVER_IVL_MSEC - integer measured in milliseconds
450
+ # ZMQ::IPV4ONLY - integer
451
+ #
452
+ # Returns 0 when the operation completed successfully.
453
+ # Returns -1 when this operation failed.
454
+ #
455
+ # With a -1 return code, the user must check ZMQ::Util.errno to determine the
456
+ # cause.
457
+ #
458
+ # # retrieve high water mark
459
+ # array = []
460
+ # rc = socket.getsockopt(ZMQ::HWM, array)
461
+ # hwm = array.first if ZMQ::Util.resultcode_ok?(rc)
462
+ #
463
+ def getsockopt name, array
464
+ rc = __getsockopt__ name, array
465
+
466
+ if Util.resultcode_ok?(rc) && (RCVMORE == name)
467
+ # convert to boolean
468
+ array[0] = 1 == array[0]
469
+ end
470
+
471
+ rc
472
+ end
473
+
474
+ # Convenience method for getting the value of the socket IDENTITY.
475
+ #
476
+ def identity
477
+ array = []
478
+ getsockopt IDENTITY, array
479
+ array.at(0)
480
+ end
481
+
482
+ # Convenience method for setting the value of the socket IDENTITY.
483
+ #
484
+ def identity=(value)
485
+ setsockopt IDENTITY, value.to_s
486
+ end
487
+
488
+ # Disconnect the socket from the given +endpoint+.
489
+ #
490
+ def disconnect(endpoint)
491
+ LibZMQ.zmq_disconnect(socket, endpoint)
492
+ end
493
+
494
+ # Unbind the socket from the given +endpoint+.
495
+ #
496
+ def unbind(endpoint)
497
+ LibZMQ.zmq_unbind(socket, endpoint)
498
+ end
499
+
429
500
 
430
501
  private
431
-
502
+
432
503
  def send_multiple(parts, flags, method_name)
433
504
  if !parts || parts.empty?
434
505
  -1
435
506
  else
436
- flags = NonBlocking if dontwait?(flags)
507
+ flags = DONTWAIT if dontwait?(flags)
437
508
  rc = 0
438
-
509
+
439
510
  parts[0..-2].each do |part|
440
511
  rc = send(method_name, part, (flags | ZMQ::SNDMORE))
441
512
  break unless Util.resultcode_ok?(rc)
442
513
  end
443
-
514
+
444
515
  Util.resultcode_ok?(rc) ? send(method_name, parts[-1], flags) : rc
445
516
  end
446
-
447
517
  end
448
518
 
449
519
  def __getsockopt__ name, array
@@ -485,277 +555,57 @@ module ZMQ
485
555
  alloc_pointer(255, 255)
486
556
 
487
557
  else
488
- # uh oh, someone passed in an unknown option; use a slop buffer
558
+ # uh oh, someone passed in an unknown option; return nil
489
559
  @int_cache ||= alloc_pointer(:int32, 4)
490
560
  end
491
561
  end
492
562
 
493
- def populate_option_lookup
494
- # integer options
495
- [EVENTS, LINGER, RCVTIMEO, SNDTIMEO, RECONNECT_IVL, FD, TYPE, BACKLOG].each { |option| @option_lookup[option] = 0 }
496
-
497
- # long long options
498
- [RCVMORE, AFFINITY].each { |option| @option_lookup[option] = 1 }
499
-
500
- # string options
501
- [SUBSCRIBE, UNSUBSCRIBE].each { |option| @option_lookup[option] = 2 }
502
- end
503
-
504
563
  def release_cache
505
564
  @longlong_cache = nil
506
565
  @int_cache = nil
507
566
  end
508
567
 
509
568
  def dontwait?(flags)
510
- (NonBlocking & flags) == NonBlocking
569
+ (DONTWAIT & flags) == DONTWAIT
511
570
  end
512
571
  alias :noblock? :dontwait?
513
-
572
+
514
573
  def alloc_pointer(kind, length)
515
574
  pointer = FFI::MemoryPointer.new :size_t
516
575
  pointer.write_int(length)
517
576
  [FFI::MemoryPointer.new(kind), pointer]
518
577
  end
519
- end # module CommonSocketBehavior
520
578
 
521
-
522
- module IdentitySupport
523
-
524
- # Convenience method for getting the value of the socket IDENTITY.
525
- #
526
- def identity
527
- array = []
528
- getsockopt IDENTITY, array
529
- array.at(0)
579
+ def __sendmsg__(socket, address, flags)
580
+ LibZMQ.zmq_sendmsg(socket, address, flags)
530
581
  end
531
582
 
532
- # Convenience method for setting the value of the socket IDENTITY.
533
- #
534
- def identity=(value)
535
- setsockopt IDENTITY, value.to_s
583
+ def __recvmsg__(socket, address, flags)
584
+ LibZMQ.zmq_recvmsg(socket, address, flags)
536
585
  end
537
586
 
538
-
539
- private
540
-
541
587
  def populate_option_lookup
542
- super()
543
-
544
- # string options
545
- [IDENTITY].each { |option| @option_lookup[option] = 2 }
546
- end
547
-
548
- end # module IdentitySupport
549
-
550
-
551
- if LibZMQ.version2?
552
-
553
- class Socket
554
- # Inclusion order is *important* since later modules may have a call
555
- # to #super. We want those calls to go up the chain in a particular
556
- # order
557
- include CommonSocketBehavior
558
- include IdentitySupport
559
-
560
- # Get the options set on this socket.
561
- #
562
- # +name+ determines the socket option to request
563
- # +array+ should be an empty array; a result of the proper type
564
- # (numeric, string, boolean) will be inserted into
565
- # the first position.
566
- #
567
- # Valid +option_name+ values:
568
- # ZMQ::RCVMORE - true or false
569
- # ZMQ::HWM - integer
570
- # ZMQ::SWAP - integer
571
- # ZMQ::AFFINITY - bitmap in an integer
572
- # ZMQ::IDENTITY - string
573
- # ZMQ::RATE - integer
574
- # ZMQ::RECOVERY_IVL - integer
575
- # ZMQ::MCAST_LOOP - true or false
576
- # ZMQ::SNDBUF - integer
577
- # ZMQ::RCVBUF - integer
578
- # ZMQ::FD - fd in an integer
579
- # ZMQ::EVENTS - bitmap integer
580
- # ZMQ::LINGER - integer measured in milliseconds
581
- # ZMQ::RECONNECT_IVL - integer measured in milliseconds
582
- # ZMQ::BACKLOG - integer
583
- # ZMQ::RECOVER_IVL_MSEC - integer measured in milliseconds
584
- #
585
- # Returns 0 when the operation completed successfully.
586
- # Returns -1 when this operation failed.
587
- #
588
- # With a -1 return code, the user must check ZMQ.errno to determine the
589
- # cause.
590
- #
591
- # # retrieve high water mark
592
- # array = []
593
- # rc = socket.getsockopt(ZMQ::HWM, array)
594
- # hwm = array.first if ZMQ::Util.resultcode_ok?(rc)
595
- #
596
- def getsockopt name, array
597
- rc = __getsockopt__ name, array
598
-
599
- if Util.resultcode_ok?(rc) && (RCVMORE == name || MCAST_LOOP == name)
600
- # convert to boolean
601
- array[0] = 1 == array[0]
602
- end
603
-
604
- rc
605
- end
606
-
588
+ IntegerSocketOptions.each { |option| @option_lookup[option] = 0 }
607
589
 
608
- private
609
-
610
- def __sendmsg__(socket, address, flags)
611
- LibZMQ.zmq_send(socket, address, flags)
612
- end
613
-
614
- def __recvmsg__(socket, address, flags)
615
- LibZMQ.zmq_recv(socket, address, flags)
616
- end
617
-
618
- def populate_option_lookup
619
- super()
620
-
621
- # integer options
622
- [RECONNECT_IVL_MAX].each { |option| @option_lookup[option] = 0 }
623
-
624
- # long long options
625
- [HWM, SWAP, RATE, RECOVERY_IVL, RECOVERY_IVL_MSEC, MCAST_LOOP, SNDBUF, RCVBUF].each { |option| @option_lookup[option] = 1 }
626
- end
627
-
628
- # these finalizer-related methods cannot live in the CommonSocketBehavior
629
- # module; they *must* be in the class definition directly
630
-
631
- def define_finalizer
632
- ObjectSpace.define_finalizer(self, self.class.close(@socket, Process.pid))
633
- end
634
-
635
- def remove_finalizer
636
- ObjectSpace.undefine_finalizer self
637
- end
590
+ LongLongSocketOptions.each { |option| @option_lookup[option] = 1 }
638
591
 
639
- def self.close socket, pid
640
- Proc.new do
641
- LibZMQ.zmq_close(socket) if socket && !socket.nil? && Process.pid == pid
642
- end
643
- end
644
- end # class Socket for version2
645
-
646
- end # LibZMQ.version2?
647
-
648
-
649
- if LibZMQ.version3?
650
- class Socket
651
- include CommonSocketBehavior
652
- include IdentitySupport
653
-
654
- # Get the options set on this socket.
655
- #
656
- # +name+ determines the socket option to request
657
- # +array+ should be an empty array; a result of the proper type
658
- # (numeric, string, boolean) will be inserted into
659
- # the first position.
660
- #
661
- # Valid +option_name+ values:
662
- # ZMQ::RCVMORE - true or false
663
- # ZMQ::HWM - integer
664
- # ZMQ::SWAP - integer
665
- # ZMQ::AFFINITY - bitmap in an integer
666
- # ZMQ::IDENTITY - string
667
- # ZMQ::RATE - integer
668
- # ZMQ::RECOVERY_IVL - integer
669
- # ZMQ::SNDBUF - integer
670
- # ZMQ::RCVBUF - integer
671
- # ZMQ::FD - fd in an integer
672
- # ZMQ::EVENTS - bitmap integer
673
- # ZMQ::LINGER - integer measured in milliseconds
674
- # ZMQ::RECONNECT_IVL - integer measured in milliseconds
675
- # ZMQ::BACKLOG - integer
676
- # ZMQ::RECOVER_IVL_MSEC - integer measured in milliseconds
677
- # ZMQ::IPV4ONLY - integer
678
- #
679
- # Returns 0 when the operation completed successfully.
680
- # Returns -1 when this operation failed.
681
- #
682
- # With a -1 return code, the user must check ZMQ.errno to determine the
683
- # cause.
684
- #
685
- # # retrieve high water mark
686
- # array = []
687
- # rc = socket.getsockopt(ZMQ::HWM, array)
688
- # hwm = array.first if ZMQ::Util.resultcode_ok?(rc)
689
- #
690
- def getsockopt name, array
691
- rc = __getsockopt__ name, array
692
-
693
- if Util.resultcode_ok?(rc) && (RCVMORE == name)
694
- # convert to boolean
695
- array[0] = 1 == array[0]
696
- end
697
-
698
- rc
699
- end
700
-
701
- # Version3 only
702
- #
703
- # Disconnect the socket from the given +endpoint+.
704
- #
705
- def disconnect(endpoint)
706
- LibZMQ.zmq_disconnect(socket, endpoint)
707
- end
708
-
709
- # Version3 only
710
- #
711
- # Unbind the socket from the given +endpoint+.
712
- #
713
- def unbind(endpoint)
714
- LibZMQ.zmq_unbind(socket, endpoint)
715
- end
716
-
717
-
718
- private
719
-
720
- def __sendmsg__(socket, address, flags)
721
- LibZMQ.zmq_sendmsg(socket, address, flags)
722
- end
723
-
724
- def __recvmsg__(socket, address, flags)
725
- LibZMQ.zmq_recvmsg(socket, address, flags)
726
- end
727
-
728
- def populate_option_lookup
729
- super()
730
-
731
- # integer options
732
- [RECONNECT_IVL_MAX, RCVHWM, SNDHWM, RATE, RECOVERY_IVL, SNDBUF, RCVBUF, IPV4ONLY,
733
- ROUTER_BEHAVIOR, TCP_KEEPALIVE, TCP_KEEPALIVE_CNT,
734
- TCP_KEEPALIVE_IDLE, TCP_KEEPALIVE_INTVL, TCP_ACCEPT_FILTER, MULTICAST_HOPS
735
- ].each { |option| @option_lookup[option] = 0 }
736
-
737
- # long long options
738
- [MAXMSGSIZE].each { |option| @option_lookup[option] = 1 }
739
-
740
- # string options
741
- [LAST_ENDPOINT].each { |option| @option_lookup[option] = 2 }
742
- end
592
+ StringSocketOptions.each { |option| @option_lookup[option] = 2 }
593
+ end
743
594
 
744
- # these finalizer-related methods cannot live in the CommonSocketBehavior
745
- # module; they *must* be in the class definition directly
595
+ # these finalizer-related methods cannot live in the CommonSocketBehavior
596
+ # module; they *must* be in the class definition directly
746
597
 
747
- def define_finalizer
748
- ObjectSpace.define_finalizer(self, self.class.close(@socket, Process.pid))
749
- end
598
+ def define_finalizer
599
+ ObjectSpace.define_finalizer(self, self.class.close(@socket, Process.pid))
600
+ end
750
601
 
751
- def remove_finalizer
752
- ObjectSpace.undefine_finalizer self
753
- end
602
+ def remove_finalizer
603
+ ObjectSpace.undefine_finalizer self
604
+ end
754
605
 
755
- def self.close socket, pid
756
- Proc.new { LibZMQ.zmq_close socket if Process.pid == pid }
757
- end
758
- end # Socket for version3
759
- end # LibZMQ.version3?
606
+ def self.close socket, pid
607
+ Proc.new { LibZMQ.zmq_close socket if Process.pid == pid }
608
+ end
609
+ end # Socket
760
610
 
761
611
  end # module ZMQ