rbczmq 1.7.4 → 1.7.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/.travis.yml +4 -1
- data/CHANGELOG.rdoc +13 -0
- data/Gemfile +8 -1
- data/Gemfile.lock +211 -2
- data/README.rdoc +7 -4
- data/ext/rbczmq/beacon.c +6 -3
- data/ext/rbczmq/context.c +117 -8
- data/ext/rbczmq/context.h +5 -0
- data/ext/rbczmq/message.c +6 -4
- data/ext/rbczmq/poller.c +12 -5
- data/ext/rbczmq/rbczmq_ext.c +2 -0
- data/ext/rbczmq/rbczmq_ext.h +1 -0
- data/ext/rbczmq/socket.c +135 -59
- data/ext/rbczmq/socket.h +2 -0
- data/ext/zeromq/CMakeLists.txt +3 -1
- data/ext/zeromq/NEWS +28 -3
- data/ext/zeromq/doc/zmq.txt +3 -3
- data/ext/zeromq/doc/zmq_getsockopt.txt +3 -3
- data/ext/zeromq/doc/zmq_msg_get.txt +2 -1
- data/ext/zeromq/doc/zmq_msg_more.txt +1 -1
- data/ext/zeromq/doc/zmq_setsockopt.txt +18 -19
- data/ext/zeromq/doc/zmq_socket.txt +4 -0
- data/ext/zeromq/include/zmq.h +14 -18
- data/ext/zeromq/src/clock.cpp +57 -2
- data/ext/zeromq/src/ctx.cpp +11 -5
- data/ext/zeromq/src/devpoll.cpp +5 -0
- data/ext/zeromq/src/devpoll.hpp +2 -0
- data/ext/zeromq/src/epoll.cpp +5 -0
- data/ext/zeromq/src/epoll.hpp +2 -0
- data/ext/zeromq/src/i_engine.hpp +2 -2
- data/ext/zeromq/src/kqueue.cpp +5 -0
- data/ext/zeromq/src/kqueue.hpp +2 -0
- data/ext/zeromq/src/pgm_receiver.cpp +2 -2
- data/ext/zeromq/src/pgm_receiver.hpp +2 -2
- data/ext/zeromq/src/pgm_sender.cpp +2 -2
- data/ext/zeromq/src/pgm_sender.hpp +2 -2
- data/ext/zeromq/src/poll.cpp +5 -0
- data/ext/zeromq/src/poll.hpp +2 -0
- data/ext/zeromq/src/router.cpp +2 -0
- data/ext/zeromq/src/select.cpp +5 -0
- data/ext/zeromq/src/select.hpp +2 -0
- data/ext/zeromq/src/session_base.cpp +2 -2
- data/ext/zeromq/src/signaler.cpp +73 -99
- data/ext/zeromq/src/signaler.hpp +2 -2
- data/ext/zeromq/src/socket_base.cpp +42 -40
- data/ext/zeromq/src/stream_engine.cpp +60 -58
- data/ext/zeromq/src/stream_engine.hpp +7 -8
- data/ext/zeromq/src/zmq_utils.cpp +6 -5
- data/ext/zeromq/tests/Makefile.am +6 -5
- data/ext/zeromq/tests/test_conflate.cpp +2 -5
- data/ext/zeromq/tests/test_ctx_destroy.cpp +1 -1
- data/ext/zeromq/tests/test_ctx_options.cpp +1 -1
- data/ext/zeromq/tests/test_immediate.cpp +1 -2
- data/ext/zeromq/tests/test_inproc_connect.cpp +1 -1
- data/ext/zeromq/tests/test_iov.cpp +1 -1
- data/ext/zeromq/tests/test_many_sockets.cpp +90 -0
- data/ext/zeromq/tests/test_monitor.cpp +3 -3
- data/ext/zeromq/tests/test_req_relaxed.cpp +1 -1
- data/ext/zeromq/tests/test_router_raw_empty.cpp +65 -0
- data/ext/zeromq/tests/test_spec_req.cpp +1 -1
- data/ext/zeromq/tests/test_stream.cpp +6 -7
- data/ext/zeromq/tests/test_sub_forward.cpp +1 -1
- data/ext/zeromq/tests/test_term_endpoint.cpp +2 -2
- data/ext/zeromq/tests/testutil.hpp +18 -1
- data/ext/zeromq/tools/Makefile.am +1 -1
- data/lib/zmq/socket.rb +1 -0
- data/lib/zmq/socket/stream.rb +44 -0
- data/lib/zmq/version.rb +1 -1
- data/test/socket/test_dealer_socket.rb +1 -1
- data/test/socket/test_pair_socket.rb +1 -1
- data/test/socket/test_pair_sockets.rb +1 -1
- data/test/socket/test_pub_socket.rb +1 -1
- data/test/socket/test_pub_sub_sockets.rb +1 -1
- data/test/socket/test_pull_socket.rb +1 -1
- data/test/socket/test_push_pull_sockets.rb +1 -1
- data/test/socket/test_push_socket.rb +1 -1
- data/test/socket/test_rep_socket.rb +1 -1
- data/test/socket/test_req_rep_sockets.rb +1 -1
- data/test/socket/test_req_socket.rb +1 -1
- data/test/socket/test_router_socket.rb +1 -1
- data/test/socket/test_routing.rb +1 -1
- data/test/socket/test_stream_socket.rb +74 -0
- data/test/socket/test_sub_socket.rb +1 -1
- data/test/test_beacon.rb +4 -2
- data/test/test_context.rb +2 -2
- data/test/test_frame.rb +2 -2
- data/test/test_handler.rb +2 -2
- data/test/test_logger.rb +1 -1
- data/test/test_loop.rb +2 -2
- data/test/test_message.rb +1 -1
- data/test/test_monitoring.rb +15 -3
- data/test/test_poller.rb +2 -2
- data/test/test_pollitem.rb +2 -2
- data/test/test_socket.rb +53 -6
- data/test/test_threading.rb +2 -2
- data/test/test_timer.rb +2 -2
- data/test/test_zmq.rb +2 -2
- metadata +109 -104
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
ZTlhN2Q2NzM1NzYxZjNlMjEzOWM3ZTVkNmYyM2FiMmQzYzE2NzIyYQ==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8ed671d96b6cc24a8815580b90a9fa972abc37ea
|
4
|
+
data.tar.gz: 9442f2bf13c7fd885656efabc7b46dc51ad0d1b6
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
MmQzNWIxMTExOTkwNWU4NzI3ZjZkNmVlOTVjY2U0MDE4MWQzMTYxNDhjMmU4
|
11
|
-
NjIyODg0ZGMxMjdjZWRmZjExOWMyZTA2OTAyNDY5ZTcyMmJkMDk=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
Mzg3MDk5M2E1MjIwOGU3Yjg2NjlkMWZlMGNmYjM2NDE2NWQ5MTM2N2RhM2Y1
|
14
|
-
NTJiMDNiMTUyNTk0ZGM2ODRmYjc0YTE0NTA1MmRhZGU2NDM3NzY2OTA0NDEx
|
15
|
-
MGYxNTk1OGE1N2VmYzJhODdjNGE4MTFjMzRhMjBlZmNhMWJlYjg=
|
6
|
+
metadata.gz: 7b69981b46f42fa30476b3cb35036c24f0a33b7fa896b720fdda085fa4652fcb6a2107b936d9b94d2bab84b3bb02d3f16fcb044fe688a48389ad976acf429451
|
7
|
+
data.tar.gz: 53303923c66106bb2a17eea84c958b87106cf2d745af310bb19d30c2a3473b15acb5b6bbc7aa687fc0504ab8a858757241ce30ff31053b9b45c35d08397075e9
|
data/.travis.yml
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
language: ruby
|
2
|
+
bundler_args: --quiet
|
2
3
|
rvm:
|
3
|
-
- rbx-
|
4
|
+
- rbx-2
|
4
5
|
- 1.9.3
|
5
6
|
- 2.0.0
|
6
7
|
- ruby-head
|
@@ -14,6 +15,8 @@ notifications:
|
|
14
15
|
branches:
|
15
16
|
only:
|
16
17
|
- master
|
18
|
+
before_install:
|
19
|
+
- if [[ $(ruby -v) =~ rubinius ]]; then travis_retry gem install rubysl; fi; gem list; true
|
17
20
|
matrix:
|
18
21
|
allow_failures:
|
19
22
|
- rvm: ruby-head
|
data/CHANGELOG.rdoc
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
= Changelog
|
2
2
|
|
3
|
+
== 1.7.5 (January 17, 2014)
|
4
|
+
|
5
|
+
* Update to ZMQ 4.0.3. This fixes several bugs, incluing: https://github.com/zeromq/libzmq/issues/769
|
6
|
+
* Fix ZMQ::Poller#poll handling of signals (INT/TERM)
|
7
|
+
* Fix several cases where Ruby strings with NUL characters in them would have been truncated as C strings when sent in ZMQ messages.
|
8
|
+
* Updates Gemfile to support rubinius 2.
|
9
|
+
* Add ZMQ::Socket#unbind method. Has same affect as disconnect, but matches semantics of bind, as per other bindings.
|
10
|
+
* Update ZMQ::Socket state to only become disconnected after all connected/bound endpoints are removed with disconnect/unbind.
|
11
|
+
* Fix ZMQ::Socket connect/bind bug with percent symbols in the address URI.
|
12
|
+
* Add ZMQ::Socket#last_endpoint for retrieving the string URI with an ephemeral port number filled in.
|
13
|
+
* Add STREAM socket type, using ruby class ZMQ::Socket::Stream.
|
14
|
+
* Fix ZMQ::Socket implicit close when garbage collected.
|
15
|
+
|
3
16
|
== 1.7.4 (November 25, 2013)
|
4
17
|
|
5
18
|
* Update ZMQ::Socket to support strings with null bytes in them (Matt Connolly)
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -6,18 +6,227 @@ PATH
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
+
ffi2-generators (0.1.1)
|
9
10
|
json (1.8.1)
|
10
|
-
|
11
|
+
minitest (4.7.5)
|
12
|
+
rake (10.1.1)
|
11
13
|
rake-compiler (0.8.3)
|
12
14
|
rake
|
13
|
-
rdoc (4.0
|
15
|
+
rdoc (4.1.0)
|
14
16
|
json (~> 1.4)
|
17
|
+
rubysl (2.0.15)
|
18
|
+
rubysl-abbrev (~> 2.0)
|
19
|
+
rubysl-base64 (~> 2.0)
|
20
|
+
rubysl-benchmark (~> 2.0)
|
21
|
+
rubysl-bigdecimal (~> 2.0)
|
22
|
+
rubysl-cgi (~> 2.0)
|
23
|
+
rubysl-cgi-session (~> 2.0)
|
24
|
+
rubysl-cmath (~> 2.0)
|
25
|
+
rubysl-complex (~> 2.0)
|
26
|
+
rubysl-continuation (~> 2.0)
|
27
|
+
rubysl-coverage (~> 2.0)
|
28
|
+
rubysl-csv (~> 2.0)
|
29
|
+
rubysl-curses (~> 2.0)
|
30
|
+
rubysl-date (~> 2.0)
|
31
|
+
rubysl-delegate (~> 2.0)
|
32
|
+
rubysl-digest (~> 2.0)
|
33
|
+
rubysl-drb (~> 2.0)
|
34
|
+
rubysl-e2mmap (~> 2.0)
|
35
|
+
rubysl-english (~> 2.0)
|
36
|
+
rubysl-enumerator (~> 2.0)
|
37
|
+
rubysl-erb (~> 2.0)
|
38
|
+
rubysl-etc (~> 2.0)
|
39
|
+
rubysl-expect (~> 2.0)
|
40
|
+
rubysl-fcntl (~> 2.0)
|
41
|
+
rubysl-fiber (~> 2.0)
|
42
|
+
rubysl-fileutils (~> 2.0)
|
43
|
+
rubysl-find (~> 2.0)
|
44
|
+
rubysl-forwardable (~> 2.0)
|
45
|
+
rubysl-getoptlong (~> 2.0)
|
46
|
+
rubysl-gserver (~> 2.0)
|
47
|
+
rubysl-io-console (~> 2.0)
|
48
|
+
rubysl-io-nonblock (~> 2.0)
|
49
|
+
rubysl-io-wait (~> 2.0)
|
50
|
+
rubysl-ipaddr (~> 2.0)
|
51
|
+
rubysl-irb (~> 2.0)
|
52
|
+
rubysl-logger (~> 2.0)
|
53
|
+
rubysl-mathn (~> 2.0)
|
54
|
+
rubysl-matrix (~> 2.0)
|
55
|
+
rubysl-mkmf (~> 2.0)
|
56
|
+
rubysl-monitor (~> 2.0)
|
57
|
+
rubysl-mutex_m (~> 2.0)
|
58
|
+
rubysl-net-ftp (~> 2.0)
|
59
|
+
rubysl-net-http (~> 2.0)
|
60
|
+
rubysl-net-imap (~> 2.0)
|
61
|
+
rubysl-net-pop (~> 2.0)
|
62
|
+
rubysl-net-protocol (~> 2.0)
|
63
|
+
rubysl-net-smtp (~> 2.0)
|
64
|
+
rubysl-net-telnet (~> 2.0)
|
65
|
+
rubysl-nkf (~> 2.0)
|
66
|
+
rubysl-observer (~> 2.0)
|
67
|
+
rubysl-open-uri (~> 2.0)
|
68
|
+
rubysl-open3 (~> 2.0)
|
69
|
+
rubysl-openssl (~> 2.0)
|
70
|
+
rubysl-optparse (~> 2.0)
|
71
|
+
rubysl-ostruct (~> 2.0)
|
72
|
+
rubysl-pathname (~> 2.0)
|
73
|
+
rubysl-prettyprint (~> 2.0)
|
74
|
+
rubysl-prime (~> 2.0)
|
75
|
+
rubysl-profile (~> 2.0)
|
76
|
+
rubysl-profiler (~> 2.0)
|
77
|
+
rubysl-pstore (~> 2.0)
|
78
|
+
rubysl-pty (~> 2.0)
|
79
|
+
rubysl-rational (~> 2.0)
|
80
|
+
rubysl-readline (~> 2.0)
|
81
|
+
rubysl-resolv (~> 2.0)
|
82
|
+
rubysl-rexml (~> 2.0)
|
83
|
+
rubysl-rinda (~> 2.0)
|
84
|
+
rubysl-rss (~> 2.0)
|
85
|
+
rubysl-scanf (~> 2.0)
|
86
|
+
rubysl-securerandom (~> 2.0)
|
87
|
+
rubysl-set (~> 2.0)
|
88
|
+
rubysl-shellwords (~> 2.0)
|
89
|
+
rubysl-singleton (~> 2.0)
|
90
|
+
rubysl-socket (~> 2.0)
|
91
|
+
rubysl-stringio (~> 2.0)
|
92
|
+
rubysl-strscan (~> 2.0)
|
93
|
+
rubysl-sync (~> 2.0)
|
94
|
+
rubysl-syslog (~> 2.0)
|
95
|
+
rubysl-tempfile (~> 2.0)
|
96
|
+
rubysl-thread (~> 2.0)
|
97
|
+
rubysl-thwait (~> 2.0)
|
98
|
+
rubysl-time (~> 2.0)
|
99
|
+
rubysl-timeout (~> 2.0)
|
100
|
+
rubysl-tmpdir (~> 2.0)
|
101
|
+
rubysl-tsort (~> 2.0)
|
102
|
+
rubysl-un (~> 2.0)
|
103
|
+
rubysl-uri (~> 2.0)
|
104
|
+
rubysl-weakref (~> 2.0)
|
105
|
+
rubysl-webrick (~> 2.0)
|
106
|
+
rubysl-xmlrpc (~> 2.0)
|
107
|
+
rubysl-yaml (~> 2.0)
|
108
|
+
rubysl-zlib (~> 2.0)
|
109
|
+
rubysl-abbrev (2.0.4)
|
110
|
+
rubysl-base64 (2.0.0)
|
111
|
+
rubysl-benchmark (2.0.1)
|
112
|
+
rubysl-bigdecimal (2.0.2)
|
113
|
+
rubysl-cgi (2.0.1)
|
114
|
+
rubysl-cgi-session (2.0.1)
|
115
|
+
rubysl-cmath (2.0.0)
|
116
|
+
rubysl-complex (2.0.0)
|
117
|
+
rubysl-continuation (2.0.0)
|
118
|
+
rubysl-coverage (2.0.3)
|
119
|
+
rubysl-csv (2.0.2)
|
120
|
+
rubysl-english (~> 2.0)
|
121
|
+
rubysl-curses (2.0.1)
|
122
|
+
rubysl-date (2.0.6)
|
123
|
+
rubysl-delegate (2.0.1)
|
124
|
+
rubysl-digest (2.0.3)
|
125
|
+
rubysl-drb (2.0.1)
|
126
|
+
rubysl-e2mmap (2.0.0)
|
127
|
+
rubysl-english (2.0.0)
|
128
|
+
rubysl-enumerator (2.0.0)
|
129
|
+
rubysl-erb (2.0.1)
|
130
|
+
rubysl-etc (2.0.3)
|
131
|
+
ffi2-generators (~> 0.1)
|
132
|
+
rubysl-expect (2.0.0)
|
133
|
+
rubysl-fcntl (2.0.4)
|
134
|
+
ffi2-generators (~> 0.1)
|
135
|
+
rubysl-fiber (2.0.0)
|
136
|
+
rubysl-fileutils (2.0.3)
|
137
|
+
rubysl-find (2.0.1)
|
138
|
+
rubysl-forwardable (2.0.1)
|
139
|
+
rubysl-getoptlong (2.0.0)
|
140
|
+
rubysl-gserver (2.0.0)
|
141
|
+
rubysl-socket (~> 2.0)
|
142
|
+
rubysl-thread (~> 2.0)
|
143
|
+
rubysl-io-console (2.0.0)
|
144
|
+
rubysl-io-nonblock (2.0.0)
|
145
|
+
rubysl-io-wait (2.0.0)
|
146
|
+
rubysl-ipaddr (2.0.0)
|
147
|
+
rubysl-irb (2.0.4)
|
148
|
+
rubysl-e2mmap (~> 2.0)
|
149
|
+
rubysl-mathn (~> 2.0)
|
150
|
+
rubysl-readline (~> 2.0)
|
151
|
+
rubysl-thread (~> 2.0)
|
152
|
+
rubysl-logger (2.0.0)
|
153
|
+
rubysl-mathn (2.0.0)
|
154
|
+
rubysl-matrix (2.1.0)
|
155
|
+
rubysl-e2mmap (~> 2.0)
|
156
|
+
rubysl-mkmf (2.0.1)
|
157
|
+
rubysl-fileutils (~> 2.0)
|
158
|
+
rubysl-shellwords (~> 2.0)
|
159
|
+
rubysl-monitor (2.0.0)
|
160
|
+
rubysl-mutex_m (2.0.0)
|
161
|
+
rubysl-net-ftp (2.0.1)
|
162
|
+
rubysl-net-http (2.0.4)
|
163
|
+
rubysl-cgi (~> 2.0)
|
164
|
+
rubysl-erb (~> 2.0)
|
165
|
+
rubysl-singleton (~> 2.0)
|
166
|
+
rubysl-net-imap (2.0.1)
|
167
|
+
rubysl-net-pop (2.0.1)
|
168
|
+
rubysl-net-protocol (2.0.1)
|
169
|
+
rubysl-net-smtp (2.0.1)
|
170
|
+
rubysl-net-telnet (2.0.0)
|
171
|
+
rubysl-nkf (2.0.1)
|
172
|
+
rubysl-observer (2.0.0)
|
173
|
+
rubysl-open-uri (2.0.0)
|
174
|
+
rubysl-open3 (2.0.0)
|
175
|
+
rubysl-openssl (2.0.5)
|
176
|
+
rubysl-optparse (2.0.1)
|
177
|
+
rubysl-shellwords (~> 2.0)
|
178
|
+
rubysl-ostruct (2.0.4)
|
179
|
+
rubysl-pathname (2.0.0)
|
180
|
+
rubysl-prettyprint (2.0.2)
|
181
|
+
rubysl-prime (2.0.1)
|
182
|
+
rubysl-profile (2.0.0)
|
183
|
+
rubysl-profiler (2.0.1)
|
184
|
+
rubysl-pstore (2.0.0)
|
185
|
+
rubysl-pty (2.0.2)
|
186
|
+
rubysl-rational (2.0.1)
|
187
|
+
rubysl-readline (2.0.2)
|
188
|
+
rubysl-resolv (2.0.0)
|
189
|
+
rubysl-rexml (2.0.2)
|
190
|
+
rubysl-rinda (2.0.0)
|
191
|
+
rubysl-rss (2.0.0)
|
192
|
+
rubysl-scanf (2.0.0)
|
193
|
+
rubysl-securerandom (2.0.0)
|
194
|
+
rubysl-set (2.0.1)
|
195
|
+
rubysl-shellwords (2.0.0)
|
196
|
+
rubysl-singleton (2.0.0)
|
197
|
+
rubysl-socket (2.0.1)
|
198
|
+
rubysl-stringio (2.0.0)
|
199
|
+
rubysl-strscan (2.0.0)
|
200
|
+
rubysl-sync (2.0.0)
|
201
|
+
rubysl-syslog (2.0.1)
|
202
|
+
ffi2-generators (~> 0.1)
|
203
|
+
rubysl-tempfile (2.0.1)
|
204
|
+
rubysl-test-unit (2.0.3)
|
205
|
+
minitest (~> 4.7)
|
206
|
+
rubysl-thread (2.0.2)
|
207
|
+
rubysl-thwait (2.0.0)
|
208
|
+
rubysl-time (2.0.3)
|
209
|
+
rubysl-timeout (2.0.0)
|
210
|
+
rubysl-tmpdir (2.0.0)
|
211
|
+
rubysl-tsort (2.0.1)
|
212
|
+
rubysl-un (2.0.0)
|
213
|
+
rubysl-fileutils (~> 2.0)
|
214
|
+
rubysl-optparse (~> 2.0)
|
215
|
+
rubysl-uri (2.0.0)
|
216
|
+
rubysl-weakref (2.0.0)
|
217
|
+
rubysl-webrick (2.0.0)
|
218
|
+
rubysl-xmlrpc (2.0.0)
|
219
|
+
rubysl-yaml (2.0.4)
|
220
|
+
rubysl-zlib (2.0.1)
|
15
221
|
|
16
222
|
PLATFORMS
|
17
223
|
ruby
|
18
224
|
|
19
225
|
DEPENDENCIES
|
226
|
+
minitest (~> 4.7)
|
20
227
|
rake
|
21
228
|
rake-compiler (~> 0.8.0)
|
22
229
|
rbczmq!
|
23
230
|
rdoc
|
231
|
+
rubysl (~> 2.0)
|
232
|
+
rubysl-test-unit (~> 2.0)
|
data/README.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= rbczmq - binding for the high level ZeroMQ C API {<img src="https://secure.travis-ci.org/methodmissing/rbczmq.png" alt="Build Status" />}[http://travis-ci.org/methodmissing/rbczmq]
|
2
2
|
|
3
|
-
(c) 2011-
|
3
|
+
(c) 2011-2014 Lourens Naudé (methodmissing), James Tucker (raggi), Matt Connolly (mattconnolly) with API guidance from the czmq (http://czmq.zeromq.org/) project.
|
4
4
|
|
5
5
|
http://github.com/methodmissing/rbczmq
|
6
6
|
|
@@ -206,7 +206,7 @@ Here's a few basic examples. Please refer to documentation (http://methodmissing
|
|
206
206
|
* A POSIX compliant OS, known to work well on Linux, BSD variants, Mac OS X and SmartOS.
|
207
207
|
* Ruby MRI 1.9, 2.0 or Rubinius (JRuby capi support forthcoming)
|
208
208
|
* A C compiler
|
209
|
-
* This is a "fat" gem, including its own source code for both ZeroMQ and CZMQ libraries. No system installation
|
209
|
+
* This is a "fat" gem, including its own source code for both ZeroMQ and CZMQ libraries. No system installation of either library is required.
|
210
210
|
|
211
211
|
== Installation
|
212
212
|
|
@@ -222,10 +222,14 @@ Building from source
|
|
222
222
|
git submodule update
|
223
223
|
rake
|
224
224
|
|
225
|
-
Running tests
|
225
|
+
Running all tests
|
226
226
|
|
227
227
|
rake test
|
228
228
|
|
229
|
+
Running a single test file:
|
230
|
+
|
231
|
+
ruby -Ilib test/test_context.rb
|
232
|
+
|
229
233
|
OS X notes:
|
230
234
|
|
231
235
|
If you are installing the package on a new Mac ensure you have libtool and autoconf installed.
|
@@ -247,7 +251,6 @@ This gem uses the "zmq" and "czmq" libraries, both of which are licensed under t
|
|
247
251
|
* Revisit the ZMQ::Loop API
|
248
252
|
* RDOC fail on mixed C and Ruby source files that document that same constants
|
249
253
|
* GC guards to prevent recycling objects being sent / received.
|
250
|
-
* Sockets can bind && connect to multiple endpoints - account for that
|
251
254
|
* Watch out for further cases where REQ / REP pairs could raise EFSM
|
252
255
|
* Do not clobber local scope from macros (James's commit in master)
|
253
256
|
* Incorporate examples into CI as well
|
data/ext/rbczmq/beacon.c
CHANGED
@@ -8,7 +8,10 @@
|
|
8
8
|
static VALUE rb_czmq_nogvl_beacon_destroy(void *ptr)
|
9
9
|
{
|
10
10
|
zmq_beacon_wrapper *beacon = ptr;
|
11
|
-
|
11
|
+
if (beacon->beacon) {
|
12
|
+
zbeacon_destroy(&beacon->beacon);
|
13
|
+
beacon->beacon = NULL;
|
14
|
+
}
|
12
15
|
return Qnil;
|
13
16
|
}
|
14
17
|
|
@@ -186,7 +189,7 @@ static VALUE rb_czmq_beacon_publish(VALUE obj, VALUE transmit)
|
|
186
189
|
GetZmqBeacon(obj);
|
187
190
|
Check_Type(transmit, T_STRING);
|
188
191
|
args.beacon = beacon;
|
189
|
-
args.transmit =
|
192
|
+
args.transmit = RSTRING_PTR(transmit);
|
190
193
|
args.length = (int)RSTRING_LEN(transmit);
|
191
194
|
rb_thread_blocking_region(rb_czmq_nogvl_publish, (void *)&args, RUBY_UBF_IO, 0);
|
192
195
|
return Qnil;
|
@@ -254,7 +257,7 @@ static VALUE rb_czmq_beacon_subscribe(VALUE obj, VALUE filter)
|
|
254
257
|
args.length = 0;
|
255
258
|
} else {
|
256
259
|
Check_Type(filter, T_STRING);
|
257
|
-
args.filter =
|
260
|
+
args.filter = RSTRING_PTR(filter);
|
258
261
|
args.length = (int)RSTRING_LEN(filter);
|
259
262
|
}
|
260
263
|
rb_thread_blocking_region(rb_czmq_nogvl_subscribe, (void *)&args, RUBY_UBF_IO, 0);
|
data/ext/rbczmq/context.c
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#include "rbczmq_ext.h"
|
2
2
|
|
3
3
|
static VALUE intern_zctx_process;
|
4
|
+
static zmutex_t* context_mutex = NULL; /* this can only be used outside of Ruby GVL to avoid deadlocks */
|
4
5
|
|
5
6
|
static VALUE rb_czmq_ctx_set_iothreads(VALUE context, VALUE io_threads);
|
6
7
|
|
@@ -18,13 +19,19 @@ static VALUE get_pid()
|
|
18
19
|
*/
|
19
20
|
static VALUE rb_czmq_nogvl_zctx_destroy(void *ptr)
|
20
21
|
{
|
22
|
+
zmutex_lock(context_mutex);
|
23
|
+
|
21
24
|
errno = 0;
|
22
25
|
zmq_ctx_wrapper *ctx = ptr;
|
23
26
|
if (ctx->pid == getpid()) {
|
24
|
-
/*
|
27
|
+
/* Only actually destroy the context if we are the process that created it. */
|
28
|
+
/* This may need to be changed when ZeroMQ's support for forking is improved. */
|
25
29
|
zctx_destroy(&ctx->ctx);
|
26
30
|
}
|
27
31
|
ctx->flags |= ZMQ_CONTEXT_DESTROYED;
|
32
|
+
|
33
|
+
zmutex_unlock(context_mutex);
|
34
|
+
|
28
35
|
return Qnil;
|
29
36
|
}
|
30
37
|
|
@@ -37,9 +44,79 @@ static void rb_czmq_free_ctx(zmq_ctx_wrapper *ctx)
|
|
37
44
|
{
|
38
45
|
VALUE ctx_map;
|
39
46
|
ctx_map = rb_ivar_get(rb_mZmq, intern_zctx_process);
|
47
|
+
|
48
|
+
// destroy sockets. This duplicates czmq's context shutdown which destroys sockets,
|
49
|
+
// but we need to process the list of Ruby ZMQ::Socket objects' data objects to mark
|
50
|
+
// them as closed so that they cannot be double destroyed.
|
51
|
+
zmq_sock_wrapper* socket;
|
52
|
+
while ((socket = zlist_pop(ctx->sockets))) {
|
53
|
+
rb_czmq_context_destroy_socket(socket);
|
54
|
+
}
|
55
|
+
|
56
|
+
// finally, shutdown the context.
|
40
57
|
rb_thread_blocking_region(rb_czmq_nogvl_zctx_destroy, ctx, RUBY_UBF_IO, 0);
|
58
|
+
|
41
59
|
ctx->ctx = NULL;
|
42
60
|
rb_hash_aset(ctx_map, ctx->pidValue, Qnil);
|
61
|
+
zlist_destroy(&ctx->sockets);
|
62
|
+
}
|
63
|
+
|
64
|
+
/*
|
65
|
+
* :nodoc:
|
66
|
+
* Destroy the socket while the GIL is released - may block depending on socket linger value.
|
67
|
+
*
|
68
|
+
*/
|
69
|
+
VALUE rb_czmq_nogvl_zsocket_destroy(void *ptr)
|
70
|
+
{
|
71
|
+
zmutex_lock(context_mutex);
|
72
|
+
|
73
|
+
zmq_sock_wrapper *sock = ptr;
|
74
|
+
errno = 0;
|
75
|
+
// zclock_log ("I: %s socket %p, context %p: destroy", zsocket_type_str(sock->socket), sock, sock->ctx);
|
76
|
+
zsocket_destroy(sock->ctx, sock->socket);
|
77
|
+
|
78
|
+
zmutex_unlock(context_mutex);
|
79
|
+
return Qnil;
|
80
|
+
}
|
81
|
+
|
82
|
+
/*
|
83
|
+
* :nodoc:
|
84
|
+
*
|
85
|
+
* Interal use: Close a socket from the context being destroyed or garbage collected, or
|
86
|
+
* from the socket being closed, or garbage collected.
|
87
|
+
*
|
88
|
+
* The order of these events cannot be determined, so this function has to be idempotent
|
89
|
+
* about this. The close socket call to CZMQ must happen only once or it will abort the
|
90
|
+
* application.
|
91
|
+
*/
|
92
|
+
void rb_czmq_context_destroy_socket(zmq_sock_wrapper* socket)
|
93
|
+
{
|
94
|
+
if (socket == NULL || socket->context == NULL) {
|
95
|
+
return;
|
96
|
+
}
|
97
|
+
|
98
|
+
if (socket && socket->context == Qnil) {
|
99
|
+
// A socket with a context object of Qnil is created by ZMQ::Beacon#new.
|
100
|
+
// zbeacon is responsible for closing this socket in its own context, we will simply mark
|
101
|
+
// it as destroyed and let the ZMQ::Beacon object do the clean up when its internal
|
102
|
+
// context is destroyed.
|
103
|
+
}
|
104
|
+
else if (socket->ctx && socket->ctx_wrapper && !(socket->flags & ZMQ_SOCKET_DESTROYED)) {
|
105
|
+
zmq_ctx_wrapper *ctx = (zmq_ctx_wrapper *)socket->ctx_wrapper;
|
106
|
+
if (ctx) {
|
107
|
+
// remove from the list of socket objects created by this context object.
|
108
|
+
zlist_remove(ctx->sockets, socket);
|
109
|
+
|
110
|
+
if (socket->socket) {
|
111
|
+
rb_thread_blocking_region(rb_czmq_nogvl_zsocket_destroy, socket, RUBY_UBF_IO, 0);
|
112
|
+
}
|
113
|
+
}
|
114
|
+
}
|
115
|
+
|
116
|
+
socket->flags |= ZMQ_SOCKET_DESTROYED;
|
117
|
+
socket->ctx = NULL;
|
118
|
+
socket->socket = NULL;
|
119
|
+
socket->state = ZMQ_SOCKET_DISCONNECTED;
|
43
120
|
}
|
44
121
|
|
45
122
|
/*
|
@@ -56,6 +133,19 @@ static void rb_czmq_free_ctx_gc(void *ptr)
|
|
56
133
|
}
|
57
134
|
}
|
58
135
|
|
136
|
+
/*
|
137
|
+
* :nodoc:
|
138
|
+
* GC mark callback
|
139
|
+
*
|
140
|
+
*/
|
141
|
+
static void rb_czmq_mark_ctx_gc(void *ptr)
|
142
|
+
{
|
143
|
+
zmq_ctx_wrapper *ctx = (zmq_ctx_wrapper *)ptr;
|
144
|
+
if (ctx) {
|
145
|
+
rb_gc_mark(ctx->pidValue);
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
59
149
|
/*
|
60
150
|
* :nodoc:
|
61
151
|
* Creates a new context while the GIL is released.
|
@@ -67,6 +157,7 @@ static VALUE rb_czmq_nogvl_zctx_new(ZMQ_UNUSED void *ptr)
|
|
67
157
|
zctx_t *ctx = NULL;
|
68
158
|
ctx = zctx_new();
|
69
159
|
zctx_set_linger(ctx, 1);
|
160
|
+
zsys_handler_reset(); // restore ruby signal handlers.
|
70
161
|
return (VALUE)ctx;
|
71
162
|
}
|
72
163
|
|
@@ -93,12 +184,13 @@ static VALUE rb_czmq_ctx_s_new(int argc, VALUE *argv, VALUE context)
|
|
93
184
|
rb_scan_args(argc, argv, "01", &io_threads);
|
94
185
|
ctx_map = rb_ivar_get(rb_mZmq, intern_zctx_process);
|
95
186
|
if (!NIL_P(rb_hash_aref(ctx_map, get_pid()))) rb_raise(rb_eZmqError, "single ZMQ context per process allowed");
|
96
|
-
context = Data_Make_Struct(rb_cZmqContext, zmq_ctx_wrapper,
|
187
|
+
context = Data_Make_Struct(rb_cZmqContext, zmq_ctx_wrapper, rb_czmq_mark_ctx_gc, rb_czmq_free_ctx_gc, ctx);
|
97
188
|
ctx->ctx = (zctx_t*)rb_thread_blocking_region(rb_czmq_nogvl_zctx_new, NULL, RUBY_UBF_IO, 0);
|
98
189
|
ZmqAssertObjOnAlloc(ctx->ctx, ctx);
|
99
190
|
ctx->flags = 0;
|
100
191
|
ctx->pid = getpid();
|
101
192
|
ctx->pidValue = get_pid();
|
193
|
+
ctx->sockets = zlist_new();
|
102
194
|
rb_obj_call_init(context, 0, NULL);
|
103
195
|
rb_hash_aset(ctx_map, ctx->pidValue, context);
|
104
196
|
if (!NIL_P(io_threads)) rb_czmq_ctx_set_iothreads(context, io_threads);
|
@@ -189,7 +281,10 @@ VALUE rb_czmq_nogvl_socket_new(void *ptr)
|
|
189
281
|
{
|
190
282
|
errno = 0;
|
191
283
|
struct nogvl_socket_args *args = ptr;
|
192
|
-
|
284
|
+
zmutex_lock(context_mutex);
|
285
|
+
VALUE result = (VALUE)zsocket_new(args->ctx, args->type);
|
286
|
+
zmutex_unlock(context_mutex);
|
287
|
+
return result;
|
193
288
|
}
|
194
289
|
|
195
290
|
/*
|
@@ -219,15 +314,17 @@ static inline VALUE rb_czmq_ctx_socket_klass(int socket_type)
|
|
219
314
|
case ZMQ_DEALER: return rb_cZmqDealerSocket;
|
220
315
|
break;
|
221
316
|
case ZMQ_XPUB: return rb_cZmqXPubSocket;
|
222
|
-
|
317
|
+
break;
|
223
318
|
case ZMQ_XSUB: return rb_cZmqXSubSocket;
|
224
|
-
|
319
|
+
break;
|
320
|
+
case ZMQ_STREAM: return rb_cZmqStreamSocket;
|
321
|
+
break;
|
225
322
|
default: rb_raise(rb_eZmqError, "ZMQ socket type %d not supported!", socket_type);
|
226
323
|
break;
|
227
324
|
}
|
228
325
|
}
|
229
326
|
|
230
|
-
VALUE rb_czmq_socket_alloc(VALUE context, zctx_t *
|
327
|
+
VALUE rb_czmq_socket_alloc(VALUE context, zctx_t *zctx, void *s)
|
231
328
|
{
|
232
329
|
VALUE socket;
|
233
330
|
zmq_sock_wrapper *sock = NULL;
|
@@ -235,7 +332,13 @@ VALUE rb_czmq_socket_alloc(VALUE context, zctx_t *ctx, void *s)
|
|
235
332
|
sock->socket = s;
|
236
333
|
ZmqAssertObjOnAlloc(sock->socket, sock);
|
237
334
|
sock->flags = 0;
|
238
|
-
sock->ctx =
|
335
|
+
sock->ctx = zctx; // czmq context
|
336
|
+
if (context == Qnil) {
|
337
|
+
sock->ctx_wrapper = NULL;
|
338
|
+
} else {
|
339
|
+
ZmqGetContext(context);
|
340
|
+
sock->ctx_wrapper = ctx; // rbczmq ZMQ::Context wrapped data struct
|
341
|
+
}
|
239
342
|
sock->verbose = false;
|
240
343
|
sock->state = ZMQ_SOCKET_PENDING;
|
241
344
|
sock->endpoints = rb_ary_new();
|
@@ -276,7 +379,11 @@ static VALUE rb_czmq_ctx_socket(VALUE obj, VALUE type)
|
|
276
379
|
|
277
380
|
args.ctx = ctx->ctx;
|
278
381
|
args.type = socket_type;
|
279
|
-
|
382
|
+
VALUE socket_object = rb_czmq_socket_alloc(obj, ctx->ctx, (void*)rb_thread_blocking_region(rb_czmq_nogvl_socket_new, (void *)&args, RUBY_UBF_IO, 0));
|
383
|
+
zmq_sock_wrapper *sock = NULL;
|
384
|
+
GetZmqSocket(socket_object);
|
385
|
+
zlist_push(ctx->sockets, sock);
|
386
|
+
return socket_object;
|
280
387
|
}
|
281
388
|
|
282
389
|
void _init_rb_czmq_context()
|
@@ -291,4 +398,6 @@ void _init_rb_czmq_context()
|
|
291
398
|
rb_define_method(rb_cZmqContext, "iothreads=", rb_czmq_ctx_set_iothreads, 1);
|
292
399
|
rb_define_method(rb_cZmqContext, "linger=", rb_czmq_ctx_set_linger, 1);
|
293
400
|
rb_define_method(rb_cZmqContext, "socket", rb_czmq_ctx_socket, 1);
|
401
|
+
|
402
|
+
context_mutex = zmutex_new();
|
294
403
|
}
|