rbczmq 1.5 → 1.6

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.
@@ -1,5 +1,10 @@
1
1
  = Changelog
2
2
 
3
+ == 1.6 (May 2, 2013 )
4
+ * Bump czmq to 1.4.0
5
+ * Bump zeromq to 3.2.3
6
+ * Make ZMQ::Loop#start thread-safe (Matt Connolly)
7
+
3
8
  == 1.5 (April 29, 2013)
4
9
  * Add support for XSUB and XPUB socket types (Matt Connolly)
5
10
  * Introduce a ZMQ.proxy API (Matt Connolly)
Binary file
@@ -111,11 +111,6 @@ end
111
111
  # build libzmq
112
112
  lib = libs_path + "libzmq.#{LIBEXT}"
113
113
  Dir.chdir zmq_path do
114
- Dir['../patches/zeromq/*.patch'].sort.each do |patch|
115
- puts "applying: #{patch}"
116
- sys "patch -p1 < #{patch}", "failed to apply patch: #{patch}"
117
- end
118
-
119
114
  sys "./autogen.sh", "ZeroMQ autogen failed!" unless File.exist?(zmq_path + 'configure')
120
115
  sys "./configure --prefix=#{dst_path} --without-documentation --enable-shared && make && make install", "ZeroMQ compile error!"
121
116
  end unless File.exist?(lib)
@@ -123,11 +118,6 @@ end unless File.exist?(lib)
123
118
  # build libczmq
124
119
  lib = libs_path + "libczmq.#{LIBEXT}"
125
120
  Dir.chdir czmq_path do
126
- Dir['../patches/czmq/*.patch'].sort.each do |patch|
127
- puts "Applying: #{patch}"
128
- sys "patch -p1 < #{patch}", "Failed to apply patch: #{patch}"
129
- end
130
-
131
121
  sys "./autogen.sh", "CZMQ autogen failed!" unless File.exist?(czmq_path + 'configure')
132
122
  sys "./configure LDFLAGS=-L#{libs_path} CFLAGS='#{CZMQ_CFLAGS.join(" ")}' --prefix=#{dst_path} --with-libzmq=#{dst_path} --disable-shared && make all && make install", "CZMQ compile error!"
133
123
  end unless File.exist?(lib)
@@ -62,25 +62,63 @@ ZMQ_NOINLINE static int rb_czmq_callback(zloop_t *loop, VALUE *args)
62
62
  return 0;
63
63
  }
64
64
 
65
+ /* data structure used to pass czmq parameters across to callbacks with ruby GVL */
66
+ struct _rb_czmq_callback_invocation
67
+ {
68
+ int result;
69
+ zloop_t *loop;
70
+ VALUE* args;
71
+
72
+ // used by poll item callback
73
+ zmq_pollitem_t *item;
74
+ void* arg;
75
+ };
76
+
65
77
  /*
66
78
  * :nodoc:
67
79
  * Low level callback for when timers registered with the reactor fires. This calls back into the Ruby VM.
68
80
  *
81
+ * This function is called from rb_thread_call_with_gvl and is executed with the ruby GVL held.
69
82
  */
70
- ZMQ_NOINLINE static int rb_czmq_loop_timer_callback(zloop_t *loop, ZMQ_UNUSED zmq_pollitem_t *item, void *cb)
83
+ ZMQ_NOINLINE static void* rb_czmq_loop_timer_callback_with_gvl(void* data)
71
84
  {
72
- int rc;
85
+ struct _rb_czmq_callback_invocation* invocation = (struct _rb_czmq_callback_invocation*)data;
86
+ zloop_t* loop = invocation->loop;
87
+ zmq_pollitem_t *item = invocation->item;
88
+ void* cb = invocation->arg;
89
+
73
90
  VALUE args[3];
74
91
  ZmqGetTimer((VALUE)cb);
75
92
  if (timer->cancelled == true) {
76
- zloop_timer_end(loop, (void *)cb);
77
- return 0;
78
- }
79
- args[0] = (VALUE)cb;
80
- args[1] = intern_call;
81
- args[2] = Qnil;
82
- rc = rb_czmq_callback(loop, args);
83
- return rc;
93
+ zloop_timer_end(loop, (void *)cb);
94
+ invocation->result = 0;
95
+ } else {
96
+ args[0] = (VALUE)cb;
97
+ args[1] = intern_call;
98
+ args[2] = Qnil;
99
+
100
+ invocation->result = rb_czmq_callback(loop, args);
101
+ }
102
+ return NULL;
103
+ }
104
+
105
+
106
+ /*
107
+ * :nodoc:
108
+ * Low level callback for when timers registered with the reactor fires. This calls back into the Ruby VM.
109
+ *
110
+ * This is the CZMQ callback, which grabs the ruby GVL and calls the with GVL callback above.
111
+ */
112
+ ZMQ_NOINLINE static int rb_czmq_loop_timer_callback(zloop_t *loop, ZMQ_UNUSED zmq_pollitem_t *item, void *cb)
113
+ {
114
+ struct _rb_czmq_callback_invocation invocation;
115
+ invocation.result = -1;
116
+ invocation.loop = loop;
117
+ invocation.item = item;
118
+ invocation.args = NULL;
119
+ invocation.arg = cb;
120
+ rb_thread_call_with_gvl(rb_czmq_loop_timer_callback_with_gvl, &invocation);
121
+ return invocation.result;
84
122
  }
85
123
 
86
124
  /*
@@ -88,9 +126,15 @@ ZMQ_NOINLINE static int rb_czmq_loop_timer_callback(zloop_t *loop, ZMQ_UNUSED zm
88
126
  * Low level callback for handling socket activity. This calls back into the Ruby VM. We special case ZMQ_POLLERR
89
127
  * by invoking the error callback on the handler registered for this socket.
90
128
  *
129
+ * This function is called from rb_thread_call_with_gvl and is executed with the ruby GVL held.
91
130
  */
92
- ZMQ_NOINLINE static int rb_czmq_loop_pollitem_callback(zloop_t *loop, zmq_pollitem_t *item, void *arg)
131
+ ZMQ_NOINLINE static void* rb_czmq_loop_pollitem_callback_with_gvl(void* data)
93
132
  {
133
+ struct _rb_czmq_callback_invocation *invocation = (struct _rb_czmq_callback_invocation *)data;
134
+ zloop_t *loop = invocation->loop;
135
+ zmq_pollitem_t *item = invocation->item;
136
+ void *arg = invocation->arg;
137
+
94
138
  int ret_r = 0;
95
139
  int ret_w = 0;
96
140
  int ret_e = 0;
@@ -111,8 +155,31 @@ ZMQ_NOINLINE static int rb_czmq_loop_pollitem_callback(zloop_t *loop, zmq_pollit
111
155
  args[2] = rb_exc_new2(rb_eZmqError, zmq_strerror(zmq_errno()));
112
156
  ret_e = rb_czmq_callback(loop, args);
113
157
  }
114
- if (ret_r == -1 || ret_w == -1 || ret_e == -1) return -1;
115
- return 0;
158
+ if (ret_r == -1 || ret_w == -1 || ret_e == -1) {
159
+ invocation->result = -1;
160
+ } else {
161
+ invocation->result = 0;
162
+ }
163
+ return NULL;
164
+ }
165
+
166
+ /*
167
+ * :nodoc:
168
+ * Low level callback for handling socket activity. This calls back into the Ruby VM. We special case ZMQ_POLLERR
169
+ * by invoking the error callback on the handler registered for this socket.
170
+ *
171
+ * This is the CZMQ callback, which grabs the ruby GVL and calls the with GVL callback above.
172
+ */
173
+ ZMQ_NOINLINE static int rb_czmq_loop_pollitem_callback(zloop_t *loop, zmq_pollitem_t *item, void *arg)
174
+ {
175
+ struct _rb_czmq_callback_invocation invocation;
176
+ invocation.result = -1;
177
+ invocation.loop = loop;
178
+ invocation.item = item;
179
+ invocation.arg = arg;
180
+ invocation.args = NULL;
181
+ rb_thread_call_with_gvl(rb_czmq_loop_pollitem_callback_with_gvl, (void*)&invocation);
182
+ return invocation.result;
116
183
  }
117
184
 
118
185
  static void rb_czmq_loop_stop0(zmq_loop_wrapper *loop);
@@ -169,14 +236,45 @@ static VALUE rb_czmq_loop_new(VALUE loop)
169
236
  return loop;
170
237
  }
171
238
 
239
+ /*
240
+ * :nodoc:
241
+ * Run the zloop without holding the GVL.
242
+ *
243
+ */
244
+ static VALUE rb_czmq_loop_start_nogvl(void *ptr)
245
+ {
246
+ zmq_loop_wrapper *loop = (zmq_loop_wrapper *)ptr;
247
+ return (VALUE)zloop_start(loop->loop);
248
+ }
249
+
250
+ /*
251
+ * :nodoc:
252
+ * unblocking function: called by ruby when our zloop is running without
253
+ * gvl to tell it to stop and return back to ruby.
254
+ */
255
+ static void rb_czmq_loop_start_ubf(void* arg)
256
+ {
257
+ // this flag is set when an interrupt / signal would kill
258
+ // an application using czmq and allows loops to end gracefully.
259
+ // This will terminate all loops and pools in all threads.
260
+
261
+ // Without setting this, the CZMQ loop does not terminate when
262
+ // the user hits CTRL-C.
263
+ zctx_interrupted = true;
264
+
265
+ // do same as
266
+ zmq_loop_wrapper *loop_wrapper = arg;
267
+ loop_wrapper->running = false;
268
+ }
269
+
172
270
  /*
173
271
  * call-seq:
174
272
  * loop.start => Fixnum
175
273
  *
176
274
  * Creates a new reactor instance and blocks the caller until the process is interrupted, the context terminates or the
177
275
  * loop's explicitly stopped via callback. Returns 0 if interrupted and -1 when stopped via a handler.
178
- *
179
276
  * === Examples
277
+ *
180
278
  * loop = ZMQ::Loop.new => ZMQ::Loop
181
279
  * loop.start => Fixnum
182
280
  *
@@ -189,7 +287,9 @@ static VALUE rb_czmq_loop_start(VALUE obj)
189
287
  ZmqGetLoop(obj);
190
288
  THREAD_PASS;
191
289
  zloop_timer(loop->loop, 1, 1, rb_czmq_loop_started_callback, loop);
192
- rc = zloop_start(loop->loop);
290
+
291
+ rc = (int)rb_thread_call_without_gvl(rb_czmq_loop_start_nogvl, (void *)loop, rb_czmq_loop_start_ubf, (void*)loop);
292
+
193
293
  if (rc > 0) rb_raise(rb_eZmqError, "internal event loop error!");
194
294
  return INT2NUM(rc);
195
295
  }
@@ -26,4 +26,4 @@ struct nogvl_poll_args {
26
26
 
27
27
  void _init_rb_czmq_poller();
28
28
 
29
- #endif
29
+ #endif
@@ -26,4 +26,4 @@ VALUE rb_czmq_pollitem_events(VALUE obj);
26
26
 
27
27
  void _init_rb_czmq_pollitem();
28
28
 
29
- #endif
29
+ #endif
@@ -23,6 +23,7 @@ VALUE rb_cZmqLoop;
23
23
  VALUE rb_cZmqTimer;
24
24
  VALUE rb_cZmqPoller;
25
25
  VALUE rb_cZmqPollitem;
26
+ VALUE rb_cZmqBeacon;
26
27
 
27
28
  st_table *frames_map = NULL;
28
29
 
@@ -282,4 +283,5 @@ void Init_rbczmq_ext()
282
283
  _init_rb_czmq_loop();
283
284
  _init_rb_czmq_poller();
284
285
  _init_rb_czmq_pollitem();
286
+ _init_rb_czmq_beacon();
285
287
  }
@@ -67,6 +67,7 @@ extern VALUE rb_cZmqLoop;
67
67
  extern VALUE rb_cZmqTimer;
68
68
  extern VALUE rb_cZmqPoller;
69
69
  extern VALUE rb_cZmqPollitem;
70
+ extern VALUE rb_cZmqBeacon;
70
71
 
71
72
  extern st_table *frames_map;
72
73
 
@@ -83,6 +84,7 @@ extern VALUE intern_error;
83
84
  #include "timer.h"
84
85
  #include "poller.h"
85
86
  #include "pollitem.h"
87
+ #include "beacon.h"
86
88
 
87
89
  static inline char *rb_czmq_formatted_current_time()
88
90
  {
Binary file
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module ZMQ
4
- VERSION = "1.5"
4
+ VERSION = "1.6"
5
5
  end
metadata CHANGED
@@ -1,49 +1,42 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: rbczmq
3
- version: !ruby/object:Gem::Version
4
- hash: 5
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.6'
5
5
  prerelease:
6
- segments:
7
- - 1
8
- - 5
9
- version: "1.5"
10
6
  platform: ruby
11
- authors:
12
- - "Lourens Naud\xC3\xA9"
7
+ authors:
8
+ - Lourens Naudé
13
9
  - James Tucker
14
10
  autorequire:
15
11
  bindir: bin
16
12
  cert_chain: []
17
-
18
- date: 2013-04-29 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
13
+ date: 2013-05-02 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
21
16
  name: rake-compiler
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
17
+ requirement: !ruby/object:Gem::Requirement
24
18
  none: false
25
- requirements:
19
+ requirements:
26
20
  - - ~>
27
- - !ruby/object:Gem::Version
28
- hash: 63
29
- segments:
30
- - 0
31
- - 8
32
- - 0
21
+ - !ruby/object:Gem::Version
33
22
  version: 0.8.0
34
23
  type: :development
35
- version_requirements: *id001
36
- description: "Ruby extension for CZMQ - High-level C Binding for \xC3\x98MQ (http://czmq.zeromq.org)"
37
- email:
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ version: 0.8.0
31
+ description: Ruby extension for CZMQ - High-level C Binding for ØMQ (http://czmq.zeromq.org)
32
+ email:
38
33
  - lourens@methodmissing.com
39
34
  - jftucker@gmail.com
40
35
  executables: []
41
-
42
- extensions:
36
+ extensions:
43
37
  - ext/rbczmq/extconf.rb
44
38
  extra_rdoc_files: []
45
-
46
- files:
39
+ files:
47
40
  - .gitignore
48
41
  - .travis.yml
49
42
  - CHANGELOG.rdoc
@@ -57,8 +50,7 @@ files:
57
50
  - examples/pub_sub.rb
58
51
  - examples/push_pull.rb
59
52
  - examples/req_rep.rb
60
- - ext/czmq-1.3.2.tar.gz
61
- - ext/patches/czmq/0_zframe_free.patch
53
+ - ext/czmq-1.4.0.tar.gz
62
54
  - ext/rbczmq/context.c
63
55
  - ext/rbczmq/context.h
64
56
  - ext/rbczmq/extconf.rb
@@ -83,7 +75,7 @@ files:
83
75
  - ext/rbczmq/socket.h
84
76
  - ext/rbczmq/timer.c
85
77
  - ext/rbczmq/timer.h
86
- - ext/zeromq-3.2.2.tar.gz
78
+ - ext/zeromq-3.2.3.tar.gz
87
79
  - lib/rbczmq.rb
88
80
  - lib/zmq.rb
89
81
  - lib/zmq/context.rb
@@ -150,38 +142,30 @@ files:
150
142
  - test/test_zmq.rb
151
143
  homepage: http://github.com/methodmissing/rbczmq
152
144
  licenses: []
153
-
154
145
  post_install_message:
155
- rdoc_options:
146
+ rdoc_options:
156
147
  - --charset=UTF-8
157
- require_paths:
148
+ require_paths:
158
149
  - lib
159
- required_ruby_version: !ruby/object:Gem::Requirement
150
+ required_ruby_version: !ruby/object:Gem::Requirement
160
151
  none: false
161
- requirements:
162
- - - ">="
163
- - !ruby/object:Gem::Version
164
- hash: 3
165
- segments:
166
- - 0
167
- version: "0"
168
- required_rubygems_version: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - ! '>='
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ required_rubygems_version: !ruby/object:Gem::Requirement
169
157
  none: false
170
- requirements:
171
- - - ">="
172
- - !ruby/object:Gem::Version
173
- hash: 3
174
- segments:
175
- - 0
176
- version: "0"
158
+ requirements:
159
+ - - ! '>='
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
177
162
  requirements: []
178
-
179
163
  rubyforge_project:
180
- rubygems_version: 1.8.15
164
+ rubygems_version: 1.8.24
181
165
  signing_key:
182
166
  specification_version: 3
183
- summary: "Ruby extension for CZMQ - High-level C Binding for \xC3\x98MQ (http://czmq.zeromq.org)"
184
- test_files:
167
+ summary: Ruby extension for CZMQ - High-level C Binding for ØMQ (http://czmq.zeromq.org)
168
+ test_files:
185
169
  - test/helper.rb
186
170
  - test/socket/test_dealer_socket.rb
187
171
  - test/socket/test_pair_socket.rb
Binary file
@@ -1,78 +0,0 @@
1
- diff --git a/include/zframe.h b/include/zframe.h
2
- index e0e36c2..1b880d3 100644
3
- --- a/include/zframe.h
4
- +++ b/include/zframe.h
5
- @@ -116,6 +116,10 @@ CZMQ_EXPORT void
6
- CZMQ_EXPORT void
7
- zframe_reset (zframe_t *self, const void *data, size_t size);
8
-
9
- +// Set the free callback for frame
10
- +CZMQ_EXPORT void
11
- + zframe_freefn(zframe_t *self, zframe_free_fn *free_fn, void *arg);
12
- +
13
- // Self test of this class
14
- CZMQ_EXPORT int
15
- zframe_test (bool verbose);
16
- diff --git a/src/zframe.c b/src/zframe.c
17
- index edeec07..cf124ac 100644
18
- --- a/src/zframe.c
19
- +++ b/src/zframe.c
20
- @@ -49,6 +49,8 @@ struct _zframe_t {
21
- zmq_msg_t zmsg; // zmq_msg_t blob for frame
22
- int more; // More flag, from last read
23
- int zero_copy; // zero-copy flag
24
- + zframe_free_fn *free_fn; // destructor callback
25
- + void *free_arg; // destructor callback arg
26
- };
27
-
28
-
29
- @@ -116,6 +118,8 @@ zframe_destroy (zframe_t **self_p)
30
- assert (self_p);
31
- if (*self_p) {
32
- zframe_t *self = *self_p;
33
- + if (self->free_fn)
34
- + (self->free_fn) (self, self->free_arg);
35
- zmq_msg_close (&self->zmsg);
36
- free (self);
37
- *self_p = NULL;
38
- @@ -373,6 +377,16 @@ zframe_reset (zframe_t *self, const void *data, size_t size)
39
- memcpy (zmq_msg_data (&self->zmsg), data, size);
40
- }
41
-
42
- +void
43
- +zframe_freefn (zframe_t *self, zframe_free_fn *free_fn, void *arg)
44
- +{
45
- + assert (self);
46
- + assert (free_fn);
47
- +
48
- + self->free_fn = free_fn;
49
- + self->free_arg = arg;
50
- +}
51
- +
52
- // --------------------------------------------------------------------------
53
- // Selftest
54
-
55
- @@ -389,6 +403,12 @@ s_test_free_cb (void *data, void *arg)
56
- free (data);
57
- }
58
-
59
- +static void
60
- +s_test_free_frame_cb(void *frame, void *arg)
61
- +{
62
- + assert (frame);
63
- +}
64
- +
65
- int
66
- zframe_test (bool verbose)
67
- {
68
- @@ -472,6 +492,10 @@ zframe_test (bool verbose)
69
- zframe_destroy (&frame);
70
- zframe_destroy (&frame_copy);
71
-
72
- + frame = zframe_new ("callback", 8);
73
- + zframe_freefn (frame, s_test_free_frame_cb, NULL);
74
- + zframe_destroy (&frame);
75
- +
76
- zctx_destroy (&ctx);
77
- // @end
78
- printf ("OK\n");
Binary file