polyphony 0.42 → 0.43.4
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 +4 -4
- data/CHANGELOG.md +27 -0
- data/Gemfile.lock +2 -2
- data/README.md +0 -1
- data/TODO.md +1 -2
- data/docs/_config.yml +2 -2
- data/docs/_sass/custom/custom.scss +10 -0
- data/docs/favicon.ico +0 -0
- data/docs/getting-started/overview.md +3 -24
- data/docs/index.md +5 -1
- data/docs/polyphony-logo.png +0 -0
- data/examples/adapters/concurrent-ruby.rb +9 -0
- data/examples/adapters/redis_blpop.rb +12 -0
- data/examples/core/xx-daemon.rb +14 -0
- data/examples/performance/mem-usage.rb +34 -28
- data/examples/performance/thread-vs-fiber/polyphony_server_read_loop.rb +1 -1
- data/ext/polyphony/libev_agent.c +161 -146
- data/ext/polyphony/libev_queue.c +5 -4
- data/ext/polyphony/polyphony.c +0 -6
- data/ext/polyphony/polyphony_ext.c +0 -2
- data/ext/polyphony/thread.c +0 -6
- data/lib/polyphony.rb +26 -10
- data/lib/polyphony/adapters/redis.rb +3 -2
- data/lib/polyphony/core/global_api.rb +5 -3
- data/lib/polyphony/core/resource_pool.rb +19 -9
- data/lib/polyphony/extensions/core.rb +31 -0
- data/lib/polyphony/extensions/fiber.rb +0 -12
- data/lib/polyphony/extensions/io.rb +5 -1
- data/lib/polyphony/extensions/openssl.rb +34 -10
- data/lib/polyphony/extensions/socket.rb +2 -2
- data/lib/polyphony/version.rb +1 -1
- data/test/test_agent.rb +13 -7
- data/test/test_fiber.rb +3 -3
- data/test/test_global_api.rb +48 -15
- data/test/test_resource_pool.rb +12 -0
- data/test/test_socket.rb +5 -4
- data/test/test_throttler.rb +6 -5
- metadata +7 -3
- data/ext/polyphony/socket.c +0 -213
data/test/test_fiber.rb
CHANGED
@@ -482,9 +482,9 @@ class FiberTest < MiniTest::Test
|
|
482
482
|
def test_select_from_multiple_fibers
|
483
483
|
sleep 0
|
484
484
|
buffer = []
|
485
|
-
f1 = spin { sleep 0.
|
486
|
-
f2 = spin { sleep 0.
|
487
|
-
f3 = spin { sleep 0.
|
485
|
+
f1 = spin { sleep 0.1; buffer << :foo; :foo }
|
486
|
+
f2 = spin { sleep 0.3; buffer << :bar; :bar }
|
487
|
+
f3 = spin { sleep 0.5; buffer << :baz; :baz }
|
488
488
|
|
489
489
|
selected, result = Fiber.select(f1, f2, f3)
|
490
490
|
assert_equal :foo, result
|
data/test/test_global_api.rb
CHANGED
@@ -106,7 +106,7 @@ class MoveOnAfterTest < MiniTest::Test
|
|
106
106
|
end
|
107
107
|
t1 = Time.now
|
108
108
|
|
109
|
-
assert t1 - t0 < 0.
|
109
|
+
assert t1 - t0 < 0.1
|
110
110
|
assert_nil v
|
111
111
|
end
|
112
112
|
|
@@ -118,7 +118,7 @@ class MoveOnAfterTest < MiniTest::Test
|
|
118
118
|
end
|
119
119
|
t1 = Time.now
|
120
120
|
|
121
|
-
assert t1 - t0 < 0.
|
121
|
+
assert t1 - t0 < 0.1
|
122
122
|
assert_equal :bar, v
|
123
123
|
end
|
124
124
|
|
@@ -129,7 +129,7 @@ class MoveOnAfterTest < MiniTest::Test
|
|
129
129
|
assert_equal Fiber.current, f.parent
|
130
130
|
v = sleep 1
|
131
131
|
t1 = Time.now
|
132
|
-
assert t1 - t0 < 0.
|
132
|
+
assert t1 - t0 < 0.1
|
133
133
|
assert_equal 'foo', v
|
134
134
|
end
|
135
135
|
end
|
@@ -145,7 +145,7 @@ class CancelAfterTest < MiniTest::Test
|
|
145
145
|
end
|
146
146
|
end
|
147
147
|
t1 = Time.now
|
148
|
-
assert t1 - t0 < 0.
|
148
|
+
assert t1 - t0 < 0.1
|
149
149
|
end
|
150
150
|
|
151
151
|
def test_cancel_after_without_block
|
@@ -157,7 +157,31 @@ class CancelAfterTest < MiniTest::Test
|
|
157
157
|
sleep 1
|
158
158
|
end
|
159
159
|
t1 = Time.now
|
160
|
-
assert t1 - t0 < 0.
|
160
|
+
assert t1 - t0 < 0.1
|
161
|
+
end
|
162
|
+
|
163
|
+
class CustomException < Exception
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_cancel_after_with_custom_exception
|
167
|
+
assert_raises CustomException do
|
168
|
+
cancel_after(0.01, with_exception: CustomException) do
|
169
|
+
sleep 1
|
170
|
+
:foo
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
begin
|
175
|
+
e = nil
|
176
|
+
cancel_after(0.01, with_exception: 'foo') do
|
177
|
+
sleep 1
|
178
|
+
:foo
|
179
|
+
end
|
180
|
+
rescue => e
|
181
|
+
ensure
|
182
|
+
assert_kind_of RuntimeError, e
|
183
|
+
assert_equal 'foo', e.message
|
184
|
+
end
|
161
185
|
end
|
162
186
|
end
|
163
187
|
|
@@ -201,10 +225,13 @@ class SpinLoopTest < MiniTest::Test
|
|
201
225
|
def test_spin_loop_with_rate
|
202
226
|
buffer = []
|
203
227
|
counter = 0
|
204
|
-
|
228
|
+
t0 = Time.now
|
229
|
+
f = spin_loop(rate: 10) { buffer << (counter += 1) }
|
205
230
|
sleep 0.2
|
206
231
|
f.stop
|
207
|
-
|
232
|
+
elapsed = Time.now - t0
|
233
|
+
expected = (elapsed * 10).to_i
|
234
|
+
assert counter >= expected - 1 && counter <= expected + 1
|
208
235
|
end
|
209
236
|
end
|
210
237
|
|
@@ -212,12 +239,15 @@ class ThrottledLoopTest < MiniTest::Test
|
|
212
239
|
def test_throttled_loop
|
213
240
|
buffer = []
|
214
241
|
counter = 0
|
242
|
+
t0 = Time.now
|
215
243
|
f = spin do
|
216
|
-
throttled_loop(
|
244
|
+
throttled_loop(10) { buffer << (counter += 1) }
|
217
245
|
end
|
218
|
-
sleep 0.
|
246
|
+
sleep 0.3
|
219
247
|
f.stop
|
220
|
-
|
248
|
+
elapsed = Time.now - t0
|
249
|
+
expected = (elapsed * 10).to_i
|
250
|
+
assert counter >= expected - 1 && counter <= expected + 1
|
221
251
|
end
|
222
252
|
|
223
253
|
def test_throttled_loop_with_count
|
@@ -243,19 +273,22 @@ class GlobalAPIEtcTest < MiniTest::Test
|
|
243
273
|
|
244
274
|
def test_every
|
245
275
|
buffer = []
|
276
|
+
t0 = Time.now
|
246
277
|
f = spin do
|
247
|
-
every(0.
|
278
|
+
every(0.1) { buffer << 1 }
|
248
279
|
end
|
249
|
-
sleep 0.
|
280
|
+
sleep 0.5
|
250
281
|
f.stop
|
251
|
-
|
282
|
+
elapsed = Time.now - t0
|
283
|
+
expected = (elapsed / 0.1).to_i
|
284
|
+
assert buffer.size >= expected - 2 && buffer.size <= expected + 2
|
252
285
|
end
|
253
286
|
|
254
287
|
def test_sleep
|
255
288
|
t0 = Time.now
|
256
|
-
sleep 0.
|
289
|
+
sleep 0.1
|
257
290
|
elapsed = Time.now - t0
|
258
|
-
assert (0.
|
291
|
+
assert (0.05..0.15).include? elapsed
|
259
292
|
|
260
293
|
f = spin { sleep }
|
261
294
|
snooze
|
data/test/test_resource_pool.rb
CHANGED
@@ -123,4 +123,16 @@ class ResourcePoolTest < MiniTest::Test
|
|
123
123
|
pool.preheat!
|
124
124
|
assert_equal 2, pool.size
|
125
125
|
end
|
126
|
+
|
127
|
+
def test_reentrant_resource_pool
|
128
|
+
resources = [+'a', +'b']
|
129
|
+
pool = Polyphony::ResourcePool.new(limit: 1) { resources.shift }
|
130
|
+
|
131
|
+
pool.acquire do |r|
|
132
|
+
assert_equal 'a', r
|
133
|
+
pool.acquire do |r|
|
134
|
+
assert_equal 'a', r
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
126
138
|
end
|
data/test/test_socket.rb
CHANGED
@@ -8,7 +8,8 @@ class SocketTest < MiniTest::Test
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def test_tcp
|
11
|
-
|
11
|
+
port = rand(1234..5678)
|
12
|
+
server = TCPServer.new('127.0.0.1', port)
|
12
13
|
|
13
14
|
server_fiber = spin do
|
14
15
|
while (socket = server.accept)
|
@@ -21,13 +22,13 @@ class SocketTest < MiniTest::Test
|
|
21
22
|
end
|
22
23
|
|
23
24
|
snooze
|
24
|
-
client = TCPSocket.new('127.0.0.1',
|
25
|
+
client = TCPSocket.new('127.0.0.1', port)
|
25
26
|
client.write("1234\n")
|
26
27
|
assert_equal "1234\n", client.readpartial(8192)
|
27
28
|
client.close
|
28
29
|
ensure
|
29
|
-
server_fiber
|
30
|
-
|
30
|
+
server_fiber&.stop
|
31
|
+
server_fiber&.await
|
31
32
|
server&.close
|
32
33
|
end
|
33
34
|
end
|
data/test/test_throttler.rb
CHANGED
@@ -4,14 +4,15 @@ require_relative 'helper'
|
|
4
4
|
|
5
5
|
class ThrottlerTest < MiniTest::Test
|
6
6
|
def test_throttler_with_rate
|
7
|
-
t = Polyphony::Throttler.new(
|
7
|
+
t = Polyphony::Throttler.new(10)
|
8
8
|
buffer = []
|
9
|
+
t0 = Time.now
|
9
10
|
f = spin { loop { t.process { buffer << 1 } } }
|
10
|
-
sleep 0.
|
11
|
+
sleep 0.2
|
11
12
|
f.stop
|
12
|
-
|
13
|
-
|
14
|
-
assert buffer.size <=
|
13
|
+
elapsed = Time.now - t0
|
14
|
+
expected = (elapsed * 10).to_i
|
15
|
+
assert buffer.size >= expected - 1 && buffer.size <= expected + 1
|
15
16
|
ensure
|
16
17
|
t.stop
|
17
18
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: polyphony
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.43.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-07-
|
11
|
+
date: 2020-07-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -267,6 +267,7 @@ files:
|
|
267
267
|
- docs/assets/img/echo-fibers.svg
|
268
268
|
- docs/assets/img/sleeping-fiber.svg
|
269
269
|
- docs/faq.md
|
270
|
+
- docs/favicon.ico
|
270
271
|
- docs/getting-started/index.md
|
271
272
|
- docs/getting-started/installing.md
|
272
273
|
- docs/getting-started/overview.md
|
@@ -278,10 +279,13 @@ files:
|
|
278
279
|
- docs/main-concepts/extending.md
|
279
280
|
- docs/main-concepts/fiber-scheduling.md
|
280
281
|
- docs/main-concepts/index.md
|
282
|
+
- docs/polyphony-logo.png
|
283
|
+
- examples/adapters/concurrent-ruby.rb
|
281
284
|
- examples/adapters/pg_client.rb
|
282
285
|
- examples/adapters/pg_notify.rb
|
283
286
|
- examples/adapters/pg_pool.rb
|
284
287
|
- examples/adapters/pg_transaction.rb
|
288
|
+
- examples/adapters/redis_blpop.rb
|
285
289
|
- examples/adapters/redis_channels.rb
|
286
290
|
- examples/adapters/redis_client.rb
|
287
291
|
- examples/adapters/redis_pubsub.rb
|
@@ -294,6 +298,7 @@ files:
|
|
294
298
|
- examples/core/xx-at_exit.rb
|
295
299
|
- examples/core/xx-caller.rb
|
296
300
|
- examples/core/xx-channels.rb
|
301
|
+
- examples/core/xx-daemon.rb
|
297
302
|
- examples/core/xx-deadlock.rb
|
298
303
|
- examples/core/xx-deferring-an-operation.rb
|
299
304
|
- examples/core/xx-erlang-style-genserver.rb
|
@@ -386,7 +391,6 @@ files:
|
|
386
391
|
- ext/polyphony/polyphony.c
|
387
392
|
- ext/polyphony/polyphony.h
|
388
393
|
- ext/polyphony/polyphony_ext.c
|
389
|
-
- ext/polyphony/socket.c
|
390
394
|
- ext/polyphony/thread.c
|
391
395
|
- ext/polyphony/tracing.c
|
392
396
|
- lib/polyphony.rb
|
data/ext/polyphony/socket.c
DELETED
@@ -1,213 +0,0 @@
|
|
1
|
-
#include "polyphony.h"
|
2
|
-
#include <sys/socket.h>
|
3
|
-
|
4
|
-
static VALUE cTCPSocket;
|
5
|
-
|
6
|
-
///////////////////////////////////////////////////////////////////////////
|
7
|
-
|
8
|
-
struct rsock_send_arg {
|
9
|
-
int fd, flags;
|
10
|
-
VALUE mesg;
|
11
|
-
struct sockaddr *to;
|
12
|
-
socklen_t tolen;
|
13
|
-
};
|
14
|
-
|
15
|
-
#define StringValue(v) rb_string_value(&(v))
|
16
|
-
#define IS_ADDRINFO(obj) rb_typeddata_is_kind_of((obj), &addrinfo_type)
|
17
|
-
|
18
|
-
VALUE
|
19
|
-
rsock_sockaddr_string_value(volatile VALUE *v)
|
20
|
-
{
|
21
|
-
// VALUE val = *v;
|
22
|
-
// if (IS_ADDRINFO(val)) {
|
23
|
-
// *v = addrinfo_to_sockaddr(val);
|
24
|
-
// }
|
25
|
-
StringValue(*v);
|
26
|
-
return *v;
|
27
|
-
}
|
28
|
-
|
29
|
-
#define SockAddrStringValue(v) rsock_sockaddr_string_value(&(v))
|
30
|
-
#define RSTRING_LENINT(str) rb_long2int(RSTRING_LEN(str))
|
31
|
-
#ifndef RSTRING_SOCKLEN
|
32
|
-
# define RSTRING_SOCKLEN (socklen_t)RSTRING_LENINT
|
33
|
-
#endif
|
34
|
-
|
35
|
-
#if defined __APPLE__
|
36
|
-
# define do_write_retry(code) do {ret = code;} while (ret == -1 && errno == EPROTOTYPE)
|
37
|
-
#else
|
38
|
-
# define do_write_retry(code) ret = code
|
39
|
-
#endif
|
40
|
-
|
41
|
-
VALUE
|
42
|
-
rsock_sendto_blocking(void *data)
|
43
|
-
{
|
44
|
-
struct rsock_send_arg *arg = data;
|
45
|
-
VALUE mesg = arg->mesg;
|
46
|
-
ssize_t ret;
|
47
|
-
do_write_retry(sendto(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg),
|
48
|
-
arg->flags, arg->to, arg->tolen));
|
49
|
-
return (VALUE)ret;
|
50
|
-
}
|
51
|
-
|
52
|
-
VALUE
|
53
|
-
rsock_send_blocking(void *data)
|
54
|
-
{
|
55
|
-
struct rsock_send_arg *arg = data;
|
56
|
-
VALUE mesg = arg->mesg;
|
57
|
-
ssize_t ret;
|
58
|
-
do_write_retry(send(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg),
|
59
|
-
arg->flags));
|
60
|
-
return (VALUE)ret;
|
61
|
-
}
|
62
|
-
|
63
|
-
///////////////////////////////////////////////////////////////////////////
|
64
|
-
|
65
|
-
static VALUE BasicSocket_send(int argc, VALUE *argv, VALUE sock) {
|
66
|
-
VALUE underlying_socket = rb_iv_get(sock, "@io");
|
67
|
-
if (!NIL_P(underlying_socket)) sock = underlying_socket;
|
68
|
-
struct rsock_send_arg arg;
|
69
|
-
VALUE flags, to;
|
70
|
-
rb_io_t *fptr;
|
71
|
-
ssize_t n;
|
72
|
-
rb_blocking_function_t *func;
|
73
|
-
const char *funcname;
|
74
|
-
VALUE agent = Qnil;
|
75
|
-
|
76
|
-
rb_scan_args(argc, argv, "21", &arg.mesg, &flags, &to);
|
77
|
-
|
78
|
-
StringValue(arg.mesg);
|
79
|
-
|
80
|
-
if (!NIL_P(to)) {
|
81
|
-
SockAddrStringValue(to);
|
82
|
-
to = rb_str_new4(to);
|
83
|
-
arg.to = (struct sockaddr *)RSTRING_PTR(to);
|
84
|
-
arg.tolen = RSTRING_SOCKLEN(to);
|
85
|
-
func = rsock_sendto_blocking;
|
86
|
-
funcname = "sendto(2)";
|
87
|
-
}
|
88
|
-
else {
|
89
|
-
func = rsock_send_blocking;
|
90
|
-
funcname = "send(2)";
|
91
|
-
}
|
92
|
-
GetOpenFile(sock, fptr);
|
93
|
-
rb_io_set_nonblock(fptr);
|
94
|
-
arg.fd = fptr->fd;
|
95
|
-
arg.flags = NUM2INT(flags);
|
96
|
-
while ((n = (ssize_t)func(&arg)) < 0) {
|
97
|
-
if (NIL_P(agent))
|
98
|
-
agent = rb_ivar_get(rb_thread_current(), ID_ivar_agent);
|
99
|
-
LibevAgent_wait_io(agent, sock, Qtrue);
|
100
|
-
}
|
101
|
-
return SSIZET2NUM(n);
|
102
|
-
}
|
103
|
-
|
104
|
-
static VALUE BasicSocket_recv(int argc, VALUE *argv, VALUE sock) {
|
105
|
-
VALUE underlying_socket = rb_iv_get(sock, "@io");
|
106
|
-
if (!NIL_P(underlying_socket)) sock = underlying_socket;
|
107
|
-
long len = argc >= 1 ? NUM2LONG(argv[0]) : 8192;
|
108
|
-
if (len < 0) {
|
109
|
-
rb_raise(rb_eArgError, "negative length %ld given", len);
|
110
|
-
}
|
111
|
-
|
112
|
-
rb_io_t *fptr;
|
113
|
-
long n;
|
114
|
-
int shrinkable;
|
115
|
-
VALUE agent = Qnil;
|
116
|
-
|
117
|
-
|
118
|
-
VALUE str = argc >= 3 ? argv[2] : Qnil;
|
119
|
-
|
120
|
-
shrinkable = io_setstrbuf(&str, len);
|
121
|
-
OBJ_TAINT(str);
|
122
|
-
GetOpenFile(sock, fptr);
|
123
|
-
// rb_io_set_nonblock(fptr);
|
124
|
-
rb_io_check_byte_readable(fptr);
|
125
|
-
|
126
|
-
if (len == 0)
|
127
|
-
return str;
|
128
|
-
|
129
|
-
while (1) {
|
130
|
-
n = recv(fptr->fd, RSTRING_PTR(str), len, MSG_DONTWAIT);
|
131
|
-
if (n < 0) {
|
132
|
-
int e = errno;
|
133
|
-
if (e == EWOULDBLOCK || e == EAGAIN) {
|
134
|
-
if (NIL_P(agent))
|
135
|
-
agent = rb_ivar_get(rb_thread_current(), ID_ivar_agent);
|
136
|
-
LibevAgent_wait_io(agent, sock, Qnil);
|
137
|
-
}
|
138
|
-
else
|
139
|
-
rb_syserr_fail(e, strerror(e));
|
140
|
-
// rb_syserr_fail_path(e, fptr->pathv);
|
141
|
-
}
|
142
|
-
else
|
143
|
-
break;
|
144
|
-
}
|
145
|
-
|
146
|
-
io_set_read_length(str, n, shrinkable);
|
147
|
-
io_enc_str(str, fptr);
|
148
|
-
|
149
|
-
if (n == 0)
|
150
|
-
return Qnil;
|
151
|
-
|
152
|
-
return str;
|
153
|
-
}
|
154
|
-
|
155
|
-
static VALUE Socket_accept(VALUE sock) {
|
156
|
-
rb_io_t *fptr;
|
157
|
-
int fd;
|
158
|
-
struct sockaddr addr;
|
159
|
-
socklen_t len = (socklen_t)sizeof addr;
|
160
|
-
VALUE agent = Qnil;
|
161
|
-
|
162
|
-
GetOpenFile(sock, fptr);
|
163
|
-
rb_io_set_nonblock(fptr);
|
164
|
-
|
165
|
-
while (1) {
|
166
|
-
fd = accept(fptr->fd, &addr, &len);
|
167
|
-
|
168
|
-
if (fd < 0) {
|
169
|
-
int e = errno;
|
170
|
-
if (e == EWOULDBLOCK || e == EAGAIN) {
|
171
|
-
if (NIL_P(agent))
|
172
|
-
agent = rb_ivar_get(rb_thread_current(), ID_ivar_agent);
|
173
|
-
LibevAgent_wait_io(agent, sock, Qnil);
|
174
|
-
}
|
175
|
-
else
|
176
|
-
rb_syserr_fail(e, strerror(e));
|
177
|
-
// rb_syserr_fail_path(e, fptr->pathv);
|
178
|
-
}
|
179
|
-
else {
|
180
|
-
VALUE connection = rb_obj_alloc(cTCPSocket);
|
181
|
-
rb_io_t *fp;
|
182
|
-
MakeOpenFile(connection, fp);
|
183
|
-
rb_update_max_fd(fd);
|
184
|
-
fp->fd = fd;
|
185
|
-
fp->mode = FMODE_READWRITE | FMODE_DUPLEX;
|
186
|
-
rb_io_ascii8bit_binmode(connection);
|
187
|
-
rb_io_set_nonblock(fp);
|
188
|
-
rb_io_synchronized(fp);
|
189
|
-
// if (rsock_do_not_reverse_lookup) {
|
190
|
-
// fp->mode |= FMODE_NOREVLOOKUP;
|
191
|
-
// }
|
192
|
-
|
193
|
-
return connection;
|
194
|
-
}
|
195
|
-
}
|
196
|
-
}
|
197
|
-
|
198
|
-
void Init_Socket() {
|
199
|
-
VALUE cBasicSocket;
|
200
|
-
VALUE cSocket;
|
201
|
-
|
202
|
-
rb_require("socket");
|
203
|
-
cBasicSocket = rb_const_get(rb_cObject, rb_intern("BasicSocket"));
|
204
|
-
|
205
|
-
rb_define_method(cBasicSocket, "send", BasicSocket_send, -1);
|
206
|
-
rb_define_method(cBasicSocket, "recv", BasicSocket_recv, -1);
|
207
|
-
|
208
|
-
cSocket = rb_const_get(rb_cObject, rb_intern("Socket"));
|
209
|
-
|
210
|
-
// rb_define_method(cSocket, "accept", Socket_accept, 0);
|
211
|
-
|
212
|
-
cTCPSocket = rb_const_get(rb_cObject, rb_intern("TCPSocket"));
|
213
|
-
}
|