Skip to content

Commit d782930

Browse files
committed
bump czmq/libzmq, statically link against them
Statically link against libzmq, czmq and libsodium, to avoid issues with dynamic linking of libzmq (see e.g. #43). Whilst on it (mainly because the existing versions of czmq/libzmq were being a PITA to get to link statically properly), also bump the versions of libzmq and czmq. With czmq now being at API v3, also adjust the extension to be compatible with it. It still uses a fair number of deprecated APIs, but it absolutely works with API v3. Fixes #43 Fixes #45 (hopefully) Fixes #47
1 parent d7ce432 commit d782930

File tree

13 files changed

+168
-66
lines changed

13 files changed

+168
-66
lines changed

.gitmodules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[submodule "ext/zeromq"]
22
path = ext/zeromq
3-
url = https://github.com/zeromq/zeromq4-x
3+
url = https://github.com/zeromq/libzmq
44
[submodule "ext/czmq"]
55
path = ext/czmq
66
url = https://github.com/zeromq/czmq

ext/czmq

Submodule czmq updated 410 files

ext/rbczmq/beacon.c

Lines changed: 30 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,15 @@
88
static VALUE rb_czmq_nogvl_beacon_destroy(void *ptr)
99
{
1010
zmq_beacon_wrapper *beacon = ptr;
11+
1112
if (beacon->beacon) {
12-
zbeacon_destroy(&beacon->beacon);
13+
zactor_destroy(&beacon->beacon);
1314
beacon->beacon = NULL;
1415
}
16+
17+
if (beacon->hostname) {
18+
zstr_free(&beacon->hostname);
19+
}
1520
return Qnil;
1621
}
1722

@@ -36,8 +41,16 @@ static void rb_czmq_free_beacon_gc(void *ptr)
3641
*/
3742
static VALUE rb_czmq_nogvl_new_beacon(void *ptr)
3843
{
39-
int port = (int)ptr;
40-
return (VALUE)zbeacon_new(port);
44+
zmq_beacon_wrapper *beacon = ptr;
45+
46+
beacon->beacon = zactor_new(zbeacon, NULL);
47+
beacon->interval = 1000;
48+
49+
zsock_send(beacon->beacon, "si", "CONFIGURE", beacon->port);
50+
beacon->hostname = zstr_recv(beacon->beacon);
51+
assert (beacon->hostname != NULL);
52+
53+
return Qnil;
4154
}
4255

4356
/*
@@ -53,11 +66,12 @@ static VALUE rb_czmq_nogvl_new_beacon(void *ptr)
5366
static VALUE rb_czmq_beacon_s_new(VALUE beacon, VALUE port)
5467
{
5568
zmq_beacon_wrapper *bcn = NULL;
56-
int prt;
5769
Check_Type(port, T_FIXNUM);
5870
beacon = Data_Make_Struct(rb_cZmqBeacon, zmq_beacon_wrapper, 0, rb_czmq_free_beacon_gc, bcn);
59-
prt = FIX2INT(port);
60-
bcn->beacon = (zbeacon_t*)rb_thread_call_without_gvl(rb_czmq_nogvl_new_beacon, (void *)prt, RUBY_UBF_IO, 0);
71+
bcn->port = FIX2INT(port);
72+
if (bcn->port == 0)
73+
rb_raise(rb_eArgError, "port must not be zero!");
74+
rb_thread_call_without_gvl(rb_czmq_nogvl_new_beacon, (void *)bcn, RUBY_UBF_IO, 0);
6175
ZmqAssertObjOnAlloc(bcn->beacon, bcn);
6276
rb_obj_call_init(beacon, 0, NULL);
6377
return beacon;
@@ -94,20 +108,7 @@ static VALUE rb_czmq_beacon_destroy(VALUE obj)
94108
static VALUE rb_czmq_beacon_hostname(VALUE obj)
95109
{
96110
GetZmqBeacon(obj);
97-
return rb_str_new2(zbeacon_hostname(beacon->beacon));
98-
}
99-
100-
/*
101-
* :nodoc:
102-
* Set the beacon broadcast interval while the GIL is released.
103-
*
104-
*/
105-
static VALUE rb_czmq_nogvl_set_interval(void *ptr)
106-
{
107-
struct nogvl_beacon_interval_args *args = ptr;
108-
zmq_beacon_wrapper *beacon = args->beacon;
109-
zbeacon_set_interval(beacon->beacon, args->interval);
110-
return Qnil;
111+
return rb_str_new2(beacon->hostname);
111112
}
112113

113114
/*
@@ -125,21 +126,7 @@ static VALUE rb_czmq_beacon_set_interval(VALUE obj, VALUE interval)
125126
struct nogvl_beacon_interval_args args;
126127
GetZmqBeacon(obj);
127128
Check_Type(interval, T_FIXNUM);
128-
args.beacon = beacon;
129-
args.interval = FIX2INT(interval);
130-
rb_thread_call_without_gvl(rb_czmq_nogvl_set_interval, (void *)&args, RUBY_UBF_IO, 0);
131-
return Qnil;
132-
}
133-
134-
/*
135-
* :nodoc:
136-
* Filter beacons while the GIL is released.
137-
*
138-
*/
139-
static VALUE rb_czmq_nogvl_noecho(void *ptr)
140-
{
141-
zmq_beacon_wrapper *beacon = ptr;
142-
zbeacon_noecho(beacon->beacon);
129+
beacon->interval = FIX2INT(interval);
143130
return Qnil;
144131
}
145132

@@ -156,7 +143,7 @@ static VALUE rb_czmq_nogvl_noecho(void *ptr)
156143
static VALUE rb_czmq_beacon_noecho(VALUE obj)
157144
{
158145
GetZmqBeacon(obj);
159-
rb_thread_call_without_gvl(rb_czmq_nogvl_noecho, (void *)beacon, RUBY_UBF_IO, 0);
146+
/* XXX: Nothing to do here, as v3 always filters out our own message */
160147
return Qnil;
161148
}
162149

@@ -169,7 +156,8 @@ static VALUE rb_czmq_nogvl_publish(void *ptr)
169156
{
170157
struct nogvl_beacon_publish_args *args = ptr;
171158
zmq_beacon_wrapper *beacon = args->beacon;
172-
zbeacon_publish(beacon->beacon, (byte *)args->transmit ,args->length);
159+
zsock_send(beacon->beacon, "sbi", "PUBLISH", (byte *)args->transmit,
160+
args->length, beacon->interval);
173161
return Qnil;
174162
}
175163

@@ -203,7 +191,7 @@ static VALUE rb_czmq_beacon_publish(VALUE obj, VALUE transmit)
203191
static VALUE rb_czmq_nogvl_silence(void *ptr)
204192
{
205193
zmq_beacon_wrapper *beacon = ptr;
206-
zbeacon_silence(beacon->beacon);
194+
zstr_sendx(beacon->beacon, "SILENCE", NULL);
207195
return Qnil;
208196
}
209197

@@ -233,7 +221,8 @@ static VALUE rb_czmq_nogvl_subscribe(void *ptr)
233221
{
234222
struct nogvl_beacon_subscribe_args *args = ptr;
235223
zmq_beacon_wrapper *beacon = args->beacon;
236-
zbeacon_subscribe(beacon->beacon, (byte *)args->filter ,args->length);
224+
zsock_send(beacon->beacon, "sb", "SUBSCRIBE", (byte *)args->filter,
225+
args->length);
237226
return Qnil;
238227
}
239228

@@ -272,7 +261,7 @@ static VALUE rb_czmq_beacon_subscribe(VALUE obj, VALUE filter)
272261
static VALUE rb_czmq_nogvl_unsubscribe(void *ptr)
273262
{
274263
zmq_beacon_wrapper *beacon = ptr;
275-
zbeacon_unsubscribe(beacon->beacon);
264+
zstr_sendx(beacon->beacon, "UNSUBSCRIBE", NULL);
276265
return Qnil;
277266
}
278267

@@ -298,7 +287,7 @@ static VALUE rb_czmq_beacon_pipe(VALUE obj)
298287
zmq_sock_wrapper *sock = NULL;
299288
VALUE socket;
300289
GetZmqBeacon(obj);
301-
socket = rb_czmq_socket_alloc(Qnil, NULL, zbeacon_socket(beacon->beacon));
290+
socket = rb_czmq_socket_alloc(Qnil, NULL, zsock_resolve(beacon->beacon));
302291
GetZmqSocket(socket);
303292
sock->state = ZMQ_SOCKET_BOUND;
304293
return socket;

ext/rbczmq/beacon.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
#define RBCZMQ_BEACON_H
33

44
typedef struct {
5-
zbeacon_t *beacon;
5+
zactor_t *beacon;
6+
char *hostname;
7+
int interval;
8+
int port;
69
} zmq_beacon_wrapper;
710

811
#define ZmqAssertBeacon(obj) ZmqAssertType(obj, rb_cZmqBeacon, "ZMQ::Beacon")

ext/rbczmq/extconf.rb

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ def check_heads heads = [], fatal = false
8787

8888
when /linux/
8989
CZMQ_CFLAGS << "-fPIC"
90+
CONFIG['LDSHARED'] = "$(CXX) -shared -lstdc++ -fPIC"
9091

9192
else
9293
# on Unix we need a g++ link, not gcc.
@@ -105,7 +106,7 @@ def check_heads heads = [], fatal = false
105106
lib = libs_path + "libsodium.#{LIBEXT}"
106107
Dir.chdir libsodium_path do
107108
sys "./autogen.sh", "libsodium autogen failed!" unless File.exist?(libsodium_path + 'configure')
108-
sys "./configure --prefix=#{dst_path} --without-documentation --enable-shared",
109+
sys "./configure CFLAGS='#{CZMQ_CFLAGS.join(" ")}' CXXFLAGS='#{CZMQ_CFLAGS.join(" ")}' --prefix=#{dst_path} --without-documentation --disable-shared --enable-static --disable-pie",
109110
"libsodium configure failed" unless File.exist?(libsodium_path + 'Makefile')
110111
sys "make && make install", "libsodium compile error!"
111112
end
@@ -118,7 +119,7 @@ def check_heads heads = [], fatal = false
118119
lib = libs_path + "libzmq.#{LIBEXT}"
119120
Dir.chdir zmq_path do
120121
sys "./autogen.sh", "ZeroMQ autogen failed!" unless File.exist?(zmq_path + 'configure')
121-
sys "./configure --prefix=#{dst_path} --without-documentation --enable-shared",
122+
sys "./configure CFLAGS='#{CZMQ_CFLAGS.join(" ")}' CXXFLAGS='#{CZMQ_CFLAGS.join(" ")}' --prefix=#{dst_path} --without-documentation --disable-shared --enable-static --with-libsodium=#{dst_path}",
122123
"ZeroMQ configure failed" unless File.exist?(zmq_path + 'Makefile')
123124
sys "make && make install", "ZeroMQ compile error!"
124125
end
@@ -131,7 +132,7 @@ def check_heads heads = [], fatal = false
131132
lib = libs_path + "libczmq.#{LIBEXT}"
132133
Dir.chdir czmq_path do
133134
sys "./autogen.sh", "CZMQ autogen failed!" unless File.exist?(czmq_path + 'configure')
134-
sys "./configure LDFLAGS=-L#{libs_path} CFLAGS='#{CZMQ_CFLAGS.join(" ")}' --prefix=#{dst_path} --with-libzmq=#{dst_path} --disable-shared",
135+
sys "./configure LDFLAGS='-L#{libs_path} -lm' CFLAGS='#{CZMQ_CFLAGS.join(" ")}' --prefix=#{dst_path} --disable-shared --enable-static --with-libsodium=#{dst_path}",
135136
"CZMQ configure error!" unless File.exist?(czmq_path + 'Makefile')
136137
sys "make all && make install", "CZMQ compile error!"
137138
end
@@ -143,7 +144,7 @@ def check_heads heads = [], fatal = false
143144
have_func('rb_thread_blocking_region')
144145
have_func('rb_thread_call_without_gvl')
145146

146-
$INCFLAGS << " -I#{libsodium_include_path}" if find_header("sodidum.h", libsodium_include_path)
147+
$INCFLAGS << " -I#{libsodium_include_path}" if find_header("sodium.h", libsodium_include_path)
147148
$INCFLAGS << " -I#{zmq_include_path}" if find_header("zmq.h", zmq_include_path)
148149
$INCFLAGS << " -I#{czmq_include_path}" if find_header("czmq.h", czmq_include_path)
149150

@@ -154,13 +155,14 @@ def check_heads heads = [], fatal = false
154155
CONFIG['LDSHARED'] = "#{CONFIG['LDSHARED']} -Wl,-rpath=#{libs_path.to_s}"
155156
end
156157

158+
fail "Error compiling and linking libsodium" unless have_library("sodium")
157159
fail "Error compiling and linking libzmq" unless have_library("zmq")
158160
fail "Error compiling and linking libczmq" unless have_library("czmq")
159161

160162
$defs << "-pedantic"
161163

162164
$CFLAGS << ' -Wall -funroll-loops'
163165
$CFLAGS << ' -Wextra -O0 -ggdb3' if ENV['DEBUG']
164-
$LDFLAGS << " -Wl,-rpath,ext/rbczmq/dst/lib/"
166+
$LDFLAGS << " -Wl,-rpath,'$$ORIGIN/dst/lib/'"
165167

166168
create_makefile('rbczmq_ext')

ext/rbczmq/socket.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1737,6 +1737,39 @@ static VALUE rb_czmq_socket_opt_last_endpoint(VALUE obj)
17371737
return result;
17381738
}
17391739

1740+
/*
1741+
* call-seq:
1742+
* sock.stream_notify = false => nil
1743+
*
1744+
* Sets the socket stream_notify value.
1745+
*
1746+
* === Examples
1747+
* ctx = ZMQ::Context.new
1748+
* sock = ctx.socket(:STREAM)
1749+
* sock.stream_notify = false => nil
1750+
*
1751+
*/
1752+
1753+
static VALUE rb_czmq_socket_set_opt_stream_notify(VALUE obj, VALUE value)
1754+
{
1755+
int rc, optval;
1756+
zmq_sock_wrapper *sock = NULL;
1757+
1758+
GetZmqSocket(obj);
1759+
ZmqSockGuardCrossThread(sock);
1760+
CheckBoolean(value);
1761+
optval = (value == Qtrue) ? 1 : 0;
1762+
1763+
rc = zmq_setsockopt(sock->socket, ZMQ_STREAM_NOTIFY, &optval, sizeof(optval));
1764+
ZmqAssert(rc);
1765+
1766+
if (sock->verbose)
1767+
zclock_log ("I: %s socket %p: set option \"STREAM_NOTIFY\" %d",
1768+
zsocket_type_str(sock->socket), (void *)obj, optval);
1769+
1770+
return Qnil;
1771+
}
1772+
17401773
/*
17411774
* :nodoc:
17421775
* Receives a monitoring event message while the GIL is released.
@@ -1974,4 +2007,5 @@ void _init_rb_czmq_socket()
19742007
rb_define_method(rb_cZmqSocket, "sndtimeo=", rb_czmq_socket_set_opt_sndtimeo, 1);
19752008
rb_define_method(rb_cZmqSocket, "monitor", rb_czmq_socket_monitor, -1);
19762009
rb_define_method(rb_cZmqSocket, "last_endpoint", rb_czmq_socket_opt_last_endpoint, 0);
2010+
rb_define_method(rb_cZmqStreamSocket, "stream_notify=", rb_czmq_socket_set_opt_stream_notify, 1);
19772011
}

ext/rbczmq/socket.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,11 @@ extern VALUE intern_on_disconnected;
156156
void _init_rb_czmq_socket();
157157
VALUE rb_czmq_nogvl_zsocket_destroy(void *ptr);
158158

159+
#if (ZMQ_VERSION_MAJOR == 4 && ZMQ_VERSION_MINOR >= 1)
160+
typedef struct {
161+
uint16_t event; // id of the event as bitfield
162+
int32_t value; // value is either error code, fd or reconnect interval
163+
} zmq_event_t;
164+
#endif
165+
159166
#endif

ext/zeromq

Submodule zeromq updated 521 files

rbczmq.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@ Gem::Specification.new do |s|
3434
end
3535
end
3636
end
37-
end
37+
end

0 commit comments

Comments
 (0)