rbczmq 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +23 -0
- data/.travis.yml +19 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +19 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +247 -0
- data/Rakefile +67 -0
- data/examples/loop.rb +109 -0
- data/examples/poller.rb +37 -0
- data/examples/pub_sub.rb +101 -0
- data/examples/push_pull.rb +104 -0
- data/examples/req_rep.rb +100 -0
- data/ext/czmq.tar.gz +0 -0
- data/ext/rbczmq/context.c +280 -0
- data/ext/rbczmq/context.h +26 -0
- data/ext/rbczmq/extconf.rb +138 -0
- data/ext/rbczmq/frame.c +401 -0
- data/ext/rbczmq/frame.h +24 -0
- data/ext/rbczmq/jruby.h +22 -0
- data/ext/rbczmq/loop.c +413 -0
- data/ext/rbczmq/loop.h +24 -0
- data/ext/rbczmq/message.c +620 -0
- data/ext/rbczmq/message.h +24 -0
- data/ext/rbczmq/poller.c +308 -0
- data/ext/rbczmq/poller.h +29 -0
- data/ext/rbczmq/pollitem.c +251 -0
- data/ext/rbczmq/pollitem.h +25 -0
- data/ext/rbczmq/rbczmq_ext.c +198 -0
- data/ext/rbczmq/rbczmq_ext.h +94 -0
- data/ext/rbczmq/rbczmq_prelude.h +22 -0
- data/ext/rbczmq/rubinius.h +24 -0
- data/ext/rbczmq/ruby18.h +43 -0
- data/ext/rbczmq/ruby19.h +15 -0
- data/ext/rbczmq/socket.c +1570 -0
- data/ext/rbczmq/socket.h +136 -0
- data/ext/rbczmq/timer.c +110 -0
- data/ext/rbczmq/timer.h +23 -0
- data/ext/zeromq.tar.gz +0 -0
- data/lib/rbczmq.rb +3 -0
- data/lib/zmq.rb +77 -0
- data/lib/zmq/context.rb +50 -0
- data/lib/zmq/default_handler.rb +16 -0
- data/lib/zmq/frame.rb +11 -0
- data/lib/zmq/handler.rb +76 -0
- data/lib/zmq/loop.rb +131 -0
- data/lib/zmq/message.rb +9 -0
- data/lib/zmq/poller.rb +22 -0
- data/lib/zmq/pollitem.rb +31 -0
- data/lib/zmq/socket.rb +125 -0
- data/lib/zmq/socket/dealer.rb +33 -0
- data/lib/zmq/socket/pair.rb +39 -0
- data/lib/zmq/socket/pub.rb +30 -0
- data/lib/zmq/socket/pull.rb +29 -0
- data/lib/zmq/socket/push.rb +32 -0
- data/lib/zmq/socket/rep.rb +37 -0
- data/lib/zmq/socket/req.rb +37 -0
- data/lib/zmq/socket/router.rb +38 -0
- data/lib/zmq/socket/sub.rb +27 -0
- data/lib/zmq/timer.rb +12 -0
- data/lib/zmq/version.rb +5 -0
- data/perf/pair.rb +7 -0
- data/perf/pair/local.rb +22 -0
- data/perf/pair/remote.rb +25 -0
- data/perf/pub_sub.rb +7 -0
- data/perf/pub_sub/local.rb +22 -0
- data/perf/pub_sub/remote.rb +25 -0
- data/perf/push_pull.rb +7 -0
- data/perf/push_pull/local.rb +21 -0
- data/perf/push_pull/remote.rb +25 -0
- data/perf/req_rep.rb +7 -0
- data/perf/req_rep/local.rb +35 -0
- data/perf/req_rep/remote.rb +28 -0
- data/perf/runner.rb +142 -0
- data/rbczmq.gemspec +22 -0
- data/test/helper.rb +21 -0
- data/test/socket/test_dealer_socket.rb +14 -0
- data/test/socket/test_pair_socket.rb +24 -0
- data/test/socket/test_pair_sockets.rb +74 -0
- data/test/socket/test_pub_socket.rb +17 -0
- data/test/socket/test_pub_sub_sockets.rb +87 -0
- data/test/socket/test_pull_socket.rb +17 -0
- data/test/socket/test_push_pull_sockets.rb +81 -0
- data/test/socket/test_push_socket.rb +17 -0
- data/test/socket/test_rep_socket.rb +25 -0
- data/test/socket/test_req_rep_sockets.rb +42 -0
- data/test/socket/test_req_socket.rb +27 -0
- data/test/socket/test_router_socket.rb +14 -0
- data/test/socket/test_routing.rb +66 -0
- data/test/socket/test_sub_socket.rb +17 -0
- data/test/test_context.rb +86 -0
- data/test/test_frame.rb +78 -0
- data/test/test_handler.rb +28 -0
- data/test/test_loop.rb +252 -0
- data/test/test_message.rb +201 -0
- data/test/test_poller.rb +154 -0
- data/test/test_pollitem.rb +78 -0
- data/test/test_socket.rb +403 -0
- data/test/test_threading.rb +34 -0
- data/test/test_timer.rb +37 -0
- data/test/test_zmq.rb +62 -0
- metadata +208 -0
data/ext/rbczmq/frame.h
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#ifndef RBCZMQ_FRAME_H
|
2
|
+
#define RBCZMQ_FRAME_H
|
3
|
+
|
4
|
+
#define ZmqAssertFrame(obj) ZmqAssertType(obj, rb_cZmqFrame, "ZMQ::Frame")
|
5
|
+
#define ZmqGetFrame(obj) \
|
6
|
+
zframe_t *frame = NULL; \
|
7
|
+
ZmqAssertFrame(obj); \
|
8
|
+
Data_Get_Struct(obj, zframe_t, frame); \
|
9
|
+
if (!frame) rb_raise(rb_eTypeError, "uninitialized ZMQ frame!"); \
|
10
|
+
if (!(st_lookup(frames_map, (st_data_t)frame, 0))) rb_raise(rb_eZmqError, "ZMQ::Frame instance %p has been destroyed by the ZMQ framework", (void *)obj);
|
11
|
+
|
12
|
+
#define ZmqRegisterFrame(fr) \
|
13
|
+
zframe_freefn((fr), rb_czmq_frame_freed); \
|
14
|
+
st_insert(frames_map, (st_data_t)(fr), (st_data_t)0);
|
15
|
+
|
16
|
+
void rb_czmq_free_frame(zframe_t *frame);
|
17
|
+
void rb_czmq_free_frame_gc(void *ptr);
|
18
|
+
void rb_czmq_frame_freed(zframe_t *frame);
|
19
|
+
|
20
|
+
VALUE rb_czmq_alloc_frame(zframe_t *frame);
|
21
|
+
|
22
|
+
void _init_rb_czmq_frame();
|
23
|
+
|
24
|
+
#endif
|
data/ext/rbczmq/jruby.h
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#ifndef RBCZMQ_JRUBY_H
|
2
|
+
#define RBCZMQ_JRUBY_H
|
3
|
+
|
4
|
+
#include "st.h"
|
5
|
+
|
6
|
+
/* XXX */
|
7
|
+
#define ZmqEncode(str) str
|
8
|
+
#ifndef THREAD_PASS
|
9
|
+
#define THREAD_PASS rb_thread_schedule();
|
10
|
+
#endif
|
11
|
+
|
12
|
+
#define TRAP_BEG
|
13
|
+
#define TRAP_END
|
14
|
+
|
15
|
+
#undef rb_errinfo
|
16
|
+
#define rb_errinfo() (rb_gv_get("$!"))
|
17
|
+
|
18
|
+
#define ZMQ_DEFAULT_SOCKET_TIMEOUT Qnil
|
19
|
+
|
20
|
+
#define HAVE_RB_THREAD_BLOCKING_REGION 1
|
21
|
+
|
22
|
+
#endif
|
data/ext/rbczmq/loop.c
ADDED
@@ -0,0 +1,413 @@
|
|
1
|
+
#include <rbczmq_ext.h>
|
2
|
+
|
3
|
+
static VALUE intern_call;
|
4
|
+
static VALUE intern_readable;
|
5
|
+
static VALUE intern_writable;
|
6
|
+
static VALUE intern_error;
|
7
|
+
|
8
|
+
/*
|
9
|
+
* :nodoc:
|
10
|
+
* Wraps rb_funcall to support callbacks with or without callbacks.
|
11
|
+
*
|
12
|
+
*/
|
13
|
+
static VALUE rb_czmq_callback0(VALUE *args)
|
14
|
+
{
|
15
|
+
return (NIL_P(args[2])) ? rb_funcall(args[0], args[1], 0) : rb_funcall(args[0], args[1], 1, args[2]);
|
16
|
+
}
|
17
|
+
|
18
|
+
/*
|
19
|
+
* :nodoc:
|
20
|
+
* Callback for when the reactor started. Invoked from a a oneshot timer that fires after 1ms and updates the running
|
21
|
+
* member on the loop struct.
|
22
|
+
*
|
23
|
+
*/
|
24
|
+
ZMQ_NOINLINE static int rb_czmq_loop_started_callback(ZMQ_UNUSED zloop_t *loop, ZMQ_UNUSED zmq_pollitem_t *item, void *arg)
|
25
|
+
{
|
26
|
+
zmq_loop_wrapper *loop_wrapper = arg;
|
27
|
+
loop_wrapper->running = TRUE;
|
28
|
+
return 0;
|
29
|
+
}
|
30
|
+
|
31
|
+
/*
|
32
|
+
* :nodoc:
|
33
|
+
* Callback to signal / break the reactor loop. Triggered when we invoke ZMQ::Loop#stop. The -1 return will trickle down
|
34
|
+
* to libczmq and stop the event loop.
|
35
|
+
*
|
36
|
+
*/
|
37
|
+
ZMQ_NOINLINE static int rb_czmq_loop_breaker_callback(ZMQ_UNUSED zloop_t *loop, ZMQ_UNUSED zmq_pollitem_t *item, void *arg)
|
38
|
+
{
|
39
|
+
zmq_loop_wrapper *loop_wrapper = arg;
|
40
|
+
loop_wrapper->running = FALSE;
|
41
|
+
return -1;
|
42
|
+
}
|
43
|
+
|
44
|
+
/*
|
45
|
+
* :nodoc:
|
46
|
+
* Wraps calls back into the Ruby VM with rb_protect and properly bubbles up an errors to the user.
|
47
|
+
*
|
48
|
+
*/
|
49
|
+
ZMQ_NOINLINE static int rb_czmq_callback(zloop_t *loop, VALUE *args)
|
50
|
+
{
|
51
|
+
int status;
|
52
|
+
volatile VALUE ret;
|
53
|
+
status = 0;
|
54
|
+
ret = rb_protect((VALUE(*)(VALUE))rb_czmq_callback0, (VALUE)args, &status);
|
55
|
+
if (status) {
|
56
|
+
zloop_timer(loop, 1, 1, rb_czmq_loop_breaker_callback, (void *)args[0]);
|
57
|
+
if (NIL_P(rb_errinfo())) {
|
58
|
+
rb_jump_tag(status);
|
59
|
+
} else {
|
60
|
+
rb_funcall(args[0], intern_error, 1, rb_errinfo());
|
61
|
+
return 0;
|
62
|
+
}
|
63
|
+
} else if (ret == Qfalse) {
|
64
|
+
zloop_timer(loop, 1, 1, rb_czmq_loop_breaker_callback, (void *)args[0]);
|
65
|
+
return -1;
|
66
|
+
}
|
67
|
+
return 0;
|
68
|
+
}
|
69
|
+
|
70
|
+
/*
|
71
|
+
* :nodoc:
|
72
|
+
* Low level callback for when timers registered with the reactor fires. This calls back into the Ruby VM.
|
73
|
+
*
|
74
|
+
*/
|
75
|
+
ZMQ_NOINLINE static int rb_czmq_loop_timer_callback(zloop_t *loop, ZMQ_UNUSED zmq_pollitem_t *item, void *cb)
|
76
|
+
{
|
77
|
+
int rc;
|
78
|
+
VALUE args[3];
|
79
|
+
ZmqGetTimer((VALUE)cb);
|
80
|
+
if (timer->cancelled == TRUE) {
|
81
|
+
zloop_timer_end(loop, (void *)cb);
|
82
|
+
return 0;
|
83
|
+
}
|
84
|
+
args[0] = (VALUE)cb;
|
85
|
+
args[1] = intern_call;
|
86
|
+
args[2] = Qnil;
|
87
|
+
rc = rb_czmq_callback(loop, args);
|
88
|
+
return rc;
|
89
|
+
}
|
90
|
+
|
91
|
+
/*
|
92
|
+
* :nodoc:
|
93
|
+
* Low level callback for handling socket activity. This calls back into the Ruby VM. We special case ZMQ_POLLERR
|
94
|
+
* by invoking the error callback on the handler registered for this socket.
|
95
|
+
*
|
96
|
+
*/
|
97
|
+
ZMQ_NOINLINE static int rb_czmq_loop_pollitem_callback(zloop_t *loop, zmq_pollitem_t *item, void *arg)
|
98
|
+
{
|
99
|
+
int ret_r = 0;
|
100
|
+
int ret_w = 0;
|
101
|
+
int ret_e = 0;
|
102
|
+
VALUE args[3];
|
103
|
+
zmq_pollitem_wrapper *pollitem = (zmq_pollitem_wrapper *)arg;
|
104
|
+
args[0] = (VALUE)pollitem->handler;
|
105
|
+
args[2] = Qnil;
|
106
|
+
if (item->revents & ZMQ_POLLIN) {
|
107
|
+
args[1] = intern_readable;
|
108
|
+
ret_r = rb_czmq_callback(loop, args);
|
109
|
+
}
|
110
|
+
if (item->revents & ZMQ_POLLOUT) {
|
111
|
+
args[1] = intern_writable;
|
112
|
+
ret_w = rb_czmq_callback(loop, args);
|
113
|
+
}
|
114
|
+
if (item->revents & ZMQ_POLLERR) {
|
115
|
+
args[1] = intern_error;
|
116
|
+
args[2] = rb_exc_new2(rb_eZmqError, zmq_strerror(zmq_errno()));
|
117
|
+
ret_e = rb_czmq_callback(loop, args);
|
118
|
+
}
|
119
|
+
if (ret_r == -1 || ret_w == -1 || ret_e == -1) return -1;
|
120
|
+
return 0;
|
121
|
+
}
|
122
|
+
|
123
|
+
static void rb_czmq_loop_stop0(zmq_loop_wrapper *loop);
|
124
|
+
|
125
|
+
/*
|
126
|
+
* :nodoc:
|
127
|
+
* Free all resources for a reactor loop - invoked by the lower level ZMQ::Loop#destroy as well as the GC callback
|
128
|
+
*
|
129
|
+
*/
|
130
|
+
static void rb_czmq_free_loop(zmq_loop_wrapper *loop)
|
131
|
+
{
|
132
|
+
rb_czmq_loop_stop0(loop);
|
133
|
+
zloop_destroy(&(loop->loop));
|
134
|
+
loop->loop = NULL;
|
135
|
+
loop->flags |= ZMQ_LOOP_DESTROYED;
|
136
|
+
}
|
137
|
+
|
138
|
+
/*
|
139
|
+
* :nodoc:
|
140
|
+
* GC free callback
|
141
|
+
*
|
142
|
+
*/
|
143
|
+
static void rb_czmq_free_loop_gc(void *ptr)
|
144
|
+
{
|
145
|
+
zmq_loop_wrapper *loop = (zmq_loop_wrapper *)ptr;
|
146
|
+
if (loop) {
|
147
|
+
if (loop->loop != NULL && !(loop->flags & ZMQ_LOOP_DESTROYED)) rb_czmq_free_loop(loop);
|
148
|
+
xfree(loop);
|
149
|
+
}
|
150
|
+
}
|
151
|
+
|
152
|
+
/*
|
153
|
+
* call-seq:
|
154
|
+
* ZMQ::Loop.new => ZMQ::Loop
|
155
|
+
*
|
156
|
+
* Creates a new reactor instance. Several loops per process is supported for the lower level API.
|
157
|
+
*
|
158
|
+
* === Examples
|
159
|
+
* ZMQ::Loop.new => ZMQ::Loop
|
160
|
+
*
|
161
|
+
*/
|
162
|
+
|
163
|
+
static VALUE rb_czmq_loop_new(VALUE loop)
|
164
|
+
{
|
165
|
+
zmq_loop_wrapper *lp = NULL;
|
166
|
+
errno = 0;
|
167
|
+
loop = Data_Make_Struct(rb_cZmqLoop, zmq_loop_wrapper, 0, rb_czmq_free_loop_gc, lp);
|
168
|
+
lp->loop = zloop_new();
|
169
|
+
ZmqAssertObjOnAlloc(lp->loop, lp);
|
170
|
+
lp->flags = 0;
|
171
|
+
lp->running = FALSE;
|
172
|
+
lp->verbose = FALSE;
|
173
|
+
rb_obj_call_init(loop, 0, NULL);
|
174
|
+
return loop;
|
175
|
+
}
|
176
|
+
|
177
|
+
/*
|
178
|
+
* call-seq:
|
179
|
+
* loop.start => Fixnum
|
180
|
+
*
|
181
|
+
* Creates a new reactor instance and blocks the caller until the process is interrupted, the context terminates or the
|
182
|
+
* loop's explicitly stopped via callback. Returns 0 if interrupted and -1 when stopped via a handler.
|
183
|
+
*
|
184
|
+
* === Examples
|
185
|
+
* loop = ZMQ::Loop.new => ZMQ::Loop
|
186
|
+
* loop.start => Fixnum
|
187
|
+
*
|
188
|
+
*/
|
189
|
+
|
190
|
+
static VALUE rb_czmq_loop_start(VALUE obj)
|
191
|
+
{
|
192
|
+
int rc;
|
193
|
+
errno = 0;
|
194
|
+
ZmqGetLoop(obj);
|
195
|
+
THREAD_PASS;
|
196
|
+
zloop_timer(loop->loop, 1, 1, rb_czmq_loop_started_callback, loop);
|
197
|
+
rc = zloop_start(loop->loop);
|
198
|
+
if (rc > 0) rb_raise(rb_eZmqError, "internal event loop error!");
|
199
|
+
return INT2NUM(rc);
|
200
|
+
}
|
201
|
+
|
202
|
+
/*
|
203
|
+
* call-seq:
|
204
|
+
* loop.running? => boolean
|
205
|
+
*
|
206
|
+
* Predicate that returns true if the reactor is currently running.
|
207
|
+
*
|
208
|
+
* === Examples
|
209
|
+
* loop = ZMQ::Loop.new => ZMQ::Loop
|
210
|
+
* loop.running? => false
|
211
|
+
*
|
212
|
+
*/
|
213
|
+
|
214
|
+
static VALUE rb_czmq_loop_running_p(VALUE obj)
|
215
|
+
{
|
216
|
+
ZmqGetLoop(obj);
|
217
|
+
return (loop->running == TRUE) ? Qtrue : Qfalse;
|
218
|
+
}
|
219
|
+
|
220
|
+
/*
|
221
|
+
* :nodoc:
|
222
|
+
* Registers a oneshot timer that'll fire after 1msec to signal a loop break.
|
223
|
+
*
|
224
|
+
*/
|
225
|
+
static void rb_czmq_loop_stop0(zmq_loop_wrapper *loop)
|
226
|
+
{
|
227
|
+
zloop_timer(loop->loop, 1, 1, rb_czmq_loop_breaker_callback, loop);
|
228
|
+
}
|
229
|
+
|
230
|
+
/*
|
231
|
+
* call-seq:
|
232
|
+
* loop.stop => nil
|
233
|
+
*
|
234
|
+
* Stops the reactor loop. ZMQ::Loop#start will return a -1 status code as this can only be called via a handler.
|
235
|
+
*
|
236
|
+
* === Examples
|
237
|
+
* loop = ZMQ::Loop.new => ZMQ::Loop
|
238
|
+
* loop.add_timer(1){ loop.stop }
|
239
|
+
* loop.start => -1
|
240
|
+
*
|
241
|
+
*/
|
242
|
+
|
243
|
+
static VALUE rb_czmq_loop_stop(VALUE obj)
|
244
|
+
{
|
245
|
+
ZmqGetLoop(obj);
|
246
|
+
if (loop->running == FALSE) rb_raise(rb_eZmqError, "event loop not running!");
|
247
|
+
rb_czmq_loop_stop0(loop);
|
248
|
+
return Qnil;
|
249
|
+
}
|
250
|
+
|
251
|
+
/*
|
252
|
+
* call-seq:
|
253
|
+
* loop.destroy => nil
|
254
|
+
*
|
255
|
+
* Explicitly destroys a reactor instance. Useful for manual memory management, otherwise the GC
|
256
|
+
* will take the same action if a message object is not reachable anymore on the next GC cycle. This is
|
257
|
+
* a lower level API.
|
258
|
+
*
|
259
|
+
* === Examples
|
260
|
+
* loop = ZMQ::Loop.new => ZMQ::Loop
|
261
|
+
* loop.destroy => nil
|
262
|
+
*
|
263
|
+
*/
|
264
|
+
|
265
|
+
static VALUE rb_czmq_loop_destroy(VALUE obj)
|
266
|
+
{
|
267
|
+
ZmqGetLoop(obj);
|
268
|
+
rb_czmq_free_loop(loop);
|
269
|
+
return Qnil;
|
270
|
+
}
|
271
|
+
|
272
|
+
/*
|
273
|
+
* call-seq:
|
274
|
+
* loop.verbose = true => nil
|
275
|
+
*
|
276
|
+
* Logs reactor activity to stdout - useful for debugging, but can be quite noisy with lots of activity.
|
277
|
+
*
|
278
|
+
* === Examples
|
279
|
+
* loop = ZMQ::Loop.new => ZMQ::Loop
|
280
|
+
* loop.verbose = true => nil
|
281
|
+
*
|
282
|
+
*/
|
283
|
+
|
284
|
+
static VALUE rb_czmq_loop_set_verbose(VALUE obj, VALUE level)
|
285
|
+
{
|
286
|
+
Bool vlevel;
|
287
|
+
ZmqGetLoop(obj);
|
288
|
+
vlevel = (level == Qtrue) ? TRUE : FALSE;
|
289
|
+
zloop_set_verbose(loop->loop, vlevel);
|
290
|
+
loop->verbose = vlevel;
|
291
|
+
return Qnil;
|
292
|
+
}
|
293
|
+
|
294
|
+
/*
|
295
|
+
* call-seq:
|
296
|
+
* loop.register(item) => true
|
297
|
+
*
|
298
|
+
* Registers a poll item with the reactor. Only ZMQ::POLLIN and ZMQ::POLLOUT events are supported.
|
299
|
+
*
|
300
|
+
* === Examples
|
301
|
+
* loop = ZMQ::Loop.new => ZMQ::Loop
|
302
|
+
* item = ZMQ::Pollitem.new(sock, ZMQ::POLLIN) => ZMQ::Pollitem
|
303
|
+
* loop.register(item) => true
|
304
|
+
*
|
305
|
+
*/
|
306
|
+
|
307
|
+
static VALUE rb_czmq_loop_register(VALUE obj, VALUE pollable)
|
308
|
+
{
|
309
|
+
int rc;
|
310
|
+
errno = 0;
|
311
|
+
ZmqGetLoop(obj);
|
312
|
+
pollable = rb_czmq_pollitem_coerce(pollable);
|
313
|
+
ZmqGetPollitem(pollable);
|
314
|
+
rc = zloop_poller(loop->loop, pollitem->item, rb_czmq_loop_pollitem_callback, (void *)pollitem);
|
315
|
+
ZmqAssert(rc);
|
316
|
+
/* Let pollable be verbose if loop is verbose */
|
317
|
+
if (loop->verbose == TRUE) rb_czmq_pollitem_set_verbose(pollable, Qtrue);
|
318
|
+
return Qtrue;
|
319
|
+
}
|
320
|
+
|
321
|
+
/*
|
322
|
+
* call-seq:
|
323
|
+
* loop.remove(item) => nil
|
324
|
+
*
|
325
|
+
* Removes a previously registered poll item from the reactor loop.
|
326
|
+
*
|
327
|
+
* === Examples
|
328
|
+
* loop = ZMQ::Loop.new => ZMQ::Loop
|
329
|
+
* item = ZMQ::Pollitem.new(sock, ZMQ::POLLIN) => ZMQ::Pollitem
|
330
|
+
* loop.register(item) => true
|
331
|
+
* loop.remove(item) => nil
|
332
|
+
*
|
333
|
+
*/
|
334
|
+
|
335
|
+
static VALUE rb_czmq_loop_remove(VALUE obj, VALUE pollable)
|
336
|
+
{
|
337
|
+
errno = 0;
|
338
|
+
ZmqGetLoop(obj);
|
339
|
+
pollable = rb_czmq_pollitem_coerce(pollable);
|
340
|
+
ZmqGetPollitem(pollable);
|
341
|
+
zloop_poller_end(loop->loop, pollitem->item);
|
342
|
+
return Qnil;
|
343
|
+
}
|
344
|
+
|
345
|
+
/*
|
346
|
+
* call-seq:
|
347
|
+
* loop.register_timer(timer) => true
|
348
|
+
*
|
349
|
+
* Registers a ZMQ::Timer instance with the reactor.
|
350
|
+
*
|
351
|
+
* === Examples
|
352
|
+
* loop = ZMQ::Loop.new => ZMQ::Loop
|
353
|
+
* timer = ZMQ::Timer.new(1, 2){ :fired }
|
354
|
+
* loop.register_timer(timer) => true
|
355
|
+
*
|
356
|
+
*/
|
357
|
+
|
358
|
+
static VALUE rb_czmq_loop_register_timer(VALUE obj, VALUE tm)
|
359
|
+
{
|
360
|
+
int rc;
|
361
|
+
errno = 0;
|
362
|
+
ZmqGetLoop(obj);
|
363
|
+
ZmqGetTimer(tm);
|
364
|
+
rc = zloop_timer(loop->loop, timer->delay, timer->times, rb_czmq_loop_timer_callback, (void *)tm);
|
365
|
+
ZmqAssert(rc);
|
366
|
+
return Qtrue;
|
367
|
+
}
|
368
|
+
|
369
|
+
/*
|
370
|
+
* call-seq:
|
371
|
+
* loop.cancel_timer(timer) => nil
|
372
|
+
*
|
373
|
+
* Cancels a ZMQ::Timer instance previously registered with the reactor.
|
374
|
+
*
|
375
|
+
* === Examples
|
376
|
+
* loop = ZMQ::Loop.new => ZMQ::Loop
|
377
|
+
* timer = ZMQ::Timer.new(1, 2){ :fired }
|
378
|
+
* loop.register_timer(timer) => true
|
379
|
+
* loop.cancel_timer(timer) => nil
|
380
|
+
*
|
381
|
+
*/
|
382
|
+
|
383
|
+
static VALUE rb_czmq_loop_cancel_timer(VALUE obj, VALUE tm)
|
384
|
+
{
|
385
|
+
int rc;
|
386
|
+
errno = 0;
|
387
|
+
ZmqGetLoop(obj);
|
388
|
+
ZmqGetTimer(tm);
|
389
|
+
rc = zloop_timer_end(loop->loop, (void *)tm);
|
390
|
+
ZmqAssert(rc);
|
391
|
+
return Qtrue;
|
392
|
+
}
|
393
|
+
|
394
|
+
void _init_rb_czmq_loop()
|
395
|
+
{
|
396
|
+
intern_call = rb_intern("call");
|
397
|
+
intern_readable = rb_intern("on_readable");
|
398
|
+
intern_writable = rb_intern("on_writable");
|
399
|
+
intern_error = rb_intern("on_error");
|
400
|
+
|
401
|
+
rb_cZmqLoop = rb_define_class_under(rb_mZmq, "Loop", rb_cObject);
|
402
|
+
|
403
|
+
rb_define_alloc_func(rb_cZmqLoop, rb_czmq_loop_new);
|
404
|
+
rb_define_method(rb_cZmqLoop, "start", rb_czmq_loop_start, 0);
|
405
|
+
rb_define_method(rb_cZmqLoop, "stop", rb_czmq_loop_stop, 0);
|
406
|
+
rb_define_method(rb_cZmqLoop, "running?", rb_czmq_loop_running_p, 0);
|
407
|
+
rb_define_method(rb_cZmqLoop, "destroy", rb_czmq_loop_destroy, 0);
|
408
|
+
rb_define_method(rb_cZmqLoop, "verbose=", rb_czmq_loop_set_verbose, 1);
|
409
|
+
rb_define_method(rb_cZmqLoop, "register", rb_czmq_loop_register, 1);
|
410
|
+
rb_define_method(rb_cZmqLoop, "remove", rb_czmq_loop_remove, 1);
|
411
|
+
rb_define_method(rb_cZmqLoop, "register_timer", rb_czmq_loop_register_timer, 1);
|
412
|
+
rb_define_method(rb_cZmqLoop, "cancel_timer", rb_czmq_loop_cancel_timer, 1);
|
413
|
+
}
|