rbczmq 0.1
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/.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
@@ -0,0 +1,25 @@
|
|
1
|
+
#ifndef RBCZMQ_POLLITEM_H
|
2
|
+
#define RBCZMQ_POLLITEM_H
|
3
|
+
|
4
|
+
typedef struct {
|
5
|
+
VALUE socket;
|
6
|
+
VALUE io;
|
7
|
+
VALUE events;
|
8
|
+
VALUE handler;
|
9
|
+
zmq_pollitem_t *item;
|
10
|
+
} zmq_pollitem_wrapper;
|
11
|
+
|
12
|
+
#define ZmqAssertPollitem(obj) ZmqAssertType(obj, rb_cZmqPollitem, "ZMQ::Pollitem")
|
13
|
+
#define ZmqGetPollitem(obj) \
|
14
|
+
zmq_pollitem_wrapper *pollitem = NULL; \
|
15
|
+
ZmqAssertPollitem(obj); \
|
16
|
+
Data_Get_Struct(obj, zmq_pollitem_wrapper, pollitem); \
|
17
|
+
if (!pollitem) rb_raise(rb_eTypeError, "uninitialized ZMQ pollitem!");
|
18
|
+
|
19
|
+
VALUE rb_czmq_pollitem_coerce(VALUE pollable);
|
20
|
+
VALUE rb_czmq_pollitem_pollable(VALUE obj);
|
21
|
+
VALUE rb_czmq_pollitem_events(VALUE obj);
|
22
|
+
|
23
|
+
void _init_rb_czmq_pollitem();
|
24
|
+
|
25
|
+
#endif
|
@@ -0,0 +1,198 @@
|
|
1
|
+
#include <rbczmq_ext.h>
|
2
|
+
|
3
|
+
VALUE rb_mZmq;
|
4
|
+
VALUE rb_eZmqError;
|
5
|
+
VALUE rb_cZmqContext;
|
6
|
+
|
7
|
+
VALUE rb_cZmqSocket;
|
8
|
+
VALUE rb_cZmqPubSocket;
|
9
|
+
VALUE rb_cZmqSubSocket;
|
10
|
+
VALUE rb_cZmqPushSocket;
|
11
|
+
VALUE rb_cZmqPullSocket;
|
12
|
+
VALUE rb_cZmqRouterSocket;
|
13
|
+
VALUE rb_cZmqDealerSocket;
|
14
|
+
VALUE rb_cZmqRepSocket;
|
15
|
+
VALUE rb_cZmqReqSocket;
|
16
|
+
VALUE rb_cZmqPairSocket;
|
17
|
+
|
18
|
+
VALUE rb_cZmqFrame;
|
19
|
+
VALUE rb_cZmqMessage;
|
20
|
+
VALUE rb_cZmqLoop;
|
21
|
+
VALUE rb_cZmqTimer;
|
22
|
+
VALUE rb_cZmqPoller;
|
23
|
+
VALUE rb_cZmqPollitem;
|
24
|
+
|
25
|
+
st_table *frames_map = NULL;
|
26
|
+
|
27
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
28
|
+
rb_encoding *binary_encoding;
|
29
|
+
#endif
|
30
|
+
|
31
|
+
/*
|
32
|
+
* call-seq:
|
33
|
+
* ZMQ.interrupted? => boolean
|
34
|
+
*
|
35
|
+
* Returns true if the process was interrupted by signal.
|
36
|
+
*
|
37
|
+
* === Examples
|
38
|
+
* ZMQ.interrupted? => boolean
|
39
|
+
*
|
40
|
+
*/
|
41
|
+
|
42
|
+
static VALUE rb_czmq_m_interrupted_p(ZMQ_UNUSED VALUE obj)
|
43
|
+
{
|
44
|
+
return (zctx_interrupted == TRUE) ? Qtrue : Qfalse;
|
45
|
+
}
|
46
|
+
|
47
|
+
/*
|
48
|
+
* call-seq:
|
49
|
+
* ZMQ.version => Array
|
50
|
+
*
|
51
|
+
* Returns the libzmq version linked against.
|
52
|
+
*
|
53
|
+
* === Examples
|
54
|
+
* ZMQ.version => [2,1,11]
|
55
|
+
*
|
56
|
+
*/
|
57
|
+
|
58
|
+
static VALUE rb_czmq_m_version(ZMQ_UNUSED VALUE obj)
|
59
|
+
{
|
60
|
+
int major, minor, patch;
|
61
|
+
zmq_version(&major, &minor, &patch);
|
62
|
+
return rb_ary_new3(3, INT2NUM(major), INT2NUM(minor), INT2NUM(patch));
|
63
|
+
}
|
64
|
+
|
65
|
+
/*
|
66
|
+
* call-seq:
|
67
|
+
* ZMQ.now => Fixnum
|
68
|
+
*
|
69
|
+
* Returns a current timestamp as a Fixnum
|
70
|
+
*
|
71
|
+
* === Examples
|
72
|
+
* ZMQ.now => 1323206405148
|
73
|
+
*
|
74
|
+
*/
|
75
|
+
|
76
|
+
static VALUE rb_czmq_m_now(ZMQ_UNUSED VALUE obj)
|
77
|
+
{
|
78
|
+
return INT2NUM(zclock_time());
|
79
|
+
}
|
80
|
+
|
81
|
+
/*
|
82
|
+
* call-seq:
|
83
|
+
* ZMQ.log("msg") => nil
|
84
|
+
*
|
85
|
+
* Logs a timestamped message to stdout.
|
86
|
+
*
|
87
|
+
* === Examples
|
88
|
+
* ZMQ.log("msg") => nil # 11-12-06 21:20:55 msg
|
89
|
+
*
|
90
|
+
*/
|
91
|
+
|
92
|
+
static VALUE rb_czmq_m_log(ZMQ_UNUSED VALUE obj, VALUE msg)
|
93
|
+
{
|
94
|
+
Check_Type(msg, T_STRING);
|
95
|
+
zclock_log(StringValueCStr(msg));
|
96
|
+
return Qnil;
|
97
|
+
}
|
98
|
+
|
99
|
+
/*
|
100
|
+
* call-seq:
|
101
|
+
* ZMQ.error => ZMQ::Error
|
102
|
+
*
|
103
|
+
* Returns the last known ZMQ error (if any) as a ZMQ::Error instance.
|
104
|
+
*
|
105
|
+
* === Examples
|
106
|
+
* ZMQ.error => ZMQ::Error or nil
|
107
|
+
*
|
108
|
+
*/
|
109
|
+
|
110
|
+
static VALUE rb_czmq_m_error(ZMQ_UNUSED VALUE obj)
|
111
|
+
{
|
112
|
+
int err;
|
113
|
+
err = zmq_errno();
|
114
|
+
if (err == 0) return Qnil;
|
115
|
+
return rb_exc_new2(rb_eZmqError, zmq_strerror(zmq_errno()));
|
116
|
+
}
|
117
|
+
|
118
|
+
/*
|
119
|
+
* call-seq:
|
120
|
+
* ZMQ.errno => Fixnum
|
121
|
+
*
|
122
|
+
* Returns the last known ZMQ errno (if any) as a Fixnum.
|
123
|
+
*
|
124
|
+
* === Examples
|
125
|
+
* ZMQ.errno => 0
|
126
|
+
*
|
127
|
+
*/
|
128
|
+
|
129
|
+
static VALUE rb_czmq_m_errno(ZMQ_UNUSED VALUE obj)
|
130
|
+
{
|
131
|
+
return INT2NUM(zmq_errno());
|
132
|
+
}
|
133
|
+
|
134
|
+
/*
|
135
|
+
* call-seq:
|
136
|
+
* ZMQ.interrupted! => nil
|
137
|
+
*
|
138
|
+
* Callback for Ruby signal handlers for terminating blocking functions and the reactor loop in libczmq.
|
139
|
+
*
|
140
|
+
* === Examples
|
141
|
+
* ZMQ.interrupted! => nil
|
142
|
+
*
|
143
|
+
*/
|
144
|
+
|
145
|
+
static VALUE rb_czmq_m_interrupted_bang(ZMQ_UNUSED VALUE obj)
|
146
|
+
{
|
147
|
+
zctx_interrupted = 1;
|
148
|
+
return Qnil;
|
149
|
+
}
|
150
|
+
|
151
|
+
void Init_rbczmq_ext()
|
152
|
+
{
|
153
|
+
frames_map = st_init_numtable();
|
154
|
+
|
155
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
156
|
+
binary_encoding = rb_enc_find("binary");
|
157
|
+
#endif
|
158
|
+
|
159
|
+
rb_mZmq = rb_define_module("ZMQ");
|
160
|
+
|
161
|
+
rb_eZmqError = rb_define_class_under(rb_mZmq, "Error", rb_eStandardError);
|
162
|
+
|
163
|
+
rb_define_module_function(rb_mZmq, "interrupted?", rb_czmq_m_interrupted_p, 0);
|
164
|
+
rb_define_module_function(rb_mZmq, "version", rb_czmq_m_version, 0);
|
165
|
+
rb_define_module_function(rb_mZmq, "now", rb_czmq_m_now, 0);
|
166
|
+
rb_define_module_function(rb_mZmq, "log", rb_czmq_m_log, 1);
|
167
|
+
rb_define_module_function(rb_mZmq, "error", rb_czmq_m_error, 0);
|
168
|
+
rb_define_module_function(rb_mZmq, "errno", rb_czmq_m_errno, 0);
|
169
|
+
rb_define_module_function(rb_mZmq, "interrupted!", rb_czmq_m_interrupted_bang, 0);
|
170
|
+
|
171
|
+
rb_define_const(rb_mZmq, "POLLIN", INT2NUM(ZMQ_POLLIN));
|
172
|
+
rb_define_const(rb_mZmq, "POLLOUT", INT2NUM(ZMQ_POLLOUT));
|
173
|
+
rb_define_const(rb_mZmq, "POLLERR", INT2NUM(ZMQ_POLLERR));
|
174
|
+
|
175
|
+
rb_define_const(rb_mZmq, "PAIR", INT2NUM(ZMQ_PAIR));
|
176
|
+
rb_define_const(rb_mZmq, "SUB", INT2NUM(ZMQ_SUB));
|
177
|
+
rb_define_const(rb_mZmq, "PUB", INT2NUM(ZMQ_PUB));
|
178
|
+
rb_define_const(rb_mZmq, "REQ", INT2NUM(ZMQ_REQ));
|
179
|
+
rb_define_const(rb_mZmq, "REP", INT2NUM(ZMQ_REP));
|
180
|
+
rb_define_const(rb_mZmq, "DEALER", INT2NUM(ZMQ_DEALER));
|
181
|
+
rb_define_const(rb_mZmq, "ROUTER", INT2NUM(ZMQ_ROUTER));
|
182
|
+
rb_define_const(rb_mZmq, "PUSH", INT2NUM(ZMQ_PUSH));
|
183
|
+
rb_define_const(rb_mZmq, "PULL", INT2NUM(ZMQ_PULL));
|
184
|
+
|
185
|
+
rb_define_const(rb_mZmq, "EFSM", INT2NUM(EFSM));
|
186
|
+
rb_define_const(rb_mZmq, "ENOCOMPATPROTO", INT2NUM(ENOCOMPATPROTO));
|
187
|
+
rb_define_const(rb_mZmq, "ETERM", INT2NUM(ETERM));
|
188
|
+
rb_define_const(rb_mZmq, "EMTHREAD", INT2NUM(EMTHREAD));
|
189
|
+
|
190
|
+
_init_rb_czmq_context();
|
191
|
+
_init_rb_czmq_socket();
|
192
|
+
_init_rb_czmq_frame();
|
193
|
+
_init_rb_czmq_message();
|
194
|
+
_init_rb_czmq_timer();
|
195
|
+
_init_rb_czmq_loop();
|
196
|
+
_init_rb_czmq_poller();
|
197
|
+
_init_rb_czmq_pollitem();
|
198
|
+
}
|
@@ -0,0 +1,94 @@
|
|
1
|
+
#ifndef RBCZMQ_EXT_H
|
2
|
+
#define RBCZMQ_EXT_H
|
3
|
+
|
4
|
+
#include <czmq.h>
|
5
|
+
#include "ruby.h"
|
6
|
+
|
7
|
+
/* Compiler specific */
|
8
|
+
|
9
|
+
#if defined(__GNUC__) && (__GNUC__ >= 3)
|
10
|
+
#define ZMQ_UNUSED __attribute__ ((unused))
|
11
|
+
#define ZMQ_NOINLINE __attribute__ ((noinline))
|
12
|
+
#else
|
13
|
+
#define ZMQ_UNUSED
|
14
|
+
#define ZMQ_NOINLINE
|
15
|
+
#endif
|
16
|
+
|
17
|
+
#include <rbczmq_prelude.h>
|
18
|
+
|
19
|
+
#define ZmqRaiseSysError() { \
|
20
|
+
printf("Sys error location: %s:%d\n", __FILE__,__LINE__); \
|
21
|
+
rb_sys_fail(zmq_strerror(zmq_errno())); \
|
22
|
+
}
|
23
|
+
#define ZmqAssertSysError() if (zmq_errno() != 0 && zmq_errno() != EAGAIN) ZmqRaiseSysError();
|
24
|
+
#define ZmqAssert(rc) \
|
25
|
+
if (rc == -1) { \
|
26
|
+
ZmqAssertSysError(); \
|
27
|
+
if (rc == ENOMEM) rb_memerror(); \
|
28
|
+
return Qfalse; \
|
29
|
+
}
|
30
|
+
#define ZmqAssertObjOnAlloc(obj, wrapper) \
|
31
|
+
if (obj == NULL) { \
|
32
|
+
xfree(wrapper); \
|
33
|
+
ZmqAssertSysError(); \
|
34
|
+
rb_memerror(); \
|
35
|
+
}
|
36
|
+
#define ZmqAssertType(obj, type, desc) \
|
37
|
+
if (!rb_obj_is_kind_of(obj,type)) \
|
38
|
+
rb_raise(rb_eTypeError, "wrong argument type %s (expected %s): %s", rb_obj_classname(obj), desc, RSTRING_PTR(rb_obj_as_string(obj)));
|
39
|
+
|
40
|
+
extern VALUE rb_mZmq;
|
41
|
+
extern VALUE rb_eZmqError;
|
42
|
+
extern VALUE rb_cZmqContext;
|
43
|
+
|
44
|
+
extern VALUE rb_cZmqSocket;
|
45
|
+
extern VALUE rb_cZmqPubSocket;
|
46
|
+
extern VALUE rb_cZmqSubSocket;
|
47
|
+
extern VALUE rb_cZmqPushSocket;
|
48
|
+
extern VALUE rb_cZmqPullSocket;
|
49
|
+
extern VALUE rb_cZmqRouterSocket;
|
50
|
+
extern VALUE rb_cZmqDealerSocket;
|
51
|
+
extern VALUE rb_cZmqRepSocket;
|
52
|
+
extern VALUE rb_cZmqReqSocket;
|
53
|
+
extern VALUE rb_cZmqPairSocket;
|
54
|
+
|
55
|
+
extern VALUE rb_cZmqFrame;
|
56
|
+
extern VALUE rb_cZmqMessage;
|
57
|
+
extern VALUE rb_cZmqLoop;
|
58
|
+
extern VALUE rb_cZmqTimer;
|
59
|
+
extern VALUE rb_cZmqPoller;
|
60
|
+
extern VALUE rb_cZmqPollitem;
|
61
|
+
|
62
|
+
extern st_table *frames_map;
|
63
|
+
|
64
|
+
#include <context.h>
|
65
|
+
#include <socket.h>
|
66
|
+
#include <frame.h>
|
67
|
+
#include <message.h>
|
68
|
+
#include <loop.h>
|
69
|
+
#include <timer.h>
|
70
|
+
#include <poller.h>
|
71
|
+
#include <pollitem.h>
|
72
|
+
|
73
|
+
static inline char *rb_czmq_formatted_current_time()
|
74
|
+
{
|
75
|
+
time_t curtime = time (NULL);
|
76
|
+
struct tm *loctime = localtime(&curtime);
|
77
|
+
char *formatted;
|
78
|
+
formatted = (char*)xmalloc(20);
|
79
|
+
strftime(formatted, 20, "%y-%m-%d %H:%M:%S ", loctime);
|
80
|
+
return formatted;
|
81
|
+
}
|
82
|
+
|
83
|
+
struct nogvl_device_args {
|
84
|
+
int type;
|
85
|
+
#ifndef HAVE_RB_THREAD_BLOCKING_REGION
|
86
|
+
zctx_t *ctx;
|
87
|
+
#endif
|
88
|
+
zmq_sock_wrapper *in;
|
89
|
+
zmq_sock_wrapper *out;
|
90
|
+
int rc;
|
91
|
+
};
|
92
|
+
typedef struct nogvl_device_args nogvl_device_args_t;
|
93
|
+
|
94
|
+
#endif
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#ifndef RBCZMQ_PRELUDE_H
|
2
|
+
#define RBCZMQ_PRELUDE_H
|
3
|
+
|
4
|
+
#ifndef RFLOAT_VALUE
|
5
|
+
#define RFLOAT_VALUE(v) (RFLOAT(v)->value)
|
6
|
+
#endif
|
7
|
+
|
8
|
+
#ifdef RUBINIUS
|
9
|
+
#include <rubinius.h>
|
10
|
+
#else
|
11
|
+
#ifdef JRUBY
|
12
|
+
#include <jruby.h>
|
13
|
+
#else
|
14
|
+
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
|
15
|
+
#include <ruby19.h>
|
16
|
+
#else
|
17
|
+
#include <ruby18.h>
|
18
|
+
#endif
|
19
|
+
#endif
|
20
|
+
#endif
|
21
|
+
|
22
|
+
#endif
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#ifndef RBCZMQ_RUBINIUS_H
|
2
|
+
#define RBCZMQ_RUBINIUS_H
|
3
|
+
|
4
|
+
#define RSTRING_NOT_MODIFIED
|
5
|
+
|
6
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
7
|
+
#include <ruby/st.h>
|
8
|
+
#include <ruby/encoding.h>
|
9
|
+
#include <ruby/io.h>
|
10
|
+
extern rb_encoding *binary_encoding;
|
11
|
+
#define ZmqEncode(str) rb_enc_associate(str, binary_encoding)
|
12
|
+
#else
|
13
|
+
#include "st.h"
|
14
|
+
#define ZmqEncode(str) str
|
15
|
+
#endif
|
16
|
+
|
17
|
+
#define TRAP_BEG
|
18
|
+
#define TRAP_END
|
19
|
+
|
20
|
+
#define ZMQ_DEFAULT_SOCKET_TIMEOUT Qnil
|
21
|
+
|
22
|
+
#define THREAD_PASS rb_thread_schedule();
|
23
|
+
|
24
|
+
#endif
|
data/ext/rbczmq/ruby18.h
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
#ifndef RBCZMQ_RUBY18_H
|
2
|
+
#define RBCZMQ_RUBY18_H
|
3
|
+
|
4
|
+
#define THREAD_PASS rb_thread_schedule();
|
5
|
+
#define ZmqEncode(str) str
|
6
|
+
#include "rubyio.h"
|
7
|
+
#include "rubysig.h"
|
8
|
+
#include "st.h"
|
9
|
+
|
10
|
+
#ifndef RSTRING_PTR
|
11
|
+
#define RSTRING_PTR(str) RSTRING(str)->ptr
|
12
|
+
#endif
|
13
|
+
#ifndef RSTRING_LEN
|
14
|
+
#define RSTRING_LEN(s) (RSTRING(s)->len)
|
15
|
+
#endif
|
16
|
+
|
17
|
+
/*
|
18
|
+
* partial emulation of the 1.9 rb_thread_blocking_region under 1.8,
|
19
|
+
* this is enough for dealing with blocking I/O functions in the
|
20
|
+
* presence of threads.
|
21
|
+
*/
|
22
|
+
|
23
|
+
#define RUBY_UBF_IO ((rb_unblock_function_t *)-1)
|
24
|
+
typedef void rb_unblock_function_t(void *);
|
25
|
+
typedef VALUE rb_blocking_function_t(void *);
|
26
|
+
static VALUE
|
27
|
+
rb_thread_blocking_region(
|
28
|
+
rb_blocking_function_t *func, void *data1,
|
29
|
+
ZMQ_UNUSED rb_unblock_function_t *ubf,
|
30
|
+
ZMQ_UNUSED void *data2)
|
31
|
+
{
|
32
|
+
VALUE rv;
|
33
|
+
TRAP_BEG;
|
34
|
+
rv = func(data1);
|
35
|
+
TRAP_END;
|
36
|
+
return rv;
|
37
|
+
}
|
38
|
+
|
39
|
+
struct timeval rb_time_interval _((VALUE));
|
40
|
+
|
41
|
+
#define rb_errinfo() ruby_errinfo
|
42
|
+
|
43
|
+
#endif
|
data/ext/rbczmq/ruby19.h
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#ifndef RBCZMQ_RUBY19_H
|
2
|
+
#define RBCZMQ_RUBY19_H
|
3
|
+
|
4
|
+
#include <ruby/encoding.h>
|
5
|
+
#include <ruby/io.h>
|
6
|
+
extern rb_encoding *binary_encoding;
|
7
|
+
#define ZmqEncode(str) rb_enc_associate(str, binary_encoding)
|
8
|
+
#ifndef THREAD_PASS
|
9
|
+
#define THREAD_PASS rb_thread_schedule();
|
10
|
+
#endif
|
11
|
+
|
12
|
+
#define TRAP_BEG
|
13
|
+
#define TRAP_END
|
14
|
+
|
15
|
+
#endif
|
data/ext/rbczmq/socket.c
ADDED
@@ -0,0 +1,1570 @@
|
|
1
|
+
#include <rbczmq_ext.h>
|
2
|
+
|
3
|
+
/*
|
4
|
+
* :nodoc:
|
5
|
+
* Destroy the socket while the GIL is released - may block depending on socket linger value.
|
6
|
+
*
|
7
|
+
*/
|
8
|
+
static VALUE rb_czmq_nogvl_zsocket_destroy(void *ptr)
|
9
|
+
{
|
10
|
+
zmq_sock_wrapper *sock = ptr;
|
11
|
+
errno = 0;
|
12
|
+
zsocket_destroy(sock->ctx, sock->socket);
|
13
|
+
return Qnil;
|
14
|
+
}
|
15
|
+
|
16
|
+
/*
|
17
|
+
* :nodoc:
|
18
|
+
* Free all resources for a socket - invoked by the lower level ZMQ::Socket#destroy as well as the GC callback (some
|
19
|
+
* regressions here still though).
|
20
|
+
*
|
21
|
+
*/
|
22
|
+
void rb_czmq_free_sock(zmq_sock_wrapper *sock)
|
23
|
+
{
|
24
|
+
if (sock->ctx) {
|
25
|
+
rb_thread_blocking_region(rb_czmq_nogvl_zsocket_destroy, sock, RUBY_UBF_IO, 0);
|
26
|
+
if (zmq_errno() == ENOTSOCK) ZmqRaiseSysError();
|
27
|
+
sock->socket = NULL;
|
28
|
+
sock->flags |= ZMQ_SOCKET_DESTROYED;
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
/*
|
33
|
+
* :nodoc:
|
34
|
+
* GC mark callback
|
35
|
+
*
|
36
|
+
*/
|
37
|
+
void rb_czmq_mark_sock(void *ptr)
|
38
|
+
{
|
39
|
+
zmq_sock_wrapper *sock = (zmq_sock_wrapper *)ptr;
|
40
|
+
if (sock){
|
41
|
+
if (sock->verbose)
|
42
|
+
zclock_log ("I: %s socket %p, context %p: GC mark", zsocket_type_str(sock->socket), sock, sock->ctx);
|
43
|
+
rb_gc_mark(sock->endpoint);
|
44
|
+
rb_gc_mark(sock->thread);
|
45
|
+
rb_gc_mark(sock->recv_timeout);
|
46
|
+
rb_gc_mark(sock->send_timeout);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
/*
|
51
|
+
* :nodoc:
|
52
|
+
* GC free callback
|
53
|
+
*
|
54
|
+
*/
|
55
|
+
void rb_czmq_free_sock_gc(void *ptr)
|
56
|
+
{
|
57
|
+
zmq_sock_wrapper *sock = (zmq_sock_wrapper *)ptr;
|
58
|
+
if (sock){
|
59
|
+
if (sock->verbose)
|
60
|
+
zclock_log ("I: %s socket %p, context %p: GC free", zsocket_type_str(sock->socket), sock, sock->ctx);
|
61
|
+
/*
|
62
|
+
XXX: cyclic dependency
|
63
|
+
#4 0x0000000100712524 in zsockopt_set_linger (linger=1, socket=<value temporarily unavailable, due to optimizations>) at zsockopt.c:288
|
64
|
+
if (sock->socket != NULL && !(sock->flags & ZMQ_SOCKET_DESTROYED)) rb_czmq_free_sock(sock);
|
65
|
+
*/
|
66
|
+
#ifndef HAVE_RB_THREAD_BLOCKING_REGION
|
67
|
+
zlist_destroy(&(sock->str_buffer));
|
68
|
+
zlist_destroy(&(sock->frame_buffer));
|
69
|
+
zlist_destroy(&(sock->msg_buffer));
|
70
|
+
#endif
|
71
|
+
xfree(sock);
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
/*
|
76
|
+
* call-seq:
|
77
|
+
* sock.close => nil
|
78
|
+
*
|
79
|
+
* Closes a socket. The GC will take the same action if a socket object is not reachable anymore on the next GC cycle.
|
80
|
+
* This is a lower level API.
|
81
|
+
*
|
82
|
+
* === Examples
|
83
|
+
* sock.close => nil
|
84
|
+
*
|
85
|
+
*/
|
86
|
+
|
87
|
+
static VALUE rb_czmq_socket_close(VALUE obj)
|
88
|
+
{
|
89
|
+
zmq_sock_wrapper *sock = NULL;
|
90
|
+
GetZmqSocket(obj);
|
91
|
+
ZmqSockGuardCrossThread(sock);
|
92
|
+
/* This is useless for production / real use cases as we can't query the state again OR assume
|
93
|
+
anything about the underlying connection. Merely doing the right thing. */
|
94
|
+
sock->state = ZMQ_SOCKET_PENDING;
|
95
|
+
rb_czmq_free_sock(sock);
|
96
|
+
return Qnil;
|
97
|
+
}
|
98
|
+
|
99
|
+
/*
|
100
|
+
* call-seq:
|
101
|
+
* sock.endpoint => String or nil
|
102
|
+
*
|
103
|
+
* Returns the endpoint this socket is currently connected to, if any.
|
104
|
+
*
|
105
|
+
* === Examples
|
106
|
+
* ctx = ZMQ::Context.new
|
107
|
+
* sock = ctx.socket(:PUSH)
|
108
|
+
* sock.endpoint => nil
|
109
|
+
* sock.bind("inproc://test")
|
110
|
+
* sock.endpoint => "inproc://test"
|
111
|
+
*
|
112
|
+
*/
|
113
|
+
|
114
|
+
static VALUE rb_czmq_socket_endpoint(VALUE obj)
|
115
|
+
{
|
116
|
+
zmq_sock_wrapper *sock = NULL;
|
117
|
+
GetZmqSocket(obj);
|
118
|
+
return sock->endpoint;
|
119
|
+
}
|
120
|
+
|
121
|
+
/*
|
122
|
+
* call-seq:
|
123
|
+
* sock.state => String
|
124
|
+
*
|
125
|
+
* Returns the current socket state, one of ZMQ::Socket::PENDING, ZMQ::Socket::BOUND or ZMQ::Socket::CONNECTED
|
126
|
+
*
|
127
|
+
* === Examples
|
128
|
+
* ctx = ZMQ::Context.new
|
129
|
+
* sock = ctx.socket(:PUSH)
|
130
|
+
* sock.state => ZMQ::Socket::PENDING
|
131
|
+
* sock.bind("inproc://test")
|
132
|
+
* sock.state => ZMQ::Socket::BOUND
|
133
|
+
*
|
134
|
+
*/
|
135
|
+
|
136
|
+
static VALUE rb_czmq_socket_state(VALUE obj)
|
137
|
+
{
|
138
|
+
zmq_sock_wrapper *sock = NULL;
|
139
|
+
GetZmqSocket(obj);
|
140
|
+
return INT2NUM(sock->state);
|
141
|
+
}
|
142
|
+
|
143
|
+
/*
|
144
|
+
* call-seq:
|
145
|
+
* sock.fd => Fixnum
|
146
|
+
*
|
147
|
+
* Returns a file descriptor reference for integrating this socket with an externel event loop or multiplexor.
|
148
|
+
* Edge-triggered notification of I/O state changes.
|
149
|
+
*
|
150
|
+
* === Examples
|
151
|
+
* ctx = ZMQ::Context.new
|
152
|
+
* sock = ctx.socket(:PUSH)
|
153
|
+
* sock.fd => -1
|
154
|
+
* sock.bind("inproc://test")
|
155
|
+
* sock.fd => 4
|
156
|
+
*
|
157
|
+
*/
|
158
|
+
|
159
|
+
static VALUE rb_czmq_socket_fd(VALUE obj)
|
160
|
+
{
|
161
|
+
zmq_sock_wrapper *sock = NULL;
|
162
|
+
GetZmqSocket(obj);
|
163
|
+
if (sock->state == ZMQ_SOCKET_PENDING) return INT2NUM(-1);
|
164
|
+
return INT2NUM(zsockopt_fd(sock->socket));
|
165
|
+
}
|
166
|
+
|
167
|
+
/*
|
168
|
+
* :nodoc:
|
169
|
+
* Binds to an endpoint while the GIL is released.
|
170
|
+
*
|
171
|
+
*/
|
172
|
+
VALUE rb_czmq_nogvl_socket_bind(void *ptr)
|
173
|
+
{
|
174
|
+
int rc;
|
175
|
+
struct nogvl_conn_args *args = ptr;
|
176
|
+
errno = 0;
|
177
|
+
zmq_sock_wrapper *socket = args->socket;
|
178
|
+
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
|
179
|
+
rc = zsocket_bind(socket->socket, args->endpoint);
|
180
|
+
#else
|
181
|
+
rc = zsocket_bind(socket->socket, args->endpoint);
|
182
|
+
#endif
|
183
|
+
return (VALUE)rc;
|
184
|
+
}
|
185
|
+
|
186
|
+
/*
|
187
|
+
* :nodoc:
|
188
|
+
* Connects to an endpoint while the GIL is released.
|
189
|
+
*
|
190
|
+
*/
|
191
|
+
VALUE rb_czmq_nogvl_socket_connect(void *ptr)
|
192
|
+
{
|
193
|
+
int rc;
|
194
|
+
struct nogvl_conn_args *args = ptr;
|
195
|
+
errno = 0;
|
196
|
+
zmq_sock_wrapper *socket = args->socket;
|
197
|
+
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
|
198
|
+
rc = zsocket_connect(socket->socket, args->endpoint);
|
199
|
+
#else
|
200
|
+
rc = zsocket_connect(socket->socket, args->endpoint);
|
201
|
+
#endif
|
202
|
+
return (VALUE)rc;
|
203
|
+
}
|
204
|
+
|
205
|
+
/*
|
206
|
+
* call-seq:
|
207
|
+
* sock.bind("inproc://test") => Fixnum
|
208
|
+
*
|
209
|
+
* Binds to a given endpoint. When the port number is '*', attempts to bind to a free port. Always returns the port
|
210
|
+
* number on success.
|
211
|
+
*
|
212
|
+
* === Examples
|
213
|
+
* ctx = ZMQ::Context.new
|
214
|
+
* sock = ctx.socket(:PUSH)
|
215
|
+
* sock.bind("tcp://localhost:*") => 5432
|
216
|
+
*
|
217
|
+
*/
|
218
|
+
|
219
|
+
static VALUE rb_czmq_socket_bind(VALUE obj, VALUE endpoint)
|
220
|
+
{
|
221
|
+
struct nogvl_conn_args args;
|
222
|
+
int rc;
|
223
|
+
zmq_sock_wrapper *sock = NULL;
|
224
|
+
GetZmqSocket(obj);
|
225
|
+
ZmqSockGuardCrossThread(sock);
|
226
|
+
Check_Type(endpoint, T_STRING);
|
227
|
+
args.socket = sock;
|
228
|
+
args.endpoint = StringValueCStr(endpoint);
|
229
|
+
rc = (int)rb_thread_blocking_region(rb_czmq_nogvl_socket_bind, (void *)&args, RUBY_UBF_IO, 0);
|
230
|
+
if (rc == -1) ZmqRaiseSysError();
|
231
|
+
if (sock->verbose)
|
232
|
+
zclock_log ("I: %s socket %p: bound \"%s\"", zsocket_type_str(sock->socket), obj, StringValueCStr(endpoint));
|
233
|
+
sock->state = ZMQ_SOCKET_BOUND;
|
234
|
+
sock->endpoint = rb_str_new4(endpoint);
|
235
|
+
return INT2NUM(rc);
|
236
|
+
}
|
237
|
+
|
238
|
+
/*
|
239
|
+
* call-seq:
|
240
|
+
* sock.connect("tcp://localhost:3456") => boolean
|
241
|
+
*
|
242
|
+
* Attempts to connect to a given endpoint.
|
243
|
+
*
|
244
|
+
* === Examples
|
245
|
+
* ctx = ZMQ::Context.new
|
246
|
+
* rep = ctx.socket(:REP)
|
247
|
+
* port = rep.bind("tcp://localhost:*") => 5432
|
248
|
+
* req = ctx.socket(:REQ)
|
249
|
+
* req.connect("tcp://localhost:#{port}") => true
|
250
|
+
*
|
251
|
+
*/
|
252
|
+
|
253
|
+
static VALUE rb_czmq_socket_connect(VALUE obj, VALUE endpoint)
|
254
|
+
{
|
255
|
+
struct nogvl_conn_args args;
|
256
|
+
int rc;
|
257
|
+
zmq_sock_wrapper *sock = NULL;
|
258
|
+
GetZmqSocket(obj);
|
259
|
+
ZmqSockGuardCrossThread(sock);
|
260
|
+
Check_Type(endpoint, T_STRING);
|
261
|
+
args.socket = sock;
|
262
|
+
args.endpoint = StringValueCStr(endpoint);
|
263
|
+
rc = (int)rb_thread_blocking_region(rb_czmq_nogvl_socket_connect, (void *)&args, RUBY_UBF_IO, 0);
|
264
|
+
ZmqAssert(rc);
|
265
|
+
if (sock->verbose)
|
266
|
+
zclock_log ("I: %s socket %p: connected \"%s\"", zsocket_type_str(sock->socket), obj, StringValueCStr(endpoint));
|
267
|
+
sock->state = ZMQ_SOCKET_CONNECTED;
|
268
|
+
sock->endpoint = rb_str_new4(endpoint);
|
269
|
+
return Qtrue;
|
270
|
+
}
|
271
|
+
|
272
|
+
/*
|
273
|
+
* call-seq:
|
274
|
+
* sock.verbose = true => nil
|
275
|
+
*
|
276
|
+
* Let this socket be verbose - dumps a lot of data to stdout for debugging.
|
277
|
+
*
|
278
|
+
* === Examples
|
279
|
+
* ctx = ZMQ::Context.new
|
280
|
+
* sock = ctx.socket(:REP)
|
281
|
+
* sock.verbose = true => nil
|
282
|
+
*
|
283
|
+
*/
|
284
|
+
|
285
|
+
static VALUE rb_czmq_socket_set_verbose(VALUE obj, VALUE level)
|
286
|
+
{
|
287
|
+
Bool vlevel;
|
288
|
+
zmq_sock_wrapper *sock = NULL;
|
289
|
+
GetZmqSocket(obj);
|
290
|
+
vlevel = (level == Qtrue) ? TRUE : FALSE;
|
291
|
+
sock->verbose = vlevel;
|
292
|
+
return Qnil;
|
293
|
+
}
|
294
|
+
|
295
|
+
/*
|
296
|
+
* :nodoc:
|
297
|
+
* Sends a raw string while the GIL is released.
|
298
|
+
*
|
299
|
+
*/
|
300
|
+
static VALUE rb_czmq_nogvl_zstr_send(void *ptr)
|
301
|
+
{
|
302
|
+
struct nogvl_send_args *args = ptr;
|
303
|
+
errno = 0;
|
304
|
+
zmq_sock_wrapper *socket = args->socket;
|
305
|
+
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
|
306
|
+
return (VALUE)zstr_send(socket->socket, args->msg);
|
307
|
+
#else
|
308
|
+
if (rb_thread_alone()) return (VALUE)zstr_send_nowait(socket->socket, args->msg);
|
309
|
+
try_writable:
|
310
|
+
if ((zsockopt_events(socket->socket) & ZMQ_POLLOUT) == ZMQ_POLLOUT) {
|
311
|
+
return (VALUE)zstr_send_nowait(socket->socket, args->msg);
|
312
|
+
} else {
|
313
|
+
rb_thread_wait_fd(zsockopt_fd(socket->socket));
|
314
|
+
goto try_writable;
|
315
|
+
}
|
316
|
+
#endif
|
317
|
+
}
|
318
|
+
|
319
|
+
/*
|
320
|
+
* :nodoc:
|
321
|
+
* Sends a raw string with the multi flag set while the GIL is released.
|
322
|
+
*
|
323
|
+
*/
|
324
|
+
static VALUE rb_czmq_nogvl_zstr_sendm(void *ptr)
|
325
|
+
{
|
326
|
+
struct nogvl_send_args *args = ptr;
|
327
|
+
errno = 0;
|
328
|
+
zmq_sock_wrapper *socket = args->socket;
|
329
|
+
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
|
330
|
+
return (VALUE)zstr_sendm(socket->socket, args->msg);
|
331
|
+
#else
|
332
|
+
if (rb_thread_alone()) return (VALUE)zstr_sendm(socket->socket, args->msg);
|
333
|
+
try_writable:
|
334
|
+
if ((zsockopt_events(socket->socket) & ZMQ_POLLOUT) == ZMQ_POLLOUT) {
|
335
|
+
return (VALUE)zstr_sendm(socket->socket, args->msg);
|
336
|
+
} else {
|
337
|
+
rb_thread_wait_fd(zsockopt_fd(socket->socket));
|
338
|
+
goto try_writable;
|
339
|
+
}
|
340
|
+
#endif
|
341
|
+
}
|
342
|
+
|
343
|
+
/*
|
344
|
+
* call-seq:
|
345
|
+
* sock.send("message") => boolean
|
346
|
+
*
|
347
|
+
* Sends a string to this ZMQ socket.
|
348
|
+
*
|
349
|
+
* === Examples
|
350
|
+
* ctx = ZMQ::Context.new
|
351
|
+
* sock = ctx.socket(:REQ)
|
352
|
+
* sock.connect("inproc://test")
|
353
|
+
* sock.send("message") => true
|
354
|
+
*
|
355
|
+
*/
|
356
|
+
|
357
|
+
static VALUE rb_czmq_socket_send(VALUE obj, VALUE msg)
|
358
|
+
{
|
359
|
+
int rc;
|
360
|
+
struct nogvl_send_args args;
|
361
|
+
zmq_sock_wrapper *sock = NULL;
|
362
|
+
GetZmqSocket(obj);
|
363
|
+
ZmqAssertSocketNotPending(sock, "can only send on a bound or connected socket!");
|
364
|
+
ZmqSockGuardCrossThread(sock);
|
365
|
+
Check_Type(msg, T_STRING);
|
366
|
+
args.socket = sock;
|
367
|
+
args.msg = StringValueCStr(msg);
|
368
|
+
rc = (int)rb_thread_blocking_region(rb_czmq_nogvl_zstr_send, (void *)&args, RUBY_UBF_IO, 0);
|
369
|
+
ZmqAssert(rc);
|
370
|
+
if (sock->verbose)
|
371
|
+
zclock_log ("I: %s socket %p: send \"%s\"", zsocket_type_str(sock->socket), obj, StringValueCStr(msg));
|
372
|
+
return Qtrue;
|
373
|
+
}
|
374
|
+
|
375
|
+
/*
|
376
|
+
* call-seq:
|
377
|
+
* sock.sendm("message") => boolean
|
378
|
+
*
|
379
|
+
* Sends a string to this ZMQ socket, with a more flag set.
|
380
|
+
*
|
381
|
+
* === Examples
|
382
|
+
* ctx = ZMQ::Context.new
|
383
|
+
* sock = ctx.socket(:REQ)
|
384
|
+
* sock.connect("inproc://test")
|
385
|
+
* sock.sendm("mes") => true
|
386
|
+
* sock.sendm("sage") => true
|
387
|
+
*
|
388
|
+
*/
|
389
|
+
|
390
|
+
static VALUE rb_czmq_socket_sendm(VALUE obj, VALUE msg)
|
391
|
+
{
|
392
|
+
int rc;
|
393
|
+
struct nogvl_send_args args;
|
394
|
+
zmq_sock_wrapper *sock = NULL;
|
395
|
+
GetZmqSocket(obj);
|
396
|
+
ZmqAssertSocketNotPending(sock, "can only send on a bound or connected socket!");
|
397
|
+
ZmqSockGuardCrossThread(sock);
|
398
|
+
Check_Type(msg, T_STRING);
|
399
|
+
args.socket = sock;
|
400
|
+
args.msg = StringValueCStr(msg);
|
401
|
+
rc = (int)rb_thread_blocking_region(rb_czmq_nogvl_zstr_sendm, (void *)&args, RUBY_UBF_IO, 0);
|
402
|
+
ZmqAssert(rc);
|
403
|
+
if (sock->verbose)
|
404
|
+
zclock_log ("I: %s socket %p: sendm \"%s\"", zsocket_type_str(sock->socket), sock->socket, StringValueCStr(msg));
|
405
|
+
return Qtrue;
|
406
|
+
}
|
407
|
+
|
408
|
+
/*
|
409
|
+
* :nodoc:
|
410
|
+
* Receives a raw string while the GIL is released.
|
411
|
+
*
|
412
|
+
*/
|
413
|
+
static VALUE rb_czmq_nogvl_recv(void *ptr)
|
414
|
+
{
|
415
|
+
struct nogvl_recv_args *args = ptr;
|
416
|
+
errno = 0;
|
417
|
+
zmq_sock_wrapper *socket = args->socket;
|
418
|
+
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
|
419
|
+
return (VALUE)zstr_recv(socket->socket);
|
420
|
+
#else
|
421
|
+
if (zlist_size(socket->str_buffer) != 0)
|
422
|
+
return (VALUE)zlist_pop(socket->str_buffer);
|
423
|
+
try_readable:
|
424
|
+
if ((zsockopt_events(socket->socket) & ZMQ_POLLIN) == ZMQ_POLLIN) {
|
425
|
+
do {
|
426
|
+
zlist_append(socket->str_buffer, zstr_recv_nowait(socket->socket));
|
427
|
+
} while (zmq_errno() != EAGAIN && zmq_errno() != EINTR);
|
428
|
+
return (VALUE)zlist_pop(socket->str_buffer);
|
429
|
+
} else {
|
430
|
+
rb_thread_wait_fd(zsockopt_fd(socket->socket));
|
431
|
+
goto try_readable;
|
432
|
+
}
|
433
|
+
#endif
|
434
|
+
}
|
435
|
+
|
436
|
+
/*
|
437
|
+
* call-seq:
|
438
|
+
* sock.recv => String or nil
|
439
|
+
*
|
440
|
+
* Receive a string from this ZMQ socket. May block depending on the socket type.
|
441
|
+
*
|
442
|
+
* === Examples
|
443
|
+
* ctx = ZMQ::Context.new
|
444
|
+
* sock = ctx.socket(:REP)
|
445
|
+
* sock.bind("inproc://test")
|
446
|
+
* sock.recv => "message"
|
447
|
+
*
|
448
|
+
*/
|
449
|
+
|
450
|
+
static VALUE rb_czmq_socket_recv(VALUE obj)
|
451
|
+
{
|
452
|
+
char *str = NULL;
|
453
|
+
struct nogvl_recv_args args;
|
454
|
+
VALUE result = Qnil;
|
455
|
+
zmq_sock_wrapper *sock = NULL;
|
456
|
+
GetZmqSocket(obj);
|
457
|
+
ZmqAssertSocketNotPending(sock, "can only receive on a bound or connected socket!");
|
458
|
+
ZmqSockGuardCrossThread(sock);
|
459
|
+
args.socket = sock;
|
460
|
+
str = (char *)rb_thread_blocking_region(rb_czmq_nogvl_recv, (void *)&args, RUBY_UBF_IO, 0);
|
461
|
+
if (str == NULL) return result;
|
462
|
+
ZmqAssertSysError();
|
463
|
+
if (sock->verbose)
|
464
|
+
zclock_log ("I: %s socket %p: recv \"%s\"", zsocket_type_str(sock->socket), sock->socket, str);
|
465
|
+
result = ZmqEncode(rb_str_new2(str));
|
466
|
+
free(str);
|
467
|
+
return result;
|
468
|
+
}
|
469
|
+
|
470
|
+
/*
|
471
|
+
* call-seq:
|
472
|
+
* sock.recv_nonblock => String or nil
|
473
|
+
*
|
474
|
+
* Receive a string from this ZMQ socket. Does not block.
|
475
|
+
*
|
476
|
+
* === Examples
|
477
|
+
* ctx = ZMQ::Context.new
|
478
|
+
* sock = ctx.socket(:REP)
|
479
|
+
* sock.bind("inproc://test")
|
480
|
+
* sock.recv_nonblock => "message"
|
481
|
+
*
|
482
|
+
*/
|
483
|
+
|
484
|
+
static VALUE rb_czmq_socket_recv_nonblock(VALUE obj)
|
485
|
+
{
|
486
|
+
char *str = NULL;
|
487
|
+
errno = 0;
|
488
|
+
VALUE result = Qnil;
|
489
|
+
zmq_sock_wrapper *sock = NULL;
|
490
|
+
GetZmqSocket(obj);
|
491
|
+
ZmqAssertSocketNotPending(sock, "can only receive on a bound or connected socket!");
|
492
|
+
ZmqSockGuardCrossThread(sock);
|
493
|
+
str = zstr_recv_nowait(sock->socket);
|
494
|
+
if (str == NULL) return result;
|
495
|
+
ZmqAssertSysError();
|
496
|
+
if (sock->verbose)
|
497
|
+
zclock_log ("I: %s socket %p: recv_nonblock \"%s\"", zsocket_type_str(sock->socket), sock->socket, str);
|
498
|
+
result = ZmqEncode(rb_str_new2(str));
|
499
|
+
free(str);
|
500
|
+
return result;
|
501
|
+
}
|
502
|
+
|
503
|
+
/*
|
504
|
+
* :nodoc:
|
505
|
+
* Sends a frame while the GIL is released.
|
506
|
+
*
|
507
|
+
*/
|
508
|
+
static VALUE rb_czmq_nogvl_send_frame(void *ptr)
|
509
|
+
{
|
510
|
+
struct nogvl_send_frame_args *args = ptr;
|
511
|
+
errno = 0;
|
512
|
+
zmq_sock_wrapper *socket = args->socket;
|
513
|
+
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
|
514
|
+
return (VALUE)zframe_send(&(args->frame), socket->socket, args->flags);
|
515
|
+
#else
|
516
|
+
if (rb_thread_alone()) return (VALUE)zframe_send(&(args->frame), socket->socket, args->flags);
|
517
|
+
try_writable:
|
518
|
+
if ((zsockopt_events(socket->socket) & ZMQ_POLLOUT) == ZMQ_POLLOUT) {
|
519
|
+
return (VALUE)zframe_send(&(args->frame), socket->socket, args->flags);
|
520
|
+
} else {
|
521
|
+
rb_thread_wait_fd(zsockopt_fd(socket->socket));
|
522
|
+
goto try_writable;
|
523
|
+
}
|
524
|
+
#endif
|
525
|
+
}
|
526
|
+
|
527
|
+
/*
|
528
|
+
* call-seq:
|
529
|
+
* sock.send_frame(frame) => nil
|
530
|
+
*
|
531
|
+
* Sends a ZMQ::Frame instance to this socket.
|
532
|
+
*
|
533
|
+
* === Examples
|
534
|
+
* ctx = ZMQ::Context.new
|
535
|
+
* sock = ctx.socket(:REP)
|
536
|
+
* sock.bind("inproc://test")
|
537
|
+
* frame = ZMQ::Frame("frame")
|
538
|
+
* sock.send_frame(frame) => nil
|
539
|
+
* frame = ZMQ::Frame("multi")
|
540
|
+
* sock.send_frame(frame, ZMQ::Frame::MORE)
|
541
|
+
*
|
542
|
+
*/
|
543
|
+
|
544
|
+
static VALUE rb_czmq_socket_send_frame(int argc, VALUE *argv, VALUE obj)
|
545
|
+
{
|
546
|
+
struct nogvl_send_frame_args args;
|
547
|
+
VALUE frame_obj;
|
548
|
+
VALUE flags;
|
549
|
+
char print_prefix[255];
|
550
|
+
char *cur_time = NULL;
|
551
|
+
zframe_t *print_frame = NULL;
|
552
|
+
int rc, flgs;
|
553
|
+
zmq_sock_wrapper *sock = NULL;
|
554
|
+
GetZmqSocket(obj);
|
555
|
+
ZmqAssertSocketNotPending(sock, "can only send on a bound or connected socket!");
|
556
|
+
ZmqSockGuardCrossThread(sock);
|
557
|
+
rb_scan_args(argc, argv, "11", &frame_obj, &flags);
|
558
|
+
ZmqGetFrame(frame_obj);
|
559
|
+
|
560
|
+
if (NIL_P(flags)) {
|
561
|
+
flgs = 0;
|
562
|
+
} else {
|
563
|
+
if (SYMBOL_P(flags)) flags = rb_const_get_at(rb_cZmqFrame, rb_to_id(flags));
|
564
|
+
Check_Type(flags, T_FIXNUM);
|
565
|
+
flgs = FIX2INT(flags);
|
566
|
+
}
|
567
|
+
|
568
|
+
if (sock->verbose) {
|
569
|
+
cur_time = rb_czmq_formatted_current_time();
|
570
|
+
print_frame = (flgs & ZFRAME_REUSE) ? frame : zframe_dup(frame);
|
571
|
+
}
|
572
|
+
args.socket = sock;
|
573
|
+
args.frame = frame;
|
574
|
+
args.flags = flgs;
|
575
|
+
rc = (int)rb_thread_blocking_region(rb_czmq_nogvl_send_frame, (void *)&args, RUBY_UBF_IO, 0);
|
576
|
+
ZmqAssert(rc);
|
577
|
+
if (sock->verbose) ZmqDumpFrame("send_frame", print_frame);
|
578
|
+
return Qtrue;
|
579
|
+
}
|
580
|
+
|
581
|
+
/*
|
582
|
+
* :nodoc:
|
583
|
+
* Sends a message while the GIL is released.
|
584
|
+
*
|
585
|
+
*/
|
586
|
+
static VALUE rb_czmq_nogvl_send_message(void *ptr)
|
587
|
+
{
|
588
|
+
struct nogvl_send_message_args *args = ptr;
|
589
|
+
zmq_sock_wrapper *socket = args->socket;
|
590
|
+
errno = 0;
|
591
|
+
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
|
592
|
+
zmsg_send(&(args->message), socket->socket);
|
593
|
+
#else
|
594
|
+
if (rb_thread_alone()) {
|
595
|
+
zmsg_send(&(args->message), socket->socket);
|
596
|
+
return Qnil;
|
597
|
+
}
|
598
|
+
try_writable:
|
599
|
+
if ((zsockopt_events(socket->socket) & ZMQ_POLLOUT) == ZMQ_POLLOUT) {
|
600
|
+
zmsg_send(&(args->message), socket->socket);
|
601
|
+
} else {
|
602
|
+
rb_thread_wait_fd(zsockopt_fd(socket->socket));
|
603
|
+
goto try_writable;
|
604
|
+
}
|
605
|
+
#endif
|
606
|
+
return Qnil;
|
607
|
+
}
|
608
|
+
|
609
|
+
/*
|
610
|
+
* call-seq:
|
611
|
+
* sock.send_message(msg) => nil
|
612
|
+
*
|
613
|
+
* Sends a ZMQ::Message instance to this socket.
|
614
|
+
*
|
615
|
+
* === Examples
|
616
|
+
* ctx = ZMQ::Context.new
|
617
|
+
* sock = ctx.socket(:REP)
|
618
|
+
* sock.bind("inproc://test")
|
619
|
+
* msg = ZMQ::Message.new
|
620
|
+
* msg.push ZMQ::Frame("header")
|
621
|
+
* sock.send_message(msg) => nil
|
622
|
+
*
|
623
|
+
*/
|
624
|
+
|
625
|
+
static VALUE rb_czmq_socket_send_message(VALUE obj, VALUE message_obj)
|
626
|
+
{
|
627
|
+
struct nogvl_send_message_args args;
|
628
|
+
zmsg_t *print_message = NULL;
|
629
|
+
zmq_sock_wrapper *sock = NULL;
|
630
|
+
GetZmqSocket(obj);
|
631
|
+
ZmqAssertSocketNotPending(sock, "can only send on a bound or connected socket!");
|
632
|
+
ZmqSockGuardCrossThread(sock);
|
633
|
+
ZmqGetMessage(message_obj);
|
634
|
+
if (sock->verbose) print_message = zmsg_dup(message->message);
|
635
|
+
args.socket = sock;
|
636
|
+
args.message = message->message;
|
637
|
+
rb_thread_blocking_region(rb_czmq_nogvl_send_message, (void *)&args, RUBY_UBF_IO, 0);
|
638
|
+
message->flags |= ZMQ_MESSAGE_DESTROYED;
|
639
|
+
if (sock->verbose) ZmqDumpMessage("send_message", print_message);
|
640
|
+
return Qnil;
|
641
|
+
}
|
642
|
+
|
643
|
+
/*
|
644
|
+
* :nodoc:
|
645
|
+
* Receives a frame while the GIL is released.
|
646
|
+
*
|
647
|
+
*/
|
648
|
+
static VALUE rb_czmq_nogvl_recv_frame(void *ptr)
|
649
|
+
{
|
650
|
+
struct nogvl_recv_args *args = ptr;
|
651
|
+
errno = 0;
|
652
|
+
zmq_sock_wrapper *socket = args->socket;
|
653
|
+
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
|
654
|
+
return (VALUE)zframe_recv(socket->socket);
|
655
|
+
#else
|
656
|
+
if (zlist_size(socket->frame_buffer) != 0)
|
657
|
+
return (VALUE)zlist_pop(socket->frame_buffer);
|
658
|
+
try_readable:
|
659
|
+
if ((zsockopt_events(socket->socket) & ZMQ_POLLIN) == ZMQ_POLLIN) {
|
660
|
+
do {
|
661
|
+
zlist_append(socket->frame_buffer, zframe_recv_nowait(socket->socket));
|
662
|
+
} while (zmq_errno() != EAGAIN && zmq_errno() != EINTR);
|
663
|
+
return (VALUE)zlist_pop(socket->frame_buffer);
|
664
|
+
} else {
|
665
|
+
rb_thread_wait_fd(zsockopt_fd(socket->socket));
|
666
|
+
goto try_readable;
|
667
|
+
}
|
668
|
+
#endif
|
669
|
+
}
|
670
|
+
|
671
|
+
/*
|
672
|
+
* call-seq:
|
673
|
+
* sock.recv_frame => ZMQ::Frame or nil
|
674
|
+
*
|
675
|
+
* Receives a ZMQ frame from this socket.
|
676
|
+
*
|
677
|
+
* === Examples
|
678
|
+
* ctx = ZMQ::Context.new
|
679
|
+
* sock = ctx.socket(:REP)
|
680
|
+
* sock.bind("inproc://test")
|
681
|
+
* sock.recv_frame => ZMQ::Frame or nil
|
682
|
+
*
|
683
|
+
*/
|
684
|
+
|
685
|
+
static VALUE rb_czmq_socket_recv_frame(VALUE obj)
|
686
|
+
{
|
687
|
+
zframe_t *frame = NULL;
|
688
|
+
struct nogvl_recv_args args;
|
689
|
+
char print_prefix[255];
|
690
|
+
char *cur_time = NULL;
|
691
|
+
zmq_sock_wrapper *sock = NULL;
|
692
|
+
GetZmqSocket(obj);
|
693
|
+
ZmqAssertSocketNotPending(sock, "can only receive on a bound or connected socket!");
|
694
|
+
ZmqSockGuardCrossThread(sock);
|
695
|
+
args.socket = sock;
|
696
|
+
frame = (zframe_t *)rb_thread_blocking_region(rb_czmq_nogvl_recv_frame, (void *)&args, RUBY_UBF_IO, 0);
|
697
|
+
if (frame == NULL) return Qnil;
|
698
|
+
if (sock->verbose) {
|
699
|
+
cur_time = rb_czmq_formatted_current_time();
|
700
|
+
ZmqDumpFrame("recv_frame", frame);
|
701
|
+
}
|
702
|
+
return rb_czmq_alloc_frame(frame);
|
703
|
+
}
|
704
|
+
|
705
|
+
/*
|
706
|
+
* call-seq:
|
707
|
+
* sock.recv_frame_nonblock => ZMQ::Frame or nil
|
708
|
+
*
|
709
|
+
* Receives a ZMQ frame from this socket. Does not block
|
710
|
+
*
|
711
|
+
* === Examples
|
712
|
+
* ctx = ZMQ::Context.new
|
713
|
+
* sock = ctx.socket(:REP)
|
714
|
+
* sock.bind("inproc://test")
|
715
|
+
* sock.recv_frame_nonblock => ZMQ::Frame or nil
|
716
|
+
*
|
717
|
+
*/
|
718
|
+
|
719
|
+
static VALUE rb_czmq_socket_recv_frame_nonblock(VALUE obj)
|
720
|
+
{
|
721
|
+
zframe_t *frame = NULL;
|
722
|
+
char print_prefix[255];
|
723
|
+
char *cur_time = NULL;
|
724
|
+
errno = 0;
|
725
|
+
zmq_sock_wrapper *sock = NULL;
|
726
|
+
GetZmqSocket(obj);
|
727
|
+
ZmqAssertSocketNotPending(sock, "can only receive on a bound or connected socket!");
|
728
|
+
ZmqSockGuardCrossThread(sock);
|
729
|
+
frame = zframe_recv_nowait(sock->socket);
|
730
|
+
if (frame == NULL) return Qnil;
|
731
|
+
if (sock->verbose) {
|
732
|
+
cur_time = rb_czmq_formatted_current_time();
|
733
|
+
ZmqDumpFrame("recv_frame_nonblock", frame);
|
734
|
+
}
|
735
|
+
return rb_czmq_alloc_frame(frame);
|
736
|
+
}
|
737
|
+
|
738
|
+
/*
|
739
|
+
* :nodoc:
|
740
|
+
* Receives a message while the GIL is released.
|
741
|
+
*
|
742
|
+
*/
|
743
|
+
static VALUE rb_czmq_nogvl_recv_message(void *ptr)
|
744
|
+
{
|
745
|
+
struct nogvl_recv_args *args = ptr;
|
746
|
+
errno = 0;
|
747
|
+
zmq_sock_wrapper *socket = args->socket;
|
748
|
+
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
|
749
|
+
return (VALUE)zmsg_recv(socket->socket);
|
750
|
+
#else
|
751
|
+
if (zlist_size(socket->msg_buffer) != 0)
|
752
|
+
return (VALUE)zlist_pop(socket->msg_buffer);
|
753
|
+
try_readable:
|
754
|
+
if ((zsockopt_events(socket->socket) & ZMQ_POLLIN) == ZMQ_POLLIN) {
|
755
|
+
do {
|
756
|
+
zlist_append(socket->msg_buffer, zmsg_recv(socket->socket));
|
757
|
+
} while (zmq_errno() != EAGAIN && zmq_errno() != EINTR);
|
758
|
+
return (VALUE)zlist_pop(socket->msg_buffer);
|
759
|
+
} else {
|
760
|
+
rb_thread_wait_fd(zsockopt_fd(socket->socket));
|
761
|
+
goto try_readable;
|
762
|
+
}
|
763
|
+
#endif
|
764
|
+
}
|
765
|
+
|
766
|
+
/*
|
767
|
+
* call-seq:
|
768
|
+
* sock.recv_message => ZMQ::Message or nil
|
769
|
+
*
|
770
|
+
* Receives a ZMQ message from this socket.
|
771
|
+
*
|
772
|
+
* === Examples
|
773
|
+
* ctx = ZMQ::Context.new
|
774
|
+
* sock = ctx.socket(:REP)
|
775
|
+
* sock.bind("inproc://test")
|
776
|
+
* sock.recv_message => ZMQ::Message or nil
|
777
|
+
*
|
778
|
+
*/
|
779
|
+
|
780
|
+
static VALUE rb_czmq_socket_recv_message(VALUE obj)
|
781
|
+
{
|
782
|
+
zmsg_t *message = NULL;
|
783
|
+
struct nogvl_recv_args args;
|
784
|
+
zmq_sock_wrapper *sock = NULL;
|
785
|
+
GetZmqSocket(obj);
|
786
|
+
ZmqAssertSocketNotPending(sock, "can only receive on a bound or connected socket!");
|
787
|
+
ZmqSockGuardCrossThread(sock);
|
788
|
+
args.socket = sock;
|
789
|
+
message = (zmsg_t *)rb_thread_blocking_region(rb_czmq_nogvl_recv_message, (void *)&args, RUBY_UBF_IO, 0);
|
790
|
+
if (message == NULL) return Qnil;
|
791
|
+
if (sock->verbose) ZmqDumpMessage("recv_message", message);
|
792
|
+
return rb_czmq_alloc_message(message);
|
793
|
+
}
|
794
|
+
|
795
|
+
/*
|
796
|
+
* call-seq:
|
797
|
+
* sock.recv_timeout = 5 => nil
|
798
|
+
*
|
799
|
+
* Sets a receive timeout for this socket.
|
800
|
+
*
|
801
|
+
* === Examples
|
802
|
+
* ctx = ZMQ::Context.new
|
803
|
+
* sock = ctx.socket(:REP)
|
804
|
+
* sock.recv_timeout = 5 => nil
|
805
|
+
*
|
806
|
+
*/
|
807
|
+
|
808
|
+
static VALUE rb_czmq_socket_set_recv_timeout(VALUE obj, VALUE timeout)
|
809
|
+
{
|
810
|
+
zmq_sock_wrapper *sock = NULL;
|
811
|
+
GetZmqSocket(obj);
|
812
|
+
if (TYPE(timeout) != T_FIXNUM && TYPE(timeout) != T_FLOAT) rb_raise(rb_eTypeError, "wrong timeout type %s (expected Fixnum or Float)", RSTRING_PTR(rb_obj_as_string(timeout)));
|
813
|
+
sock->recv_timeout = timeout;
|
814
|
+
return Qnil;
|
815
|
+
}
|
816
|
+
|
817
|
+
/*
|
818
|
+
* call-seq:
|
819
|
+
* sock.recv_timeout => Fixnum or nil
|
820
|
+
*
|
821
|
+
* Returns the recv timeout currently associated with this socket.
|
822
|
+
*
|
823
|
+
* === Examples
|
824
|
+
* ctx = ZMQ::Context.new
|
825
|
+
* sock = ctx.socket(:REP)
|
826
|
+
* sock.recv_timeout = 5
|
827
|
+
* sock.recv_timeout => 5
|
828
|
+
*
|
829
|
+
*/
|
830
|
+
|
831
|
+
static VALUE rb_czmq_socket_recv_timeout(VALUE obj)
|
832
|
+
{
|
833
|
+
zmq_sock_wrapper *sock = NULL;
|
834
|
+
GetZmqSocket(obj);
|
835
|
+
return sock->recv_timeout;
|
836
|
+
}
|
837
|
+
|
838
|
+
/*
|
839
|
+
* call-seq:
|
840
|
+
* sock.send_timeout = 5 => nil
|
841
|
+
*
|
842
|
+
* Sets a send timeout for this socket.
|
843
|
+
*
|
844
|
+
* === Examples
|
845
|
+
* ctx = ZMQ::Context.new
|
846
|
+
* sock = ctx.socket(:REP)
|
847
|
+
* sock.send_timeout = 5 => nil
|
848
|
+
*
|
849
|
+
*/
|
850
|
+
|
851
|
+
static VALUE rb_czmq_socket_set_send_timeout(VALUE obj, VALUE timeout)
|
852
|
+
{
|
853
|
+
zmq_sock_wrapper *sock = NULL;
|
854
|
+
GetZmqSocket(obj);
|
855
|
+
if (TYPE(timeout) != T_FIXNUM && TYPE(timeout) != T_FLOAT) rb_raise(rb_eTypeError, "wrong timeout type %s (expected Fixnum or Float)", RSTRING_PTR(rb_obj_as_string(timeout)));
|
856
|
+
sock->send_timeout = timeout;
|
857
|
+
return Qnil;
|
858
|
+
}
|
859
|
+
|
860
|
+
/*
|
861
|
+
* call-seq:
|
862
|
+
* sock.send_timeout => Fixnum or nil
|
863
|
+
*
|
864
|
+
* Returns the send timeout currently associated with this socket.
|
865
|
+
*
|
866
|
+
* === Examples
|
867
|
+
* ctx = ZMQ::Context.new
|
868
|
+
* sock = ctx.socket(:REP)
|
869
|
+
* sock.send_timeout = 5
|
870
|
+
* sock.send_timeout => 5
|
871
|
+
*
|
872
|
+
*/
|
873
|
+
|
874
|
+
static VALUE rb_czmq_socket_send_timeout(VALUE obj)
|
875
|
+
{
|
876
|
+
zmq_sock_wrapper *sock = NULL;
|
877
|
+
GetZmqSocket(obj);
|
878
|
+
return sock->send_timeout;
|
879
|
+
}
|
880
|
+
|
881
|
+
/*
|
882
|
+
* call-seq:
|
883
|
+
* sock.hwm => Fixnum
|
884
|
+
*
|
885
|
+
* Returns the socket HWM (High Water Mark) value.
|
886
|
+
*
|
887
|
+
* === Examples
|
888
|
+
* ctx = ZMQ::Context.new
|
889
|
+
* sock = ctx.socket(:REP)
|
890
|
+
* sock.hwm => 0
|
891
|
+
*
|
892
|
+
*/
|
893
|
+
|
894
|
+
static VALUE rb_czmq_socket_opt_hwm(VALUE obj)
|
895
|
+
{
|
896
|
+
zmq_sock_wrapper *sock = NULL;
|
897
|
+
GetZmqSocket(obj);
|
898
|
+
return INT2NUM(zsockopt_hwm(sock->socket));
|
899
|
+
}
|
900
|
+
|
901
|
+
/*
|
902
|
+
* call-seq:
|
903
|
+
* sock.hwm = 100 => nil
|
904
|
+
*
|
905
|
+
* Sets the socket HWM (High Water Mark() value.
|
906
|
+
*
|
907
|
+
* === Examples
|
908
|
+
* ctx = ZMQ::Context.new
|
909
|
+
* sock = ctx.socket(:REP)
|
910
|
+
* sock.hwm = 100 => nil
|
911
|
+
* sock.hwm => 100
|
912
|
+
*
|
913
|
+
*/
|
914
|
+
|
915
|
+
static VALUE rb_czmq_socket_set_opt_hwm(VALUE obj, VALUE value)
|
916
|
+
{
|
917
|
+
zmq_sock_wrapper *sock = NULL;
|
918
|
+
ZmqSetSockOpt(obj, zsockopt_set_hwm, "HWM", value);
|
919
|
+
}
|
920
|
+
|
921
|
+
/*
|
922
|
+
* call-seq:
|
923
|
+
* sock.swap => Fixnum
|
924
|
+
*
|
925
|
+
* Returns the socket SWAP value.
|
926
|
+
*
|
927
|
+
* === Examples
|
928
|
+
* ctx = ZMQ::Context.new
|
929
|
+
* sock = ctx.socket(:REP)
|
930
|
+
* sock.swap => 0
|
931
|
+
*
|
932
|
+
*/
|
933
|
+
|
934
|
+
static VALUE rb_czmq_socket_opt_swap(VALUE obj)
|
935
|
+
{
|
936
|
+
zmq_sock_wrapper *sock = NULL;
|
937
|
+
GetZmqSocket(obj);
|
938
|
+
return INT2NUM(zsockopt_swap(sock->socket));
|
939
|
+
}
|
940
|
+
|
941
|
+
/*
|
942
|
+
* call-seq:
|
943
|
+
* sock.swap = 100 => nil
|
944
|
+
*
|
945
|
+
* Sets the socket SWAP value.
|
946
|
+
*
|
947
|
+
* === Examples
|
948
|
+
* ctx = ZMQ::Context.new
|
949
|
+
* sock = ctx.socket(:REP)
|
950
|
+
* sock.swap = 100 => nil
|
951
|
+
*
|
952
|
+
*/
|
953
|
+
|
954
|
+
static VALUE rb_czmq_socket_set_opt_swap(VALUE obj, VALUE value)
|
955
|
+
{
|
956
|
+
zmq_sock_wrapper *sock = NULL;
|
957
|
+
ZmqSetSockOpt(obj, zsockopt_set_swap, "SWAP", value);
|
958
|
+
}
|
959
|
+
|
960
|
+
/*
|
961
|
+
* call-seq:
|
962
|
+
* sock.affinity => Fixnum
|
963
|
+
*
|
964
|
+
* Returns the socket AFFINITY value.
|
965
|
+
*
|
966
|
+
* === Examples
|
967
|
+
* ctx = ZMQ::Context.new
|
968
|
+
* sock = ctx.socket(:REP)
|
969
|
+
* sock.affinity => 0
|
970
|
+
*
|
971
|
+
*/
|
972
|
+
|
973
|
+
static VALUE rb_czmq_socket_opt_affinity(VALUE obj)
|
974
|
+
{
|
975
|
+
zmq_sock_wrapper *sock = NULL;
|
976
|
+
GetZmqSocket(obj);
|
977
|
+
return INT2NUM(zsockopt_affinity(sock->socket));
|
978
|
+
}
|
979
|
+
|
980
|
+
/*
|
981
|
+
* call-seq:
|
982
|
+
* sock.affinity = 1 => nil
|
983
|
+
*
|
984
|
+
* Sets the socket AFFINITY value.
|
985
|
+
*
|
986
|
+
* === Examples
|
987
|
+
* ctx = ZMQ::Context.new
|
988
|
+
* sock = ctx.socket(:REP)
|
989
|
+
* sock.affinity = 1 => nil
|
990
|
+
*
|
991
|
+
*/
|
992
|
+
|
993
|
+
static VALUE rb_czmq_socket_set_opt_affinity(VALUE obj, VALUE value)
|
994
|
+
{
|
995
|
+
zmq_sock_wrapper *sock = NULL;
|
996
|
+
ZmqSetSockOpt(obj, zsockopt_set_affinity, "AFFINITY", value);
|
997
|
+
}
|
998
|
+
|
999
|
+
/*
|
1000
|
+
* call-seq:
|
1001
|
+
* sock.rate => Fixnum
|
1002
|
+
*
|
1003
|
+
* Returns the socket RATE value.
|
1004
|
+
*
|
1005
|
+
* === Examples
|
1006
|
+
* ctx = ZMQ::Context.new
|
1007
|
+
* sock = ctx.socket(:REP)
|
1008
|
+
* sock.rate => 40000
|
1009
|
+
*
|
1010
|
+
*/
|
1011
|
+
|
1012
|
+
static VALUE rb_czmq_socket_opt_rate(VALUE obj)
|
1013
|
+
{
|
1014
|
+
zmq_sock_wrapper *sock = NULL;
|
1015
|
+
GetZmqSocket(obj);
|
1016
|
+
return INT2NUM(zsockopt_rate(sock->socket));
|
1017
|
+
}
|
1018
|
+
|
1019
|
+
/*
|
1020
|
+
* call-seq:
|
1021
|
+
* sock.rate = 50000 => nil
|
1022
|
+
*
|
1023
|
+
* Sets the socket RATE value.
|
1024
|
+
*
|
1025
|
+
* === Examples
|
1026
|
+
* ctx = ZMQ::Context.new
|
1027
|
+
* sock = ctx.socket(:REP)
|
1028
|
+
* sock.rate = 50000 => nil
|
1029
|
+
*
|
1030
|
+
*/
|
1031
|
+
|
1032
|
+
static VALUE rb_czmq_socket_set_opt_rate(VALUE obj, VALUE value)
|
1033
|
+
{
|
1034
|
+
zmq_sock_wrapper *sock = NULL;
|
1035
|
+
ZmqSetSockOpt(obj, zsockopt_set_rate, "RATE", value);
|
1036
|
+
}
|
1037
|
+
|
1038
|
+
/*
|
1039
|
+
* call-seq:
|
1040
|
+
* sock.recovery_ivl => Fixnum
|
1041
|
+
*
|
1042
|
+
* Returns the socket RECOVERY_IVL value.
|
1043
|
+
*
|
1044
|
+
* === Examples
|
1045
|
+
* ctx = ZMQ::Context.new
|
1046
|
+
* sock = ctx.socket(:REP)
|
1047
|
+
* sock.recovery_ivl => 10
|
1048
|
+
*
|
1049
|
+
*/
|
1050
|
+
|
1051
|
+
static VALUE rb_czmq_socket_opt_recovery_ivl(VALUE obj)
|
1052
|
+
{
|
1053
|
+
zmq_sock_wrapper *sock = NULL;
|
1054
|
+
GetZmqSocket(obj);
|
1055
|
+
return INT2NUM(zsockopt_recovery_ivl(sock->socket));
|
1056
|
+
}
|
1057
|
+
|
1058
|
+
/*
|
1059
|
+
* call-seq:
|
1060
|
+
* sock.recovery_ivl = 20 => nil
|
1061
|
+
*
|
1062
|
+
* Sets the socket RECOVERY_IVL value.
|
1063
|
+
*
|
1064
|
+
* === Examples
|
1065
|
+
* ctx = ZMQ::Context.new
|
1066
|
+
* sock = ctx.socket(:REP)
|
1067
|
+
* sock.recovery_ivl = 20 => nil
|
1068
|
+
*
|
1069
|
+
*/
|
1070
|
+
|
1071
|
+
static VALUE rb_czmq_socket_set_opt_recovery_ivl(VALUE obj, VALUE value)
|
1072
|
+
{
|
1073
|
+
zmq_sock_wrapper *sock = NULL;
|
1074
|
+
ZmqSetSockOpt(obj, zsockopt_set_recovery_ivl, "RECOVERY_IVL", value);
|
1075
|
+
}
|
1076
|
+
|
1077
|
+
/*
|
1078
|
+
* call-seq:
|
1079
|
+
* sock.recovery_ivl_msec => Fixnum
|
1080
|
+
*
|
1081
|
+
* Returns the socket RECOVERY_IVL_MSEC value.
|
1082
|
+
*
|
1083
|
+
* === Examples
|
1084
|
+
* ctx = ZMQ::Context.new
|
1085
|
+
* sock = ctx.socket(:REP)
|
1086
|
+
* sock.recovery_ivl_msec => -1
|
1087
|
+
*
|
1088
|
+
*/
|
1089
|
+
|
1090
|
+
static VALUE rb_czmq_socket_opt_recovery_ivl_msec(VALUE obj)
|
1091
|
+
{
|
1092
|
+
zmq_sock_wrapper *sock = NULL;
|
1093
|
+
GetZmqSocket(obj);
|
1094
|
+
return INT2NUM(zsockopt_recovery_ivl_msec(sock->socket));
|
1095
|
+
}
|
1096
|
+
|
1097
|
+
/*
|
1098
|
+
* call-seq:
|
1099
|
+
* sock.recovery_ivl_msec = 20 => nil
|
1100
|
+
*
|
1101
|
+
* Sets the socket RECOVERY_IVL_MSEC value.
|
1102
|
+
*
|
1103
|
+
* === Examples
|
1104
|
+
* ctx = ZMQ::Context.new
|
1105
|
+
* sock = ctx.socket(:REP)
|
1106
|
+
* sock.recovery_ivl_msec = 20 => nil
|
1107
|
+
*
|
1108
|
+
*/
|
1109
|
+
|
1110
|
+
static VALUE rb_czmq_socket_set_opt_recovery_ivl_msec(VALUE obj, VALUE value)
|
1111
|
+
{
|
1112
|
+
zmq_sock_wrapper *sock = NULL;
|
1113
|
+
ZmqSetSockOpt(obj, zsockopt_set_recovery_ivl_msec, "RECOVERY_IVL_MSEC", value);
|
1114
|
+
}
|
1115
|
+
|
1116
|
+
/*
|
1117
|
+
* call-seq:
|
1118
|
+
* sock.mcast_loop? => boolean
|
1119
|
+
*
|
1120
|
+
* Returns the socket MCAST_LOOP status.
|
1121
|
+
*
|
1122
|
+
* === Examples
|
1123
|
+
* ctx = ZMQ::Context.new
|
1124
|
+
* sock = ctx.socket(:REP)
|
1125
|
+
* sock.mcast_loop? => true
|
1126
|
+
*
|
1127
|
+
*/
|
1128
|
+
|
1129
|
+
static VALUE rb_czmq_socket_opt_mcast_loop(VALUE obj)
|
1130
|
+
{
|
1131
|
+
zmq_sock_wrapper *sock = NULL;
|
1132
|
+
GetZmqSocket(obj);
|
1133
|
+
return (zsockopt_mcast_loop(sock->socket) == 1) ? Qtrue : Qfalse;
|
1134
|
+
}
|
1135
|
+
|
1136
|
+
/*
|
1137
|
+
* call-seq:
|
1138
|
+
* sock.mcast_loop = false => nil
|
1139
|
+
*
|
1140
|
+
* Sets the socket MCAST_LOOP value.
|
1141
|
+
*
|
1142
|
+
* === Examples
|
1143
|
+
* ctx = ZMQ::Context.new
|
1144
|
+
* sock = ctx.socket(:REP)
|
1145
|
+
* sock.mcast_loop = false => nil
|
1146
|
+
*
|
1147
|
+
*/
|
1148
|
+
|
1149
|
+
static VALUE rb_czmq_socket_set_opt_mcast_loop(VALUE obj, VALUE value)
|
1150
|
+
{
|
1151
|
+
zmq_sock_wrapper *sock = NULL;
|
1152
|
+
ZmqSetBooleanSockOpt(obj, zsockopt_set_mcast_loop, "MCAST_LOOP", value);
|
1153
|
+
}
|
1154
|
+
|
1155
|
+
/*
|
1156
|
+
* call-seq:
|
1157
|
+
* sock.sndbuf => Fixnum
|
1158
|
+
*
|
1159
|
+
* Returns the socket SNDBUF value.
|
1160
|
+
*
|
1161
|
+
* === Examples
|
1162
|
+
* ctx = ZMQ::Context.new
|
1163
|
+
* sock = ctx.socket(:REP)
|
1164
|
+
* sock.sndbuf => 0
|
1165
|
+
*
|
1166
|
+
*/
|
1167
|
+
|
1168
|
+
static VALUE rb_czmq_socket_opt_sndbuf(VALUE obj)
|
1169
|
+
{
|
1170
|
+
zmq_sock_wrapper *sock = NULL;
|
1171
|
+
GetZmqSocket(obj);
|
1172
|
+
return INT2NUM(zsockopt_sndbuf(sock->socket));
|
1173
|
+
}
|
1174
|
+
|
1175
|
+
/*
|
1176
|
+
* call-seq:
|
1177
|
+
* sock.sndbuf = 1000 => nil
|
1178
|
+
*
|
1179
|
+
* Sets the socket SNDBUF value.
|
1180
|
+
*
|
1181
|
+
* === Examples
|
1182
|
+
* ctx = ZMQ::Context.new
|
1183
|
+
* sock = ctx.socket(:REP)
|
1184
|
+
* sock.sndbuf = 1000 => nil
|
1185
|
+
*
|
1186
|
+
*/
|
1187
|
+
|
1188
|
+
static VALUE rb_czmq_socket_set_opt_sndbuf(VALUE obj, VALUE value)
|
1189
|
+
{
|
1190
|
+
zmq_sock_wrapper *sock = NULL;
|
1191
|
+
ZmqSetSockOpt(obj, zsockopt_set_sndbuf, "SNDBUF", value);
|
1192
|
+
}
|
1193
|
+
|
1194
|
+
/*
|
1195
|
+
* call-seq:
|
1196
|
+
* sock.rcvbuf => Fixnum
|
1197
|
+
*
|
1198
|
+
* Returns the socket RCVBUF value.
|
1199
|
+
*
|
1200
|
+
* === Examples
|
1201
|
+
* ctx = ZMQ::Context.new
|
1202
|
+
* sock = ctx.socket(:REP)
|
1203
|
+
* sock.rcvbuf => 0
|
1204
|
+
*
|
1205
|
+
*/
|
1206
|
+
|
1207
|
+
static VALUE rb_czmq_socket_opt_rcvbuf(VALUE obj)
|
1208
|
+
{
|
1209
|
+
zmq_sock_wrapper *sock = NULL;
|
1210
|
+
GetZmqSocket(obj);
|
1211
|
+
return INT2NUM(zsockopt_rcvbuf(sock->socket));
|
1212
|
+
}
|
1213
|
+
|
1214
|
+
/*
|
1215
|
+
* call-seq:
|
1216
|
+
* sock.rcvbuf = 1000 => nil
|
1217
|
+
*
|
1218
|
+
* Sets the socket RCVBUF value.
|
1219
|
+
*
|
1220
|
+
* === Examples
|
1221
|
+
* ctx = ZMQ::Context.new
|
1222
|
+
* sock = ctx.socket(:REP)
|
1223
|
+
* sock.rcvbuf = 1000 => nil
|
1224
|
+
*
|
1225
|
+
*/
|
1226
|
+
|
1227
|
+
static VALUE rb_czmq_socket_set_opt_rcvbuf(VALUE obj, VALUE value)
|
1228
|
+
{
|
1229
|
+
zmq_sock_wrapper *sock = NULL;
|
1230
|
+
ZmqSetSockOpt(obj, zsockopt_set_rcvbuf, "RCVBUF", value);
|
1231
|
+
}
|
1232
|
+
|
1233
|
+
/*
|
1234
|
+
* call-seq:
|
1235
|
+
* sock.linger => Fixnum
|
1236
|
+
*
|
1237
|
+
* Returns the socket LINGER value.
|
1238
|
+
*
|
1239
|
+
* === Examples
|
1240
|
+
* ctx = ZMQ::Context.new
|
1241
|
+
* sock = ctx.socket(:REP)
|
1242
|
+
* sock.linger => -1
|
1243
|
+
*
|
1244
|
+
*/
|
1245
|
+
|
1246
|
+
static VALUE rb_czmq_socket_opt_linger(VALUE obj)
|
1247
|
+
{
|
1248
|
+
zmq_sock_wrapper *sock = NULL;
|
1249
|
+
GetZmqSocket(obj);
|
1250
|
+
return INT2NUM(zsockopt_linger(sock->socket));
|
1251
|
+
}
|
1252
|
+
|
1253
|
+
/*
|
1254
|
+
* call-seq:
|
1255
|
+
* sock.linger = 1000 => nil
|
1256
|
+
*
|
1257
|
+
* Sets the socket LINGER value in ms.
|
1258
|
+
*
|
1259
|
+
* === Examples
|
1260
|
+
* ctx = ZMQ::Context.new
|
1261
|
+
* sock = ctx.socket(:REP)
|
1262
|
+
* sock.linger = 1000 => nil
|
1263
|
+
*
|
1264
|
+
*/
|
1265
|
+
|
1266
|
+
static VALUE rb_czmq_socket_set_opt_linger(VALUE obj, VALUE value)
|
1267
|
+
{
|
1268
|
+
zmq_sock_wrapper *sock = NULL;
|
1269
|
+
ZmqSetSockOpt(obj, zsockopt_set_linger, "LINGER", value);
|
1270
|
+
}
|
1271
|
+
|
1272
|
+
/*
|
1273
|
+
* call-seq:
|
1274
|
+
* sock.backlog => Fixnum
|
1275
|
+
*
|
1276
|
+
* Returns the socket BACKLOG value.
|
1277
|
+
*
|
1278
|
+
* === Examples
|
1279
|
+
* ctx = ZMQ::Context.new
|
1280
|
+
* sock = ctx.socket(:REP)
|
1281
|
+
* sock.backlog => 100
|
1282
|
+
*
|
1283
|
+
*/
|
1284
|
+
|
1285
|
+
static VALUE rb_czmq_socket_opt_backlog(VALUE obj)
|
1286
|
+
{
|
1287
|
+
zmq_sock_wrapper *sock = NULL;
|
1288
|
+
GetZmqSocket(obj);
|
1289
|
+
return INT2NUM(zsockopt_backlog(sock->socket));
|
1290
|
+
}
|
1291
|
+
|
1292
|
+
/*
|
1293
|
+
* call-seq:
|
1294
|
+
* sock.backlog = 200 => nil
|
1295
|
+
*
|
1296
|
+
* Sets the socket BACKLOG value.
|
1297
|
+
*
|
1298
|
+
* === Examples
|
1299
|
+
* ctx = ZMQ::Context.new
|
1300
|
+
* sock = ctx.socket(:REP)
|
1301
|
+
* sock.backlog = 200 => nil
|
1302
|
+
*
|
1303
|
+
*/
|
1304
|
+
|
1305
|
+
static VALUE rb_czmq_socket_set_opt_backlog(VALUE obj, VALUE value)
|
1306
|
+
{
|
1307
|
+
zmq_sock_wrapper *sock = NULL;
|
1308
|
+
ZmqSetSockOpt(obj, zsockopt_set_backlog, "BACKLOG", value);
|
1309
|
+
}
|
1310
|
+
|
1311
|
+
/*
|
1312
|
+
* call-seq:
|
1313
|
+
* sock.reconnect_ivl => Fixnum
|
1314
|
+
*
|
1315
|
+
* Returns the socket RECONNECT_IVL value.
|
1316
|
+
*
|
1317
|
+
* === Examples
|
1318
|
+
* ctx = ZMQ::Context.new
|
1319
|
+
* sock = ctx.socket(:REP)
|
1320
|
+
* sock.reconnect_ivl => 100
|
1321
|
+
*
|
1322
|
+
*/
|
1323
|
+
|
1324
|
+
static VALUE rb_czmq_socket_opt_reconnect_ivl(VALUE obj)
|
1325
|
+
{
|
1326
|
+
zmq_sock_wrapper *sock = NULL;
|
1327
|
+
GetZmqSocket(obj);
|
1328
|
+
return INT2NUM(zsockopt_reconnect_ivl(sock->socket));
|
1329
|
+
}
|
1330
|
+
|
1331
|
+
/*
|
1332
|
+
* call-seq:
|
1333
|
+
* sock.reconnect_ivl = 200 => nil
|
1334
|
+
*
|
1335
|
+
* Sets the socket RECONNECT_IVL value.
|
1336
|
+
*
|
1337
|
+
* === Examples
|
1338
|
+
* ctx = ZMQ::Context.new
|
1339
|
+
* sock = ctx.socket(:REP)
|
1340
|
+
* sock.reconnect_ivl = 200 => nil
|
1341
|
+
*
|
1342
|
+
*/
|
1343
|
+
|
1344
|
+
static VALUE rb_czmq_socket_set_opt_reconnect_ivl(VALUE obj, VALUE value)
|
1345
|
+
{
|
1346
|
+
zmq_sock_wrapper *sock = NULL;
|
1347
|
+
ZmqSetSockOpt(obj, zsockopt_set_reconnect_ivl, "RECONNECT_IVL", value);
|
1348
|
+
}
|
1349
|
+
|
1350
|
+
/*
|
1351
|
+
* call-seq:
|
1352
|
+
* sock.reconnect_ivl_max => Fixnum
|
1353
|
+
*
|
1354
|
+
* Returns the socket RECONNECT_IVL_MAX value.
|
1355
|
+
*
|
1356
|
+
* === Examples
|
1357
|
+
* ctx = ZMQ::Context.new
|
1358
|
+
* sock = ctx.socket(:REP)
|
1359
|
+
* sock.reconnect_ivl_max => 0
|
1360
|
+
*
|
1361
|
+
*/
|
1362
|
+
|
1363
|
+
static VALUE rb_czmq_socket_opt_reconnect_ivl_max(VALUE obj)
|
1364
|
+
{
|
1365
|
+
zmq_sock_wrapper *sock = NULL;
|
1366
|
+
GetZmqSocket(obj);
|
1367
|
+
return INT2NUM(zsockopt_reconnect_ivl_max(sock->socket));
|
1368
|
+
}
|
1369
|
+
|
1370
|
+
/*
|
1371
|
+
* call-seq:
|
1372
|
+
* sock.reconnect_ivl_max = 5 => nil
|
1373
|
+
*
|
1374
|
+
* Sets the socket RECONNECT_IVL_MAX value.
|
1375
|
+
*
|
1376
|
+
* === Examples
|
1377
|
+
* ctx = ZMQ::Context.new
|
1378
|
+
* sock = ctx.socket(:REP)
|
1379
|
+
* sock.reconnect_ivl_max = 5 => nil
|
1380
|
+
*
|
1381
|
+
*/
|
1382
|
+
|
1383
|
+
static VALUE rb_czmq_socket_set_opt_reconnect_ivl_max(VALUE obj, VALUE value)
|
1384
|
+
{
|
1385
|
+
zmq_sock_wrapper *sock = NULL;
|
1386
|
+
ZmqSetSockOpt(obj, zsockopt_set_reconnect_ivl_max, "RECONNECT_IVL_MAX", value);
|
1387
|
+
}
|
1388
|
+
|
1389
|
+
/*
|
1390
|
+
* call-seq:
|
1391
|
+
* sock.identity = "anonymous" => nil
|
1392
|
+
*
|
1393
|
+
* Sets the socket IDENTITY value.
|
1394
|
+
*
|
1395
|
+
* === Examples
|
1396
|
+
* ctx = ZMQ::Context.new
|
1397
|
+
* sock = ctx.socket(:REP)
|
1398
|
+
* sock.identity = "anonymous" => nil
|
1399
|
+
*
|
1400
|
+
*/
|
1401
|
+
|
1402
|
+
static VALUE rb_czmq_socket_set_opt_identity(VALUE obj, VALUE value)
|
1403
|
+
{
|
1404
|
+
char *val;
|
1405
|
+
zmq_sock_wrapper *sock = NULL;
|
1406
|
+
GetZmqSocket(obj);
|
1407
|
+
ZmqSockGuardCrossThread(sock);
|
1408
|
+
Check_Type(value, T_STRING);
|
1409
|
+
if (RSTRING_LEN(value) == 0) rb_raise(rb_eZmqError, "socket identity cannot be empty.");
|
1410
|
+
if (RSTRING_LEN(value) > 255) rb_raise(rb_eZmqError, "maximum socket identity is 255 chars.");
|
1411
|
+
val = StringValueCStr(value);
|
1412
|
+
zsockopt_set_identity(sock->socket, val);
|
1413
|
+
if (sock->verbose)
|
1414
|
+
zclock_log ("I: %s socket %p: set option \"IDENTITY\" \"%s\"", zsocket_type_str(sock->socket), obj, val);
|
1415
|
+
return Qnil;
|
1416
|
+
}
|
1417
|
+
|
1418
|
+
/*
|
1419
|
+
* call-seq:
|
1420
|
+
* sock.subscribe "ruby" => nil
|
1421
|
+
*
|
1422
|
+
* Subscribes this SUB socket to a topic.
|
1423
|
+
*
|
1424
|
+
* === Examples
|
1425
|
+
* ctx = ZMQ::Context.new
|
1426
|
+
* sock = ctx.socket(:SUB)
|
1427
|
+
* sock.subscribe "ruby" => nil
|
1428
|
+
*
|
1429
|
+
*/
|
1430
|
+
|
1431
|
+
static VALUE rb_czmq_socket_set_opt_subscribe(VALUE obj, VALUE value)
|
1432
|
+
{
|
1433
|
+
zmq_sock_wrapper *sock = NULL;
|
1434
|
+
ZmqSetStringSockOpt(obj, zsockopt_set_subscribe, "SUBSCRIBE", value, {
|
1435
|
+
ZmqAssertSockOptFor(ZMQ_SUB)
|
1436
|
+
});
|
1437
|
+
}
|
1438
|
+
|
1439
|
+
/*
|
1440
|
+
* call-seq:
|
1441
|
+
* sock.unsubscribe "ruby" => nil
|
1442
|
+
*
|
1443
|
+
* Unsubscribes this SUB socket from a topic.
|
1444
|
+
*
|
1445
|
+
* === Examples
|
1446
|
+
* ctx = ZMQ::Context.new
|
1447
|
+
* sock = ctx.socket(:SUB)
|
1448
|
+
* sock.unsubscribe "ruby" => nil
|
1449
|
+
*
|
1450
|
+
*/
|
1451
|
+
|
1452
|
+
static VALUE rb_czmq_socket_set_opt_unsubscribe(VALUE obj, VALUE value)
|
1453
|
+
{
|
1454
|
+
zmq_sock_wrapper *sock = NULL;
|
1455
|
+
ZmqSetStringSockOpt(obj, zsockopt_set_unsubscribe, "UNSUBSCRIBE", value, {
|
1456
|
+
ZmqAssertSockOptFor(ZMQ_SUB)
|
1457
|
+
});
|
1458
|
+
}
|
1459
|
+
|
1460
|
+
/*
|
1461
|
+
* call-seq:
|
1462
|
+
* sock.rcvmore => boolean
|
1463
|
+
*
|
1464
|
+
* Query if there's more messages to receive.
|
1465
|
+
*
|
1466
|
+
* === Examples
|
1467
|
+
* ctx = ZMQ::Context.new
|
1468
|
+
* sock = ctx.socket(:SUB)
|
1469
|
+
* sock.rcvmore => true
|
1470
|
+
*
|
1471
|
+
*/
|
1472
|
+
|
1473
|
+
static VALUE rb_czmq_socket_opt_rcvmore(VALUE obj)
|
1474
|
+
{
|
1475
|
+
zmq_sock_wrapper *sock = NULL;
|
1476
|
+
GetZmqSocket(obj);
|
1477
|
+
return (zsockopt_rcvmore(sock->socket) == 1) ? Qtrue : Qfalse;
|
1478
|
+
}
|
1479
|
+
|
1480
|
+
/*
|
1481
|
+
* call-seq:
|
1482
|
+
* sock.events => Fixnum
|
1483
|
+
*
|
1484
|
+
* Query if this socket is in a readable or writable state.
|
1485
|
+
*
|
1486
|
+
* === Examples
|
1487
|
+
* ctx = ZMQ::Context.new
|
1488
|
+
* sock = ctx.socket(:SUB)
|
1489
|
+
* sock.events => ZMQ::POLLIN
|
1490
|
+
*
|
1491
|
+
*/
|
1492
|
+
|
1493
|
+
static VALUE rb_czmq_socket_opt_events(VALUE obj)
|
1494
|
+
{
|
1495
|
+
zmq_sock_wrapper *sock = NULL;
|
1496
|
+
GetZmqSocket(obj);
|
1497
|
+
return INT2NUM(zsockopt_events(sock->socket));
|
1498
|
+
}
|
1499
|
+
|
1500
|
+
void _init_rb_czmq_socket()
|
1501
|
+
{
|
1502
|
+
rb_cZmqSocket = rb_define_class_under(rb_mZmq, "Socket", rb_cObject);
|
1503
|
+
rb_cZmqPubSocket = rb_define_class_under(rb_cZmqSocket, "Pub", rb_cZmqSocket);
|
1504
|
+
rb_cZmqSubSocket = rb_define_class_under(rb_cZmqSocket, "Sub", rb_cZmqSocket);;
|
1505
|
+
rb_cZmqPushSocket = rb_define_class_under(rb_cZmqSocket, "Push", rb_cZmqSocket);;
|
1506
|
+
rb_cZmqPullSocket = rb_define_class_under(rb_cZmqSocket, "Pull", rb_cZmqSocket);;
|
1507
|
+
rb_cZmqRouterSocket = rb_define_class_under(rb_cZmqSocket, "Router", rb_cZmqSocket);;
|
1508
|
+
rb_cZmqDealerSocket = rb_define_class_under(rb_cZmqSocket, "Dealer", rb_cZmqSocket);;
|
1509
|
+
rb_cZmqRepSocket = rb_define_class_under(rb_cZmqSocket, "Rep", rb_cZmqSocket);;
|
1510
|
+
rb_cZmqReqSocket = rb_define_class_under(rb_cZmqSocket, "Req", rb_cZmqSocket);;
|
1511
|
+
rb_cZmqPairSocket = rb_define_class_under(rb_cZmqSocket, "Pair", rb_cZmqSocket);;
|
1512
|
+
|
1513
|
+
rb_define_const(rb_cZmqSocket, "PENDING", INT2NUM(ZMQ_SOCKET_PENDING));
|
1514
|
+
rb_define_const(rb_cZmqSocket, "BOUND", INT2NUM(ZMQ_SOCKET_BOUND));
|
1515
|
+
rb_define_const(rb_cZmqSocket, "CONNECTED", INT2NUM(ZMQ_SOCKET_CONNECTED));
|
1516
|
+
|
1517
|
+
rb_define_method(rb_cZmqSocket, "close", rb_czmq_socket_close, 0);
|
1518
|
+
rb_define_method(rb_cZmqSocket, "endpoint", rb_czmq_socket_endpoint, 0);
|
1519
|
+
rb_define_method(rb_cZmqSocket, "state", rb_czmq_socket_state, 0);
|
1520
|
+
rb_define_method(rb_cZmqSocket, "bind", rb_czmq_socket_bind, 1);
|
1521
|
+
rb_define_method(rb_cZmqSocket, "connect", rb_czmq_socket_connect, 1);
|
1522
|
+
rb_define_method(rb_cZmqSocket, "fd", rb_czmq_socket_fd, 0);
|
1523
|
+
rb_define_alias(rb_cZmqSocket, "to_i", "fd");
|
1524
|
+
rb_define_method(rb_cZmqSocket, "verbose=", rb_czmq_socket_set_verbose, 1);
|
1525
|
+
rb_define_method(rb_cZmqSocket, "send", rb_czmq_socket_send, 1);
|
1526
|
+
rb_define_method(rb_cZmqSocket, "sendm", rb_czmq_socket_sendm, 1);
|
1527
|
+
rb_define_method(rb_cZmqSocket, "send_frame", rb_czmq_socket_send_frame, -1);
|
1528
|
+
rb_define_method(rb_cZmqSocket, "send_message", rb_czmq_socket_send_message, 1);
|
1529
|
+
rb_define_method(rb_cZmqSocket, "recv", rb_czmq_socket_recv, 0);
|
1530
|
+
rb_define_method(rb_cZmqSocket, "recv_nonblock", rb_czmq_socket_recv_nonblock, 0);
|
1531
|
+
rb_define_method(rb_cZmqSocket, "recv_frame", rb_czmq_socket_recv_frame, 0);
|
1532
|
+
rb_define_method(rb_cZmqSocket, "recv_frame_nonblock", rb_czmq_socket_recv_frame_nonblock, 0);
|
1533
|
+
rb_define_method(rb_cZmqSocket, "recv_message", rb_czmq_socket_recv_message, 0);
|
1534
|
+
rb_define_method(rb_cZmqSocket, "recv_timeout=", rb_czmq_socket_set_recv_timeout, 1);
|
1535
|
+
rb_define_method(rb_cZmqSocket, "recv_timeout", rb_czmq_socket_recv_timeout, 0);
|
1536
|
+
rb_define_method(rb_cZmqSocket, "send_timeout=", rb_czmq_socket_set_send_timeout, 1);
|
1537
|
+
rb_define_method(rb_cZmqSocket, "send_timeout", rb_czmq_socket_send_timeout, 0);
|
1538
|
+
|
1539
|
+
rb_define_method(rb_cZmqSocket, "hwm", rb_czmq_socket_opt_hwm, 0);
|
1540
|
+
rb_define_method(rb_cZmqSocket, "hwm=", rb_czmq_socket_set_opt_hwm, 1);
|
1541
|
+
rb_define_method(rb_cZmqSocket, "swap", rb_czmq_socket_opt_swap, 0);
|
1542
|
+
rb_define_method(rb_cZmqSocket, "swap=", rb_czmq_socket_set_opt_swap, 1);
|
1543
|
+
rb_define_method(rb_cZmqSocket, "affinity", rb_czmq_socket_opt_affinity, 0);
|
1544
|
+
rb_define_method(rb_cZmqSocket, "affinity=", rb_czmq_socket_set_opt_affinity, 1);
|
1545
|
+
rb_define_method(rb_cZmqSocket, "rate", rb_czmq_socket_opt_rate, 0);
|
1546
|
+
rb_define_method(rb_cZmqSocket, "rate=", rb_czmq_socket_set_opt_rate, 1);
|
1547
|
+
rb_define_method(rb_cZmqSocket, "recovery_ivl", rb_czmq_socket_opt_recovery_ivl, 0);
|
1548
|
+
rb_define_method(rb_cZmqSocket, "recovery_ivl=", rb_czmq_socket_set_opt_recovery_ivl, 1);
|
1549
|
+
rb_define_method(rb_cZmqSocket, "recovery_ivl_msec", rb_czmq_socket_opt_recovery_ivl_msec, 0);
|
1550
|
+
rb_define_method(rb_cZmqSocket, "recovery_ivl_msec=", rb_czmq_socket_set_opt_recovery_ivl_msec, 1);
|
1551
|
+
rb_define_method(rb_cZmqSocket, "mcast_loop?", rb_czmq_socket_opt_mcast_loop, 0);
|
1552
|
+
rb_define_method(rb_cZmqSocket, "mcast_loop=", rb_czmq_socket_set_opt_mcast_loop, 1);
|
1553
|
+
rb_define_method(rb_cZmqSocket, "sndbuf", rb_czmq_socket_opt_sndbuf, 0);
|
1554
|
+
rb_define_method(rb_cZmqSocket, "sndbuf=", rb_czmq_socket_set_opt_sndbuf, 1);
|
1555
|
+
rb_define_method(rb_cZmqSocket, "rcvbuf", rb_czmq_socket_opt_rcvbuf, 0);
|
1556
|
+
rb_define_method(rb_cZmqSocket, "rcvbuf=", rb_czmq_socket_set_opt_rcvbuf, 1);
|
1557
|
+
rb_define_method(rb_cZmqSocket, "linger", rb_czmq_socket_opt_linger, 0);
|
1558
|
+
rb_define_method(rb_cZmqSocket, "linger=", rb_czmq_socket_set_opt_linger, 1);
|
1559
|
+
rb_define_method(rb_cZmqSocket, "backlog", rb_czmq_socket_opt_backlog, 0);
|
1560
|
+
rb_define_method(rb_cZmqSocket, "backlog=", rb_czmq_socket_set_opt_backlog, 1);
|
1561
|
+
rb_define_method(rb_cZmqSocket, "reconnect_ivl", rb_czmq_socket_opt_reconnect_ivl, 0);
|
1562
|
+
rb_define_method(rb_cZmqSocket, "reconnect_ivl=", rb_czmq_socket_set_opt_reconnect_ivl, 1);
|
1563
|
+
rb_define_method(rb_cZmqSocket, "reconnect_ivl_max", rb_czmq_socket_opt_reconnect_ivl_max, 0);
|
1564
|
+
rb_define_method(rb_cZmqSocket, "reconnect_ivl_max=", rb_czmq_socket_set_opt_reconnect_ivl_max, 1);
|
1565
|
+
rb_define_method(rb_cZmqSocket, "identity=", rb_czmq_socket_set_opt_identity, 1);
|
1566
|
+
rb_define_method(rb_cZmqSocket, "subscribe", rb_czmq_socket_set_opt_subscribe, 1);
|
1567
|
+
rb_define_method(rb_cZmqSocket, "unsubscribe", rb_czmq_socket_set_opt_unsubscribe, 1);
|
1568
|
+
rb_define_method(rb_cZmqSocket, "rcvmore?", rb_czmq_socket_opt_rcvmore, 0);
|
1569
|
+
rb_define_method(rb_cZmqSocket, "events", rb_czmq_socket_opt_events, 0);
|
1570
|
+
}
|