rbczmq 1.5 → 1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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