nmsg 0.1.1.pre
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.
- checksums.yaml +7 -0
- data/Gemfile +3 -0
- data/LICENSE +19 -0
- data/Makefile +13 -0
- data/README.md +13 -0
- data/examples/push_pull.rb +44 -0
- data/examples/rep.rb +29 -0
- data/examples/req.rb +45 -0
- data/ext/nmsg/extconf.rb +9 -0
- data/ext/nmsg/rubyext.c +285 -0
- data/nmsg.gemspec +20 -0
- metadata +54 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: eaf25c8d389c83267a1c4f0ce13fd6af22a17c94
|
|
4
|
+
data.tar.gz: d47c26ce0fa8f55a763dcb83bcf07e9875479f82
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 9b27be1a064c4637e685ae1f36f355b2ae2bd2757376b26fea6fcba2c89e547ca47a625e1f8f9b6737892cae291c2f045e72135b408554d1c2659e18400a062f
|
|
7
|
+
data.tar.gz: 21bf0ecc1704c1ecb5289dfab969baf8f9e23b03c5f02d334343df32f3fd8ae65dec1602f1a040e0a44f7a6a3ca9a6665e2226eb444f63038bc9885ccd97660c
|
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2014 Alex Brem
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
|
11
|
+
all copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
+
THE SOFTWARE.
|
data/Makefile
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
CFLAGS ?= -I/opt/local/include -g
|
|
2
|
+
LDFLAGS ?= -L/opt/local/lib -lnanomsg
|
|
3
|
+
|
|
4
|
+
all: nmsg
|
|
5
|
+
|
|
6
|
+
clean:
|
|
7
|
+
@cd ext/nmsg && make distclean || true
|
|
8
|
+
|
|
9
|
+
nmsg: ext/nmsg/extconf.rb ext/nmsg/rubyext.c
|
|
10
|
+
@echo Building Ruby extension 'nmsg'...
|
|
11
|
+
@cd ext/nmsg && CFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}" ruby extconf.rb && make
|
|
12
|
+
|
|
13
|
+
.PHONY: all clean nmsg
|
data/README.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
nmsg
|
|
2
|
+
====
|
|
3
|
+
|
|
4
|
+
Native Ruby binding for the [nanomsg](http://nanomsg.org/) library.
|
|
5
|
+
|
|
6
|
+
**This is incomplete and most likely a bugs galore. So please don't use this right now!**
|
|
7
|
+
|
|
8
|
+
## TODO
|
|
9
|
+
|
|
10
|
+
- [nn_setsockopt](http://nanomsg.org/v0.4/nn_setsockopt.3.html)
|
|
11
|
+
- [nn_getsockopt](http://nanomsg.org/v0.4/nn_getsockopt.3.html)
|
|
12
|
+
- add exceptions ([nn_errno](http://nanomsg.org/v0.4/nn_errno.3.html), [nn_strerror](http://nanomsg.org/v0.4/nn_strerror.3.html))
|
|
13
|
+
- TESTS
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require_relative '../ext/nmsg/nmsg'
|
|
4
|
+
|
|
5
|
+
addr = ARGV.shift || "inproc://6581"
|
|
6
|
+
|
|
7
|
+
Thread.abort_on_exception = true
|
|
8
|
+
|
|
9
|
+
@mutex = Mutex.new
|
|
10
|
+
@sent = @received = 0
|
|
11
|
+
@threads = []
|
|
12
|
+
|
|
13
|
+
MAX_MSG = 50
|
|
14
|
+
|
|
15
|
+
15.times do
|
|
16
|
+
@mutex.synchronize do
|
|
17
|
+
Thread.new do
|
|
18
|
+
push = Nmsg::Socket.new(Nmsg::AF_SP, Nmsg::NN_PUSH)
|
|
19
|
+
eid = push.connect(addr)
|
|
20
|
+
loop do
|
|
21
|
+
cnt = @mutex.synchronize { @sent += 1 }
|
|
22
|
+
Thread.current.exit if cnt > MAX_MSG
|
|
23
|
+
push.send_msg_block("#{Thread.current.object_id}: #{cnt}")
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
pull = Nmsg::Socket.new(Nmsg::AF_SP, Nmsg::NN_PULL)
|
|
30
|
+
pull.bind addr
|
|
31
|
+
|
|
32
|
+
loop do
|
|
33
|
+
ev = pull.poll Nmsg::NN_POLLIN, 50
|
|
34
|
+
raise "Error: nn_poll" if ev.nil?
|
|
35
|
+
if ev
|
|
36
|
+
@received += 1
|
|
37
|
+
puts "pulled data from thread #{pull.recv_msg}"
|
|
38
|
+
else
|
|
39
|
+
break if @received == MAX_MSG
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
@threads.each &:join
|
|
44
|
+
pull.close
|
data/examples/rep.rb
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require_relative '../ext/nmsg/nmsg'
|
|
4
|
+
|
|
5
|
+
socket = Nmsg::Socket.new Nmsg::AF_SP, Nmsg::NN_REP
|
|
6
|
+
puts "fd: #{socket.get_fd} sysfd: #{socket.get_sysfd}"
|
|
7
|
+
|
|
8
|
+
addr = ARGV.shift || "tcp://127.0.0.1:4000"
|
|
9
|
+
endpoint_id = socket.bind addr
|
|
10
|
+
puts "address: #{addr} endpoint id: #{endpoint_id}"
|
|
11
|
+
|
|
12
|
+
trap("SIGINT") do
|
|
13
|
+
puts "Exiting..."
|
|
14
|
+
socket.shutdown endpoint_id
|
|
15
|
+
socket.close
|
|
16
|
+
exit!
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
loop do
|
|
20
|
+
ev = socket.poll Nmsg::NN_POLLIN, 1000
|
|
21
|
+
raise "Error: nn_poll" if ev.nil?
|
|
22
|
+
if ev
|
|
23
|
+
data = socket.recv_msg
|
|
24
|
+
puts "=> HAI [#{data}]"
|
|
25
|
+
sleep Random.rand(1.0/Random.rand(1...100))
|
|
26
|
+
socket.send_msg data.reverse
|
|
27
|
+
puts "<= KTHXBAI [#{data}]"
|
|
28
|
+
end
|
|
29
|
+
end
|
data/examples/req.rb
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require_relative '../ext/nmsg/nmsg'
|
|
4
|
+
|
|
5
|
+
socket = Nmsg::Socket.new Nmsg::AF_SP, Nmsg::NN_REQ
|
|
6
|
+
puts "fd: #{socket.get_fd} sysfd: #{socket.get_sysfd}"
|
|
7
|
+
|
|
8
|
+
addr = ARGV.shift || "tcp://127.0.0.1:4000"
|
|
9
|
+
endpoint_id = socket.connect addr
|
|
10
|
+
puts "address: #{addr} endpoint id: #{endpoint_id}"
|
|
11
|
+
|
|
12
|
+
trap("SIGINT") do
|
|
13
|
+
puts "Exiting..."
|
|
14
|
+
socket.shutdown endpoint_id
|
|
15
|
+
socket.close
|
|
16
|
+
exit!
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
sent = false
|
|
20
|
+
msg = ''
|
|
21
|
+
loop do
|
|
22
|
+
puts "loop (sent: #{sent})"
|
|
23
|
+
unless sent
|
|
24
|
+
ev = socket.poll Nmsg::NN_POLLOUT, 1000
|
|
25
|
+
next if ev.nil?
|
|
26
|
+
if ev
|
|
27
|
+
msg = (0...8).map { ('a'..'z').to_a[rand(26)] }.join
|
|
28
|
+
sent = socket.send_msg_block msg
|
|
29
|
+
end
|
|
30
|
+
if sent
|
|
31
|
+
puts "message sent: #{msg}"
|
|
32
|
+
else
|
|
33
|
+
sleep 1
|
|
34
|
+
end
|
|
35
|
+
else
|
|
36
|
+
ev = socket.poll Nmsg::NN_POLLIN, 1000
|
|
37
|
+
next if ev.nil?
|
|
38
|
+
if ev
|
|
39
|
+
data = socket.recv_msg
|
|
40
|
+
puts "message received: #{data}" if data
|
|
41
|
+
raise "Error: Wrong message! (expected '#{msg.reverse}' and got '#{data}')" unless data && data.reverse.eql?(msg)
|
|
42
|
+
sent = false
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
data/ext/nmsg/extconf.rb
ADDED
data/ext/nmsg/rubyext.c
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
//
|
|
2
|
+
// nmsg /|\ https://github.com/localhost/nmsg
|
|
3
|
+
// a Ruby binding for nanomsg (http://nanomsg.org)
|
|
4
|
+
//
|
|
5
|
+
// Copyright (c) 2014 Alex Brem
|
|
6
|
+
//
|
|
7
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
// of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
// in the Software without restriction, including without limitation the rights
|
|
10
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
// copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
// furnished to do so, subject to the following conditions:
|
|
13
|
+
|
|
14
|
+
// The above copyright notice and this permission notice shall be included in
|
|
15
|
+
// all copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
23
|
+
// THE SOFTWARE.
|
|
24
|
+
//
|
|
25
|
+
|
|
26
|
+
#include <ruby.h>
|
|
27
|
+
|
|
28
|
+
#ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
|
|
29
|
+
# include <ruby/thread.h>
|
|
30
|
+
#endif
|
|
31
|
+
|
|
32
|
+
#include <string.h>
|
|
33
|
+
#include <stdint.h>
|
|
34
|
+
|
|
35
|
+
// core
|
|
36
|
+
#include <nanomsg/nn.h>
|
|
37
|
+
|
|
38
|
+
// protocols
|
|
39
|
+
#include <nanomsg/pair.h>
|
|
40
|
+
#include <nanomsg/reqrep.h>
|
|
41
|
+
#include <nanomsg/pubsub.h>
|
|
42
|
+
#include <nanomsg/survey.h>
|
|
43
|
+
#include <nanomsg/pipeline.h>
|
|
44
|
+
#include <nanomsg/bus.h>
|
|
45
|
+
|
|
46
|
+
// transports
|
|
47
|
+
#include <nanomsg/inproc.h>
|
|
48
|
+
#include <nanomsg/ipc.h>
|
|
49
|
+
#include <nanomsg/tcp.h>
|
|
50
|
+
|
|
51
|
+
#define GET_SOCKET(self) \
|
|
52
|
+
Socket *S; \
|
|
53
|
+
Data_Get_Struct(self, Socket, S)
|
|
54
|
+
|
|
55
|
+
static VALUE mNmsg, cSocket;
|
|
56
|
+
|
|
57
|
+
typedef struct {
|
|
58
|
+
int fd;
|
|
59
|
+
} Socket;
|
|
60
|
+
|
|
61
|
+
static void rb_socket_free(Socket *S) {
|
|
62
|
+
if (S->fd > 0)
|
|
63
|
+
nn_shutdown(S->fd, 0);
|
|
64
|
+
xfree(S);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
VALUE rb_socket_alloc(VALUE klass) {
|
|
68
|
+
Socket *S = ALLOC(Socket);
|
|
69
|
+
S->fd = -1;
|
|
70
|
+
return Data_Wrap_Struct(klass, NULL, rb_socket_free, S);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
VALUE rb_socket_initialize(VALUE self, VALUE domain, VALUE protocol) {
|
|
74
|
+
GET_SOCKET(self);
|
|
75
|
+
if (!S)
|
|
76
|
+
return Qnil;
|
|
77
|
+
|
|
78
|
+
S->fd = nn_socket(NUM2INT(domain), NUM2INT(protocol));
|
|
79
|
+
return self;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
VALUE rb_socket_bind(VALUE self, VALUE addr) {
|
|
83
|
+
GET_SOCKET(self);
|
|
84
|
+
if (!S || S->fd == -1)
|
|
85
|
+
return Qnil;
|
|
86
|
+
|
|
87
|
+
const char *addr_c = StringValueCStr(addr);
|
|
88
|
+
const int endpoint_id = nn_bind(S->fd, addr_c);
|
|
89
|
+
return (endpoint_id == -1) ? Qnil : INT2NUM(endpoint_id);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
VALUE rb_socket_connect(VALUE self, VALUE addr) {
|
|
93
|
+
GET_SOCKET(self);
|
|
94
|
+
if (!S || S->fd == -1)
|
|
95
|
+
return Qnil;
|
|
96
|
+
|
|
97
|
+
const char *addr_c = StringValueCStr(addr);
|
|
98
|
+
const int endpoint_id = nn_connect(S->fd, addr_c);
|
|
99
|
+
return (endpoint_id == -1) ? Qnil : INT2NUM(endpoint_id);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
VALUE rb_socket_poll(VALUE self, VALUE mask, VALUE timeout) {
|
|
103
|
+
GET_SOCKET(self);
|
|
104
|
+
if (!S || S->fd == -1)
|
|
105
|
+
return Qnil;
|
|
106
|
+
|
|
107
|
+
if (timeout == Qnil)
|
|
108
|
+
timeout = INT2NUM(0);
|
|
109
|
+
|
|
110
|
+
struct nn_pollfd pfd;
|
|
111
|
+
pfd.fd = S->fd;
|
|
112
|
+
pfd.events = NUM2INT(mask);
|
|
113
|
+
|
|
114
|
+
const int res = nn_poll(&pfd, 1, NUM2INT(timeout));
|
|
115
|
+
if (res == -1) // error
|
|
116
|
+
return Qnil;
|
|
117
|
+
else if (res == 0) // timeout
|
|
118
|
+
return Qfalse;
|
|
119
|
+
|
|
120
|
+
return (pfd.revents & NUM2INT(mask)) ? Qtrue : Qfalse;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
VALUE rb_socket_recv_msg(VALUE self) {
|
|
124
|
+
GET_SOCKET(self);
|
|
125
|
+
if (!S || S->fd == -1)
|
|
126
|
+
return Qnil;
|
|
127
|
+
|
|
128
|
+
void *buffer;
|
|
129
|
+
const int nbytes = nn_recv(S->fd, &buffer, NN_MSG, NN_DONTWAIT);
|
|
130
|
+
if (nbytes < 0)
|
|
131
|
+
return Qnil;
|
|
132
|
+
|
|
133
|
+
VALUE rs = rb_tainted_str_new(buffer, nbytes);
|
|
134
|
+
nn_freemsg(buffer);
|
|
135
|
+
|
|
136
|
+
return rs;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
VALUE rb_socket_send_msg(VALUE self, VALUE obj) {
|
|
140
|
+
GET_SOCKET(self);
|
|
141
|
+
if (!S || S->fd == -1)
|
|
142
|
+
return Qnil;
|
|
143
|
+
|
|
144
|
+
const int msg_bytes = RSTRING_LEN(obj);
|
|
145
|
+
const char *data = RSTRING_PTR(obj);
|
|
146
|
+
void *msg = nn_allocmsg(msg_bytes, 0);
|
|
147
|
+
if (!msg)
|
|
148
|
+
return Qnil;
|
|
149
|
+
memcpy(msg, data, msg_bytes);
|
|
150
|
+
|
|
151
|
+
const int nbytes = nn_send(S->fd, &msg, NN_MSG, NN_DONTWAIT);
|
|
152
|
+
if (nbytes < 0) {
|
|
153
|
+
nn_freemsg(msg);
|
|
154
|
+
return Qnil;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return (nbytes == msg_bytes) ? Qtrue : Qfalse;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
#ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
|
|
161
|
+
|
|
162
|
+
struct nogvl_msg {
|
|
163
|
+
int fd;
|
|
164
|
+
void **msg;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
static void *nogvl_send_msg(void *p) {
|
|
168
|
+
struct nogvl_msg *wrapper = p;
|
|
169
|
+
return (void *)(intptr_t)nn_send(wrapper->fd, wrapper->msg, NN_MSG, 0);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
VALUE rb_socket_send_msg_block(VALUE self, VALUE obj) {
|
|
173
|
+
GET_SOCKET(self);
|
|
174
|
+
if (!S || S->fd == -1)
|
|
175
|
+
return Qnil;
|
|
176
|
+
|
|
177
|
+
const int msg_bytes = RSTRING_LEN(obj);
|
|
178
|
+
const char *data = RSTRING_PTR(obj);
|
|
179
|
+
void *msg = nn_allocmsg(msg_bytes, 0);
|
|
180
|
+
if (!msg)
|
|
181
|
+
return Qnil;
|
|
182
|
+
memcpy(msg, data, msg_bytes);
|
|
183
|
+
|
|
184
|
+
struct nogvl_msg wrapper = { S->fd, &msg };
|
|
185
|
+
const int nbytes = (int)rb_thread_call_without_gvl(nogvl_send_msg, &wrapper, RUBY_UBF_IO, 0);
|
|
186
|
+
if (nbytes < 0) {
|
|
187
|
+
nn_freemsg(msg);
|
|
188
|
+
return Qnil;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return (nbytes == msg_bytes) ? Qtrue : Qfalse;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
#endif // HAVE_RB_THREAD_CALL_WITHOUT_GVL
|
|
195
|
+
|
|
196
|
+
VALUE rb_socket_close(VALUE self) {
|
|
197
|
+
GET_SOCKET(self);
|
|
198
|
+
if (S && S->fd > 0) {
|
|
199
|
+
nn_close(S->fd);
|
|
200
|
+
S->fd = -1;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return self;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
VALUE rb_socket_shutdown(VALUE self, VALUE how) {
|
|
207
|
+
GET_SOCKET(self);
|
|
208
|
+
if (S && S->fd > 0) {
|
|
209
|
+
nn_shutdown(S->fd, NUM2INT(how));
|
|
210
|
+
S->fd = -1;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return self;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
VALUE rb_socket_get_fd(VALUE self) {
|
|
217
|
+
GET_SOCKET(self);
|
|
218
|
+
return rb_int_new(S->fd);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
VALUE rb_socket_get_sysfd(VALUE self) {
|
|
222
|
+
GET_SOCKET(self);
|
|
223
|
+
|
|
224
|
+
int optval;
|
|
225
|
+
size_t optval_len = sizeof(int);
|
|
226
|
+
const int res = nn_getsockopt(S->fd, NN_SOL_SOCKET, NN_RCVFD, (void *)&optval, &optval_len);
|
|
227
|
+
return INT2NUM((res == 0) ? optval : -1);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
VALUE rb_socket_term(VALUE klass) {
|
|
231
|
+
nn_term();
|
|
232
|
+
return klass;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
VALUE rb_socket_device(VALUE klass, VALUE so1, VALUE so2) {
|
|
236
|
+
Socket *S1;
|
|
237
|
+
Data_Get_Struct(so1, Socket, S1);
|
|
238
|
+
|
|
239
|
+
Socket tmp = { .fd = -1 };
|
|
240
|
+
Socket *S2 = &tmp;
|
|
241
|
+
|
|
242
|
+
if (so2 != Qnil) // FIXME
|
|
243
|
+
Data_Get_Struct(so2, Socket, S2);
|
|
244
|
+
|
|
245
|
+
return nn_device(S1->fd, S2->fd);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
void Init_nmsg() {
|
|
249
|
+
mNmsg = rb_define_module("Nmsg");
|
|
250
|
+
|
|
251
|
+
cSocket = rb_define_class_under(mNmsg, "Socket", rb_cObject);
|
|
252
|
+
rb_define_alloc_func(cSocket, rb_socket_alloc);
|
|
253
|
+
|
|
254
|
+
rb_define_method(cSocket, "initialize", rb_socket_initialize, 2);
|
|
255
|
+
rb_define_method(cSocket, "bind", rb_socket_bind, 1);
|
|
256
|
+
rb_define_method(cSocket, "connect", rb_socket_connect, 1);
|
|
257
|
+
rb_define_method(cSocket, "poll", rb_socket_poll, 2);
|
|
258
|
+
rb_define_method(cSocket, "recv_msg", rb_socket_recv_msg, 0);
|
|
259
|
+
rb_define_method(cSocket, "send_msg", rb_socket_send_msg, 1);
|
|
260
|
+
|
|
261
|
+
#ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
|
|
262
|
+
rb_define_method(cSocket, "send_msg_block", rb_socket_send_msg_block, 1);
|
|
263
|
+
#endif
|
|
264
|
+
|
|
265
|
+
rb_define_method(cSocket, "close", rb_socket_close, 0);
|
|
266
|
+
rb_define_method(cSocket, "shutdown", rb_socket_shutdown, 1);
|
|
267
|
+
|
|
268
|
+
rb_define_method(cSocket, "get_fd", rb_socket_get_fd, 0);
|
|
269
|
+
rb_define_method(cSocket, "get_sysfd", rb_socket_get_sysfd, 0);
|
|
270
|
+
|
|
271
|
+
rb_define_singleton_method(cSocket, "device", rb_socket_device, 2);
|
|
272
|
+
rb_define_singleton_method(cSocket, "term", rb_socket_term, 0);
|
|
273
|
+
|
|
274
|
+
for (int i = 0, value;; ++i) {
|
|
275
|
+
const char *name = nn_symbol(i, &value);
|
|
276
|
+
if (!name)
|
|
277
|
+
break;
|
|
278
|
+
if (strncmp("NN_", name, 3) == 0 || strncmp("AF_", name, 3) == 0)
|
|
279
|
+
rb_const_set(mNmsg, rb_intern(name), INT2NUM(value));
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// nanomsg events (missing from nn_symbol)
|
|
283
|
+
rb_const_set(mNmsg, rb_intern("NN_POLLIN"), INT2NUM(NN_POLLIN));
|
|
284
|
+
rb_const_set(mNmsg, rb_intern("NN_POLLOUT"), INT2NUM(NN_POLLOUT));
|
|
285
|
+
}
|
data/nmsg.gemspec
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Gem::Specification.new do |s|
|
|
2
|
+
s.name = 'nmsg'
|
|
3
|
+
s.version = '0.1.1.pre'
|
|
4
|
+
s.license = 'MIT'
|
|
5
|
+
s.author = 'Alex Brem'
|
|
6
|
+
s.email = 'alex@fluktuation.net'
|
|
7
|
+
s.homepage = 'https://github.com/localhost/nmsg'
|
|
8
|
+
s.summary = %Q{native nanomsg binding}
|
|
9
|
+
s.description = %Q{native binding for the nanomsg c library}
|
|
10
|
+
|
|
11
|
+
s.files = [
|
|
12
|
+
'README.md', 'LICENSE', 'Makefile', 'Gemfile', 'nmsg.gemspec',
|
|
13
|
+
'examples/req.rb', 'examples/rep.rb', 'examples/push_pull.rb',
|
|
14
|
+
'ext/nmsg/extconf.rb', 'ext/nmsg/rubyext.c'
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
s.require_paths = ['lib']
|
|
18
|
+
s.extensions = ["ext/nmsg/extconf.rb"]
|
|
19
|
+
s.has_rdoc = false
|
|
20
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: nmsg
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.1.pre
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Alex Brem
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2014-11-05 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: native binding for the nanomsg c library
|
|
14
|
+
email: alex@fluktuation.net
|
|
15
|
+
executables: []
|
|
16
|
+
extensions:
|
|
17
|
+
- ext/nmsg/extconf.rb
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- Gemfile
|
|
21
|
+
- LICENSE
|
|
22
|
+
- Makefile
|
|
23
|
+
- README.md
|
|
24
|
+
- examples/push_pull.rb
|
|
25
|
+
- examples/rep.rb
|
|
26
|
+
- examples/req.rb
|
|
27
|
+
- ext/nmsg/extconf.rb
|
|
28
|
+
- ext/nmsg/rubyext.c
|
|
29
|
+
- nmsg.gemspec
|
|
30
|
+
homepage: https://github.com/localhost/nmsg
|
|
31
|
+
licenses:
|
|
32
|
+
- MIT
|
|
33
|
+
metadata: {}
|
|
34
|
+
post_install_message:
|
|
35
|
+
rdoc_options: []
|
|
36
|
+
require_paths:
|
|
37
|
+
- lib
|
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
39
|
+
requirements:
|
|
40
|
+
- - ">="
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: '0'
|
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: 1.3.1
|
|
48
|
+
requirements: []
|
|
49
|
+
rubyforge_project:
|
|
50
|
+
rubygems_version: 2.2.2
|
|
51
|
+
signing_key:
|
|
52
|
+
specification_version: 4
|
|
53
|
+
summary: native nanomsg binding
|
|
54
|
+
test_files: []
|