ffi-rzmq 0.8.2 → 0.9.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/AUTHORS.txt +1 -0
- data/History.txt +35 -0
- data/README.rdoc +48 -15
- data/Rakefile +7 -2
- data/examples/README.rdoc +21 -76
- data/examples/{local_lat.rb → v2api/local_lat.rb} +27 -12
- data/examples/v2api/local_lat_poll.rb +66 -0
- data/examples/{local_throughput.rb → v2api/local_throughput.rb} +24 -9
- data/examples/v2api/publish_subscribe.rb +82 -0
- data/examples/{remote_lat.rb → v2api/remote_lat.rb} +26 -8
- data/examples/v2api/remote_throughput.rb +39 -0
- data/examples/v2api/reqrep_poll.rb +62 -0
- data/examples/v2api/request_response.rb +40 -0
- data/examples/v2api/throughput_measurement.rb +138 -0
- data/examples/v3api/local_lat.rb +59 -0
- data/examples/v3api/local_lat_poll.rb +66 -0
- data/examples/v3api/local_throughput.rb +65 -0
- data/examples/v3api/publish_subscribe.rb +82 -0
- data/examples/v3api/remote_lat.rb +71 -0
- data/examples/v3api/remote_throughput.rb +47 -0
- data/examples/v3api/reqrep_poll.rb +62 -0
- data/examples/v3api/request_response.rb +40 -0
- data/examples/v3api/throughput_measurement.rb +166 -0
- data/ext/README +5 -0
- data/ffi-rzmq.gemspec +4 -4
- data/lib/ffi-rzmq.rb +4 -1
- data/lib/ffi-rzmq/constants.rb +178 -0
- data/lib/ffi-rzmq/context.rb +61 -45
- data/lib/ffi-rzmq/device.rb +22 -9
- data/lib/ffi-rzmq/exceptions.rb +0 -98
- data/lib/ffi-rzmq/libc.rb +19 -0
- data/lib/ffi-rzmq/libzmq.rb +188 -0
- data/lib/ffi-rzmq/message.rb +33 -40
- data/lib/ffi-rzmq/poll.rb +49 -52
- data/lib/ffi-rzmq/socket.rb +902 -392
- data/lib/ffi-rzmq/util.rb +101 -0
- data/spec/context_spec.rb +47 -21
- data/spec/device_spec.rb +78 -58
- data/spec/message_spec.rb +90 -12
- data/spec/multipart_spec.rb +162 -0
- data/spec/nonblocking_recv_spec.rb +325 -0
- data/spec/pushpull_spec.rb +95 -34
- data/spec/reqrep_spec.rb +55 -20
- data/spec/socket_spec.rb +353 -204
- data/spec/spec_helper.rb +46 -3
- data/version.txt +1 -1
- metadata +91 -66
- data/examples/local_lat_poll.rb +0 -54
- data/examples/local_lat_zerocopy.rb +0 -24
- data/examples/publish_subscribe.rb +0 -52
- data/examples/remote_lat_zerocopy.rb +0 -35
- data/examples/remote_throughput.rb +0 -27
- data/examples/reqrep_poll.rb +0 -49
- data/examples/request_response.rb +0 -23
- data/lib/ffi-rzmq/wrapper.rb +0 -121
- data/lib/ffi-rzmq/zmq.rb +0 -198
data/lib/ffi-rzmq/device.rb
CHANGED
@@ -1,15 +1,28 @@
|
|
1
1
|
module ZMQ
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
2
|
+
if LibZMQ.version2?
|
3
|
+
class Device
|
4
|
+
attr_reader :device
|
5
|
+
|
6
|
+
def self.create(device_type, frontend, backend)
|
7
|
+
dev = nil
|
8
|
+
begin
|
9
|
+
dev = new device_type, frontend, backend
|
10
|
+
rescue ArgumentError
|
11
|
+
dev = nil
|
9
12
|
end
|
13
|
+
|
14
|
+
dev
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(device_type,frontend,backend)
|
18
|
+
[["frontend", frontend],["backend", backend]].each do |name,socket|
|
19
|
+
unless socket.is_a?(ZMQ::Socket)
|
20
|
+
raise ArgumentError, "Expected a ZMQ::Socket, not a #{socket.class} as the #{name}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
LibZMQ.zmq_device(device_type, frontend.socket, backend.socket)
|
10
25
|
end
|
11
|
-
|
12
|
-
LibZMQ.zmq_device(device_type, frontend.socket, backend.socket)
|
13
26
|
end
|
14
27
|
end
|
15
28
|
end
|
data/lib/ffi-rzmq/exceptions.rb
CHANGED
@@ -34,104 +34,6 @@ module ZMQ
|
|
34
34
|
end # class ContextError
|
35
35
|
|
36
36
|
|
37
|
-
class PollError < ZeroMQError
|
38
|
-
# True when the exception was raised due to the library
|
39
|
-
# returning EMTHREAD.
|
40
|
-
#
|
41
|
-
# At least one of the members of the items array refers
|
42
|
-
# to a socket belonging to a different application
|
43
|
-
# thread.
|
44
|
-
#
|
45
|
-
def efault?() EFAULT == @error_code; end
|
46
|
-
|
47
|
-
end # class PollError
|
48
|
-
|
49
|
-
|
50
|
-
class SocketError < ZeroMQError
|
51
|
-
# True when the exception was raised due to the library
|
52
|
-
# returning EMTHREAD.
|
53
|
-
#
|
54
|
-
# Occurs for #send and #recv operations.
|
55
|
-
# * When calling #send, non-blocking mode was requested
|
56
|
-
# and the message cannot be queued at the moment.
|
57
|
-
# * When calling #recv, non-blocking mode was requested
|
58
|
-
# and no messages are available at the moment.
|
59
|
-
#
|
60
|
-
def egain?() EAGAIN == @error_code; end
|
61
|
-
|
62
|
-
# True when the exception was raised due to the library
|
63
|
-
# returning ENOCOMPATPROTO.
|
64
|
-
#
|
65
|
-
# The requested transport protocol is not compatible
|
66
|
-
# with the socket type.
|
67
|
-
#
|
68
|
-
def enocompatproto?() ENOCOMPATPROTO == @error_code; end
|
69
|
-
|
70
|
-
# True when the exception was raised due to the library
|
71
|
-
# returning EPROTONOSUPPORT.
|
72
|
-
#
|
73
|
-
# The requested transport protocol is not supported.
|
74
|
-
#
|
75
|
-
def eprotonosupport?() EPROTONOSUPPORT == @error_code; end
|
76
|
-
|
77
|
-
# True when the exception was raised due to the library
|
78
|
-
# returning EADDRINUSE.
|
79
|
-
#
|
80
|
-
# The given address is already in use.
|
81
|
-
#
|
82
|
-
def eaddrinuse?() EADDRINUSE == @error_code; end
|
83
|
-
|
84
|
-
# True when the exception was raised due to the library
|
85
|
-
# returning EADDRNOTAVAIL.
|
86
|
-
#
|
87
|
-
# A nonexistent interface was requested or the
|
88
|
-
# requested address was not local.
|
89
|
-
#
|
90
|
-
def eaddrnotavail?() EADDRNOTAVAIL == @error_code; end
|
91
|
-
|
92
|
-
# True when the exception was raised due to the library
|
93
|
-
# returning EMTHREAD.
|
94
|
-
#
|
95
|
-
# Occurs under 2 conditions.
|
96
|
-
# * When creating a new #Socket, the requested socket
|
97
|
-
# type is invalid.
|
98
|
-
#
|
99
|
-
# * When setting socket options with #setsockopt, the
|
100
|
-
# requested option +option_name+ is unknown, or the
|
101
|
-
# requested +option_len+ or +option_value+ is invalid.
|
102
|
-
#
|
103
|
-
def einval?() EINVAL == @error_code; end
|
104
|
-
|
105
|
-
# True when the exception was raised due to the library
|
106
|
-
# returning EMTHREAD.
|
107
|
-
#
|
108
|
-
# The send or recv operation cannot be performed on this
|
109
|
-
# socket at the moment due to the socket not being in
|
110
|
-
# the appropriate state. This error may occur with socket
|
111
|
-
# types that switch between several states, such as ZMQ::REP.
|
112
|
-
#
|
113
|
-
def efsm?() EFSM == @error_code; end
|
114
|
-
|
115
|
-
# True when the exception was raised due to the library
|
116
|
-
# returning ENOTSUP.
|
117
|
-
#
|
118
|
-
# The send or recv operation is not supported by this socket
|
119
|
-
# type.
|
120
|
-
#
|
121
|
-
def enotsup?() super; end
|
122
|
-
|
123
|
-
# True when the exception was raised due to the library
|
124
|
-
# returning EMTHREAD.
|
125
|
-
#
|
126
|
-
# The number of application threads using sockets within
|
127
|
-
# this context has been exceeded. See the +app_threads+
|
128
|
-
# parameter of #Context.
|
129
|
-
#
|
130
|
-
def emthread?() EMTHREAD == @error_code; end
|
131
|
-
|
132
|
-
end # class SocketError
|
133
|
-
|
134
|
-
|
135
37
|
class MessageError < ZeroMQError
|
136
38
|
# True when the exception was raised due to the library
|
137
39
|
# returning ENOMEM.
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
module LibC
|
3
|
+
extend FFI::Library
|
4
|
+
# figures out the correct libc for each platform including Windows
|
5
|
+
library = ffi_lib(FFI::Library::LIBC).first
|
6
|
+
|
7
|
+
# Size_t not working properly on Windows
|
8
|
+
find_type(:size_t) rescue typedef(:ulong, :size_t)
|
9
|
+
|
10
|
+
# memory allocators
|
11
|
+
attach_function :malloc, [:size_t], :pointer
|
12
|
+
attach_function :free, [:pointer], :void
|
13
|
+
|
14
|
+
# get a pointer to the free function; used for ZMQ::Message deallocation
|
15
|
+
Free = library.find_symbol('free')
|
16
|
+
|
17
|
+
# memory movers
|
18
|
+
attach_function :memcpy, [:pointer, :pointer, :size_t], :pointer
|
19
|
+
end # module LibC
|
@@ -0,0 +1,188 @@
|
|
1
|
+
|
2
|
+
# Wraps the libzmq library and attaches to the functions that are
|
3
|
+
# common across the 2.x, 3.x and 4.x APIs.
|
4
|
+
#
|
5
|
+
module LibZMQ
|
6
|
+
extend FFI::Library
|
7
|
+
|
8
|
+
# bias the library discovery to a path inside the gem first, then
|
9
|
+
# to the usual system paths
|
10
|
+
inside_gem = File.join(File.dirname(__FILE__), '..', '..', 'ext')
|
11
|
+
ZMQ_LIB_PATHS = [
|
12
|
+
inside_gem, '/usr/local/lib', '/opt/local/lib', '/usr/local/homebrew/lib', '/usr/lib64'
|
13
|
+
].map{|path| "#{path}/libzmq.#{FFI::Platform::LIBSUFFIX}"}
|
14
|
+
ffi_lib(ZMQ_LIB_PATHS + %w{libzmq})
|
15
|
+
|
16
|
+
# Size_t not working properly on Windows
|
17
|
+
find_type(:size_t) rescue typedef(:ulong, :size_t)
|
18
|
+
|
19
|
+
# Context and misc api
|
20
|
+
#
|
21
|
+
# @blocking = true is a hint to FFI that the following (and only the following)
|
22
|
+
# function may block, therefore it should release the GIL before calling it.
|
23
|
+
# This can aid in situations where the function call will/may block and another
|
24
|
+
# thread within the lib may try to call back into the ruby runtime. Failure to
|
25
|
+
# release the GIL will result in a hang; the hint *may* allow things to run
|
26
|
+
# smoothly for Ruby runtimes hampered by a GIL.
|
27
|
+
#
|
28
|
+
# This is really only honored by the MRI implementation but it *is* necessary
|
29
|
+
# otherwise the runtime hangs (and requires a kill -9 to terminate)
|
30
|
+
#
|
31
|
+
@blocking = true
|
32
|
+
attach_function :zmq_init, [:int], :pointer
|
33
|
+
@blocking = true
|
34
|
+
attach_function :zmq_socket, [:pointer, :int], :pointer
|
35
|
+
@blocking = true
|
36
|
+
attach_function :zmq_term, [:pointer], :int
|
37
|
+
@blocking = true
|
38
|
+
attach_function :zmq_errno, [], :int
|
39
|
+
@blocking = true
|
40
|
+
attach_function :zmq_strerror, [:int], :pointer
|
41
|
+
@blocking = true
|
42
|
+
attach_function :zmq_version, [:pointer, :pointer, :pointer], :void
|
43
|
+
|
44
|
+
def self.version
|
45
|
+
unless @version
|
46
|
+
major = FFI::MemoryPointer.new :int
|
47
|
+
minor = FFI::MemoryPointer.new :int
|
48
|
+
patch = FFI::MemoryPointer.new :int
|
49
|
+
LibZMQ.zmq_version major, minor, patch
|
50
|
+
@version = {:major => major.read_int, :minor => minor.read_int, :patch => patch.read_int}
|
51
|
+
end
|
52
|
+
|
53
|
+
@version
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.version2?() version[:major] == 2 && version[:minor] >= 1 end
|
57
|
+
|
58
|
+
def self.version3?() version[:major] == 3 end
|
59
|
+
|
60
|
+
def self.version4?() version[:major] == 4 end
|
61
|
+
|
62
|
+
|
63
|
+
# Message api
|
64
|
+
@blocking = true
|
65
|
+
attach_function :zmq_msg_init, [:pointer], :int
|
66
|
+
@blocking = true
|
67
|
+
attach_function :zmq_msg_init_size, [:pointer, :size_t], :int
|
68
|
+
@blocking = true
|
69
|
+
attach_function :zmq_msg_init_data, [:pointer, :pointer, :size_t, :pointer, :pointer], :int
|
70
|
+
@blocking = true
|
71
|
+
attach_function :zmq_msg_close, [:pointer], :int
|
72
|
+
@blocking = true
|
73
|
+
attach_function :zmq_msg_data, [:pointer], :pointer
|
74
|
+
@blocking = true
|
75
|
+
attach_function :zmq_msg_size, [:pointer], :size_t
|
76
|
+
@blocking = true
|
77
|
+
attach_function :zmq_msg_copy, [:pointer, :pointer], :int
|
78
|
+
@blocking = true
|
79
|
+
attach_function :zmq_msg_move, [:pointer, :pointer], :int
|
80
|
+
|
81
|
+
# Used for casting pointers back to the struct
|
82
|
+
#
|
83
|
+
class Msg < FFI::Struct
|
84
|
+
layout :content, :pointer,
|
85
|
+
:flags, :uint8,
|
86
|
+
:vsm_size, :uint8,
|
87
|
+
:vsm_data, [:uint8, 30]
|
88
|
+
end # class Msg
|
89
|
+
|
90
|
+
# Socket api
|
91
|
+
@blocking = true
|
92
|
+
attach_function :zmq_setsockopt, [:pointer, :int, :pointer, :int], :int
|
93
|
+
@blocking = true
|
94
|
+
attach_function :zmq_bind, [:pointer, :string], :int
|
95
|
+
@blocking = true
|
96
|
+
attach_function :zmq_connect, [:pointer, :string], :int
|
97
|
+
@blocking = true
|
98
|
+
attach_function :zmq_close, [:pointer], :int
|
99
|
+
|
100
|
+
# Poll api
|
101
|
+
@blocking = true
|
102
|
+
attach_function :zmq_poll, [:pointer, :int, :long], :int
|
103
|
+
|
104
|
+
module PollItemLayout
|
105
|
+
def self.included(base)
|
106
|
+
base.class_eval do
|
107
|
+
layout :socket, :pointer,
|
108
|
+
:fd, :int,
|
109
|
+
:events, :short,
|
110
|
+
:revents, :short
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end # module PollItemLayout
|
114
|
+
|
115
|
+
class PollItem < FFI::Struct
|
116
|
+
include PollItemLayout
|
117
|
+
|
118
|
+
def socket() self[:socket]; end
|
119
|
+
|
120
|
+
def readable?
|
121
|
+
(self[:revents] & ZMQ::POLLIN) > 0
|
122
|
+
end
|
123
|
+
|
124
|
+
def writable?
|
125
|
+
(self[:revents] & ZMQ::POLLOUT) > 0
|
126
|
+
end
|
127
|
+
|
128
|
+
def both_accessible?
|
129
|
+
readable? && writable?
|
130
|
+
end
|
131
|
+
|
132
|
+
def inspect
|
133
|
+
"socket [#{socket}], fd [#{self[:fd]}], events [#{self[:events]}], revents [#{self[:revents]}]"
|
134
|
+
end
|
135
|
+
|
136
|
+
def to_s; inspect; end
|
137
|
+
end # class PollItem
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
# Attaches to those functions specific to the 2.x API
|
143
|
+
#
|
144
|
+
if LibZMQ.version2?
|
145
|
+
|
146
|
+
module LibZMQ
|
147
|
+
# Socket api
|
148
|
+
@blocking = true
|
149
|
+
attach_function :zmq_getsockopt, [:pointer, :int, :pointer, :pointer], :int
|
150
|
+
@blocking = true
|
151
|
+
attach_function :zmq_recv, [:pointer, :pointer, :int], :int
|
152
|
+
@blocking = true
|
153
|
+
attach_function :zmq_send, [:pointer, :pointer, :int], :int
|
154
|
+
@blocking = true
|
155
|
+
attach_function :zmq_device, [:int, :pointer, :pointer], :int
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
# Attaches to those functions specific to the 3.x API
|
161
|
+
#
|
162
|
+
if LibZMQ.version3? || LibZMQ.version4?
|
163
|
+
|
164
|
+
module LibZMQ
|
165
|
+
# Socket api
|
166
|
+
@blocking = true
|
167
|
+
attach_function :zmq_getsockopt, [:pointer, :int, :pointer, :pointer], :int
|
168
|
+
@blocking = true
|
169
|
+
attach_function :zmq_recvmsg, [:pointer, :pointer, :int], :int
|
170
|
+
@blocking = true
|
171
|
+
attach_function :zmq_recv, [:pointer, :pointer, :size_t, :int], :int
|
172
|
+
@blocking = true
|
173
|
+
attach_function :zmq_sendmsg, [:pointer, :pointer, :int], :int
|
174
|
+
@blocking = true
|
175
|
+
attach_function :zmq_send, [:pointer, :pointer, :size_t, :int], :int
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
# Sanity check; print an error and exit if we are trying to load an unsupported
|
181
|
+
# version of libzmq.
|
182
|
+
#
|
183
|
+
unless LibZMQ.version2? || LibZMQ.version3? || LibZMQ.version4?
|
184
|
+
hash = LibZMQ.version
|
185
|
+
version = "#{hash[:major]}.#{hash[:minor]}.#{hash[:patch]}"
|
186
|
+
STDERR.puts "Unable to load this gem. The libzmq version #{version} is incompatible with ffi-rzmq."
|
187
|
+
exit 255
|
188
|
+
end
|
data/lib/ffi-rzmq/message.rb
CHANGED
@@ -1,21 +1,12 @@
|
|
1
1
|
|
2
2
|
module ZMQ
|
3
3
|
|
4
|
-
|
5
|
-
ZMQ_MSG_INIT_DATA_STR = 'zmq_msg_init_data'.freeze
|
6
|
-
ZMQ_MSG_INIT_STR = 'zmq_msg_init'.freeze
|
7
|
-
ZMQ_MSG_CLOSE_STR = 'zmq_msg_close'.freeze
|
8
|
-
ZMQ_MSG_COPY_STR = 'zmq_msg_copy'.freeze
|
9
|
-
ZMQ_MSG_MOVE_STR = 'zmq_msg_move'.freeze
|
10
|
-
ZMQ_MSG_SIZE_STR = 'zmq_msg_size'.freeze
|
11
|
-
|
12
|
-
# The constructor optionally takes a string as an argument. It will
|
4
|
+
# The factory constructor optionally takes a string as an argument. It will
|
13
5
|
# copy this string to native memory in preparation for transmission.
|
14
6
|
# So, don't pass a string unless you intend to send it. Internally it
|
15
7
|
# calls #copy_in_string.
|
16
8
|
#
|
17
|
-
# Call #close to release buffers when you
|
18
|
-
# to Socket#send. That method calls #close on your behalf.
|
9
|
+
# Call #close to release buffers when you are done with the data.
|
19
10
|
#
|
20
11
|
# (This class is not really zero-copy. Ruby makes this near impossible
|
21
12
|
# since Ruby objects can be relocated in memory by the GC at any
|
@@ -37,8 +28,17 @@ module ZMQ
|
|
37
28
|
# When you are done using a *received* message object, call #close to
|
38
29
|
# release the associated buffers.
|
39
30
|
#
|
40
|
-
#
|
41
|
-
#
|
31
|
+
# received_message = Message.create
|
32
|
+
# if received_message
|
33
|
+
# rc = socket.recv(received_message)
|
34
|
+
# if ZMQ::Util.resultcode_ok?(rc)
|
35
|
+
# puts "Message contained: #{received_message.copy_out_string}"
|
36
|
+
# else
|
37
|
+
# STDERR.puts "Error when receiving message: #{ZMQ::Util.error_string}"
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
#
|
41
|
+
# Define a custom layout for the data sent between 0mq peers.
|
42
42
|
#
|
43
43
|
# class MyMessage
|
44
44
|
# class Layout < FFI::Struct
|
@@ -85,6 +85,13 @@ module ZMQ
|
|
85
85
|
#
|
86
86
|
class Message
|
87
87
|
include ZMQ::Util
|
88
|
+
|
89
|
+
# Recommended way to create a standard message. A Message object is
|
90
|
+
# returned upon success, nil when allocation fails.
|
91
|
+
#
|
92
|
+
def self.create message = nil
|
93
|
+
new(message) rescue nil
|
94
|
+
end
|
88
95
|
|
89
96
|
def initialize message = nil
|
90
97
|
@state = :uninitialized
|
@@ -99,7 +106,7 @@ module ZMQ
|
|
99
106
|
else
|
100
107
|
# initialize an empty message structure to receive a message
|
101
108
|
result_code = LibZMQ.zmq_msg_init @pointer
|
102
|
-
|
109
|
+
raise unless Util.resultcode_ok?(result_code)
|
103
110
|
end
|
104
111
|
end
|
105
112
|
|
@@ -109,9 +116,6 @@ module ZMQ
|
|
109
116
|
#
|
110
117
|
# Can only be initialized via #copy_in_string or #copy_in_bytes once.
|
111
118
|
#
|
112
|
-
# Can raise a MessageError when #copy_in_string or #copy_in_bytes is
|
113
|
-
# called multiple times on the same instance.
|
114
|
-
#
|
115
119
|
def copy_in_string string
|
116
120
|
string_size = string.respond_to?(:bytesize) ? string.bytesize : string.size
|
117
121
|
copy_in_bytes string, string_size if string
|
@@ -122,12 +126,7 @@ module ZMQ
|
|
122
126
|
#
|
123
127
|
# Can only be initialized via #copy_in_string or #copy_in_bytes once.
|
124
128
|
#
|
125
|
-
# Can raise a MessageError when #copy_in_string or #copy_in_bytes is
|
126
|
-
# called multiple times on the same instance.
|
127
|
-
#
|
128
129
|
def copy_in_bytes bytes, len
|
129
|
-
raise MessageError.new "#{self}", -1, -1, "This object cannot be reused; allocate a new one!" if initialized?
|
130
|
-
|
131
130
|
data_buffer = LibC.malloc len
|
132
131
|
# writes the exact number of bytes, no null byte to terminate string
|
133
132
|
data_buffer.write_string bytes, len
|
@@ -135,10 +134,7 @@ module ZMQ
|
|
135
134
|
# use libC to call free on the data buffer; earlier versions used an
|
136
135
|
# FFI::Function here that called back into Ruby, but Rubinius won't
|
137
136
|
# support that and there are issues with the other runtimes too
|
138
|
-
|
139
|
-
|
140
|
-
error_check ZMQ_MSG_INIT_DATA_STR, result_code
|
141
|
-
@state = :initialized
|
137
|
+
LibZMQ.zmq_msg_init_data @pointer, data_buffer, len, LibC::Free, nil
|
142
138
|
end
|
143
139
|
|
144
140
|
# Provides the memory address of the +zmq_msg_t+ struct. Used mostly for
|
@@ -151,15 +147,11 @@ module ZMQ
|
|
151
147
|
alias :pointer :address
|
152
148
|
|
153
149
|
def copy source
|
154
|
-
|
155
|
-
error_check ZMQ_MSG_COPY_STR, result_code
|
156
|
-
@state = :initialized
|
150
|
+
LibZMQ.zmq_msg_copy @pointer, source.address
|
157
151
|
end
|
158
152
|
|
159
153
|
def move source
|
160
|
-
|
161
|
-
error_check ZMQ_MSG_MOVE_STR, result_code
|
162
|
-
@state = :initialized
|
154
|
+
LibZMQ.zmq_msg_move @pointer, source.address
|
163
155
|
end
|
164
156
|
|
165
157
|
# Provides the size of the data buffer for this +zmq_msg_t+ C struct.
|
@@ -192,17 +184,16 @@ module ZMQ
|
|
192
184
|
# no ops.
|
193
185
|
#
|
194
186
|
def close
|
187
|
+
rc = 0
|
188
|
+
|
195
189
|
if @pointer
|
196
|
-
LibZMQ.zmq_msg_close @pointer
|
190
|
+
rc = LibZMQ.zmq_msg_close @pointer
|
197
191
|
@pointer = nil
|
198
192
|
end
|
193
|
+
|
194
|
+
rc
|
199
195
|
end
|
200
196
|
|
201
|
-
|
202
|
-
private
|
203
|
-
|
204
|
-
def initialized?(); :initialized == @state; end
|
205
|
-
|
206
197
|
end # class Message
|
207
198
|
|
208
199
|
|
@@ -237,19 +228,21 @@ module ZMQ
|
|
237
228
|
# handles deallocation of the native memory buffer.
|
238
229
|
#
|
239
230
|
def copy_in_bytes bytes, len
|
240
|
-
super
|
231
|
+
rc = super
|
241
232
|
|
242
233
|
# make sure we have a way to deallocate this memory if the object goes
|
243
234
|
# out of scope
|
244
235
|
define_finalizer
|
236
|
+
rc
|
245
237
|
end
|
246
238
|
|
247
239
|
# Manually release the message struct and its associated data
|
248
240
|
# buffer.
|
249
241
|
#
|
250
242
|
def close
|
251
|
-
super
|
243
|
+
rc = super
|
252
244
|
remove_finalizer
|
245
|
+
rc
|
253
246
|
end
|
254
247
|
|
255
248
|
|