polyphony 0.57.0 → 0.60

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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -0
  3. data/Gemfile.lock +15 -29
  4. data/examples/core/message_based_supervision.rb +51 -0
  5. data/ext/polyphony/backend_common.c +108 -3
  6. data/ext/polyphony/backend_common.h +23 -0
  7. data/ext/polyphony/backend_io_uring.c +117 -39
  8. data/ext/polyphony/backend_io_uring_context.c +11 -3
  9. data/ext/polyphony/backend_io_uring_context.h +5 -3
  10. data/ext/polyphony/backend_libev.c +92 -30
  11. data/ext/polyphony/extconf.rb +2 -2
  12. data/ext/polyphony/fiber.c +1 -34
  13. data/ext/polyphony/polyphony.c +12 -19
  14. data/ext/polyphony/polyphony.h +10 -20
  15. data/ext/polyphony/polyphony_ext.c +0 -4
  16. data/ext/polyphony/queue.c +12 -12
  17. data/ext/polyphony/runqueue.c +17 -85
  18. data/ext/polyphony/runqueue.h +27 -0
  19. data/ext/polyphony/thread.c +10 -99
  20. data/lib/polyphony/core/timer.rb +2 -2
  21. data/lib/polyphony/extensions/fiber.rb +102 -82
  22. data/lib/polyphony/extensions/io.rb +10 -9
  23. data/lib/polyphony/extensions/openssl.rb +14 -4
  24. data/lib/polyphony/extensions/socket.rb +15 -15
  25. data/lib/polyphony/extensions/thread.rb +8 -0
  26. data/lib/polyphony/version.rb +1 -1
  27. data/polyphony.gemspec +0 -7
  28. data/test/test_backend.rb +71 -5
  29. data/test/test_ext.rb +1 -1
  30. data/test/test_fiber.rb +106 -18
  31. data/test/test_global_api.rb +1 -1
  32. data/test/test_io.rb +29 -0
  33. data/test/test_supervise.rb +100 -100
  34. data/test/test_thread.rb +57 -11
  35. data/test/test_thread_pool.rb +1 -1
  36. data/test/test_trace.rb +28 -49
  37. metadata +4 -108
  38. data/ext/polyphony/tracing.c +0 -11
  39. data/lib/polyphony/adapters/trace.rb +0 -138
@@ -25,6 +25,8 @@ void context_store_initialize(op_context_store_t *store) {
25
25
  store->last_id = 0;
26
26
  store->available = NULL;
27
27
  store->taken = NULL;
28
+ store->available_count = 0;
29
+ store->taken_count = 0;
28
30
  }
29
31
 
30
32
  inline op_context_t *context_store_acquire(op_context_store_t *store, enum op_type type) {
@@ -32,13 +34,12 @@ inline op_context_t *context_store_acquire(op_context_store_t *store, enum op_ty
32
34
  if (ctx) {
33
35
  if (ctx->next) ctx->next->prev = NULL;
34
36
  store->available = ctx->next;
37
+ store->available_count--;
35
38
  }
36
39
  else {
37
40
  ctx = malloc(sizeof(op_context_t));
38
41
  }
39
42
  ctx->id = (++store->last_id);
40
- // printf("acquire %d (%s)\n", ctx->id, op_type_to_str(type));
41
-
42
43
  ctx->prev = NULL;
43
44
  ctx->next = store->taken;
44
45
  if (store->taken) store->taken->prev = ctx;
@@ -50,18 +51,25 @@ inline op_context_t *context_store_acquire(op_context_store_t *store, enum op_ty
50
51
  ctx->ref_count = 2;
51
52
  ctx->result = 0;
52
53
 
54
+ store->taken_count++;
55
+
56
+ // printf("acquire %p %d (%s, ref_count: %d) taken: %d\n", ctx, ctx->id, op_type_to_str(type), ctx->ref_count, store->taken_count);
57
+
53
58
  return ctx;
54
59
  }
55
60
 
56
61
  // returns true if ctx was released
57
62
  inline int context_store_release(op_context_store_t *store, op_context_t *ctx) {
58
- // printf("release %d (%s, ref_count: %d)\n", ctx->id, op_type_to_str(ctx->type), ctx->ref_count);
63
+ // printf("release %p %d (%s, ref_count: %d)\n", ctx, ctx->id, op_type_to_str(ctx->type), ctx->ref_count);
59
64
 
60
65
  assert(ctx->ref_count);
61
66
 
62
67
  ctx->ref_count--;
63
68
  if (ctx->ref_count) return 0;
64
69
 
70
+ store->taken_count--;
71
+ store->available_count++;
72
+
65
73
  if (ctx->next) ctx->next->prev = ctx->prev;
66
74
  if (ctx->prev) ctx->prev->next = ctx->next;
67
75
  if (store->taken == ctx) store->taken = ctx->next;
@@ -22,7 +22,7 @@ typedef struct op_context {
22
22
  struct op_context *prev;
23
23
  struct op_context *next;
24
24
  enum op_type type: 16;
25
- unsigned int ref_count : 16;
25
+ unsigned int ref_count : 16;
26
26
  int id;
27
27
  int result;
28
28
  VALUE fiber;
@@ -31,8 +31,10 @@ typedef struct op_context {
31
31
 
32
32
  typedef struct op_context_store {
33
33
  int last_id;
34
- op_context_t *available;
35
- op_context_t *taken;
34
+ op_context_t *available;
35
+ op_context_t *taken;
36
+ int available_count;
37
+ int taken_count;
36
38
  } op_context_store_t;
37
39
 
38
40
  const char *op_type_to_str(enum op_type type);
@@ -73,13 +73,23 @@ typedef struct Backend_t {
73
73
  struct ev_async break_async;
74
74
  } Backend_t;
75
75
 
76
+ static void Backend_mark(void *ptr) {
77
+ Backend_t *backend = ptr;
78
+ backend_base_mark(&backend->base);
79
+ }
80
+
81
+ static void Backend_free(void *ptr) {
82
+ Backend_t *backend = ptr;
83
+ backend_base_finalize(&backend->base);
84
+ }
85
+
76
86
  static size_t Backend_size(const void *ptr) {
77
87
  return sizeof(Backend_t);
78
88
  }
79
89
 
80
90
  static const rb_data_type_t Backend_type = {
81
91
  "LibevBackend",
82
- {0, 0, Backend_size,},
92
+ {Backend_mark, Backend_free, Backend_size,},
83
93
  0, 0, RUBY_TYPED_FREE_IMMEDIATELY
84
94
  };
85
95
 
@@ -110,6 +120,8 @@ static VALUE Backend_initialize(VALUE self) {
110
120
  Backend_t *backend;
111
121
 
112
122
  GetBackend(self, backend);
123
+
124
+ backend_base_initialize(&backend->base);
113
125
  backend->ev_loop = libev_new_loop();
114
126
 
115
127
  // start async watcher used for breaking a poll op (from another thread)
@@ -119,11 +131,6 @@ static VALUE Backend_initialize(VALUE self) {
119
131
  // block when no other watcher is active
120
132
  ev_unref(backend->ev_loop);
121
133
 
122
- backend->base.currently_polling = 0;
123
- backend->base.pending_count = 0;
124
- backend->base.idle_gc_period = 0;
125
- backend->base.idle_gc_last_time = 0;
126
-
127
134
  return Qnil;
128
135
  }
129
136
 
@@ -153,24 +160,38 @@ VALUE Backend_post_fork(VALUE self) {
153
160
  return self;
154
161
  }
155
162
 
156
- inline unsigned int Backend_pending_count(VALUE self) {
163
+ inline VALUE Backend_poll(VALUE self, VALUE blocking) {
157
164
  Backend_t *backend;
158
165
  GetBackend(self, backend);
159
166
 
160
- return backend->base.pending_count;
167
+ COND_TRACE(&backend->base, 2, SYM_fiber_event_poll_enter, rb_fiber_current());
168
+ backend->base.currently_polling = 1;
169
+ ev_run(backend->ev_loop, blocking == Qtrue ? EVRUN_ONCE : EVRUN_NOWAIT);
170
+ backend->base.currently_polling = 0;
171
+ COND_TRACE(&backend->base, 2, SYM_fiber_event_poll_leave, rb_fiber_current());
172
+
173
+ return self;
161
174
  }
162
175
 
163
- VALUE Backend_poll(VALUE self, VALUE nowait, VALUE current_fiber, VALUE runqueue) {
176
+ inline void Backend_schedule_fiber(VALUE thread, VALUE self, VALUE fiber, VALUE value, int prioritize) {
164
177
  Backend_t *backend;
165
178
  GetBackend(self, backend);
166
179
 
167
- COND_TRACE(2, SYM_fiber_event_poll_enter, current_fiber);
168
- backend->base.currently_polling = 1;
169
- ev_run(backend->ev_loop, nowait == Qtrue ? EVRUN_NOWAIT : EVRUN_ONCE);
170
- backend->base.currently_polling = 0;
171
- COND_TRACE(2, SYM_fiber_event_poll_leave, current_fiber);
180
+ backend_base_schedule_fiber(thread, self, &backend->base, fiber, value, prioritize);
181
+ }
172
182
 
173
- return self;
183
+ inline void Backend_unschedule_fiber(VALUE self, VALUE fiber) {
184
+ Backend_t *backend;
185
+ GetBackend(self, backend);
186
+
187
+ runqueue_delete(&backend->base.runqueue, fiber);
188
+ }
189
+
190
+ inline VALUE Backend_switch_fiber(VALUE self) {
191
+ Backend_t *backend;
192
+ GetBackend(self, backend);
193
+
194
+ return backend_base_switch_fiber(self, &backend->base);
174
195
  }
175
196
 
176
197
  VALUE Backend_wakeup(VALUE self) {
@@ -190,6 +211,16 @@ VALUE Backend_wakeup(VALUE self) {
190
211
  return Qnil;
191
212
  }
192
213
 
214
+ inline struct backend_stats Backend_stats(VALUE self) {
215
+ Backend_t *backend;
216
+ GetBackend(self, backend);
217
+
218
+ return (struct backend_stats){
219
+ .scheduled_fibers = runqueue_len(&backend->base.runqueue),
220
+ .pending_ops = backend->base.pending_count
221
+ };
222
+ }
223
+
193
224
  struct libev_io {
194
225
  struct ev_io io;
195
226
  VALUE fiber;
@@ -229,14 +260,20 @@ VALUE libev_wait_fd(Backend_t *backend, int fd, int events, int raise_exception)
229
260
  return switchpoint_result;
230
261
  }
231
262
 
232
- VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof) {
263
+ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof, VALUE pos) {
233
264
  Backend_t *backend;
234
265
  struct libev_io watcher;
235
266
  rb_io_t *fptr;
236
267
  long dynamic_len = length == Qnil;
237
268
  long len = dynamic_len ? 4096 : NUM2INT(length);
238
- int shrinkable = io_setstrbuf(&str, len);
239
- char *buf = RSTRING_PTR(str);
269
+ long buf_pos = NUM2INT(pos);
270
+ if (str != Qnil) {
271
+ int current_len = RSTRING_LEN(str);
272
+ if (buf_pos < 0 || buf_pos > current_len) buf_pos = current_len;
273
+ }
274
+ else buf_pos = 0;
275
+ int shrinkable = io_setstrbuf(&str, buf_pos + len);
276
+ char *buf = RSTRING_PTR(str) + buf_pos;
240
277
  long total = 0;
241
278
  VALUE switchpoint_result = Qnil;
242
279
  int read_to_eof = RTEST(to_eof);
@@ -272,9 +309,9 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof)
272
309
  if (total == len) {
273
310
  if (!dynamic_len) break;
274
311
 
275
- rb_str_resize(str, total);
312
+ rb_str_resize(str, buf_pos + total);
276
313
  rb_str_modify_expand(str, len);
277
- buf = RSTRING_PTR(str) + total;
314
+ buf = RSTRING_PTR(str) + buf_pos + total;
278
315
  shrinkable = 0;
279
316
  len += len;
280
317
  }
@@ -282,7 +319,7 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof)
282
319
  }
283
320
  }
284
321
 
285
- io_set_read_length(str, total, shrinkable);
322
+ io_set_read_length(str, buf_pos + total, shrinkable);
286
323
  io_enc_str(str, fptr);
287
324
 
288
325
  if (total == 0) return Qnil;
@@ -295,17 +332,17 @@ error:
295
332
  return RAISE_EXCEPTION(switchpoint_result);
296
333
  }
297
334
 
298
- VALUE Backend_recv(VALUE self, VALUE io, VALUE str, VALUE length) {
299
- return Backend_read(self, io, str, length, Qnil);
335
+ VALUE Backend_recv(VALUE self, VALUE io, VALUE str, VALUE length, VALUE pos) {
336
+ return Backend_read(self, io, str, length, Qnil, pos);
300
337
  }
301
338
 
302
- VALUE Backend_read_loop(VALUE self, VALUE io) {
339
+ VALUE Backend_read_loop(VALUE self, VALUE io, VALUE maxlen) {
303
340
  Backend_t *backend;
304
341
  struct libev_io watcher;
305
342
  rb_io_t *fptr;
306
343
  VALUE str;
307
344
  long total;
308
- long len = 8192;
345
+ long len = NUM2INT(maxlen);
309
346
  int shrinkable;
310
347
  char *buf;
311
348
  VALUE switchpoint_result = Qnil;
@@ -1290,6 +1327,13 @@ VALUE Backend_idle_gc_period_set(VALUE self, VALUE period) {
1290
1327
  return self;
1291
1328
  }
1292
1329
 
1330
+ VALUE Backend_idle_proc_set(VALUE self, VALUE block) {
1331
+ Backend_t *backend;
1332
+ GetBackend(self, backend);
1333
+ backend->base.idle_proc = block;
1334
+ return self;
1335
+ }
1336
+
1293
1337
  inline VALUE Backend_run_idle_tasks(VALUE self) {
1294
1338
  Backend_t *backend;
1295
1339
  GetBackend(self, backend);
@@ -1433,6 +1477,21 @@ error:
1433
1477
  return RAISE_EXCEPTION(result);
1434
1478
  }
1435
1479
 
1480
+ VALUE Backend_trace(int argc, VALUE *argv, VALUE self) {
1481
+ Backend_t *backend;
1482
+ GetBackend(self, backend);
1483
+ backend_trace(&backend->base, argc, argv);
1484
+ return self;
1485
+ }
1486
+
1487
+ VALUE Backend_trace_proc_set(VALUE self, VALUE block) {
1488
+ Backend_t *backend;
1489
+ GetBackend(self, backend);
1490
+
1491
+ backend->base.trace_proc = block;
1492
+ return self;
1493
+ }
1494
+
1436
1495
  void Init_Backend() {
1437
1496
  ev_set_allocator(xrealloc);
1438
1497
 
@@ -1442,22 +1501,25 @@ void Init_Backend() {
1442
1501
  rb_define_method(cBackend, "initialize", Backend_initialize, 0);
1443
1502
  rb_define_method(cBackend, "finalize", Backend_finalize, 0);
1444
1503
  rb_define_method(cBackend, "post_fork", Backend_post_fork, 0);
1504
+ rb_define_method(cBackend, "trace", Backend_trace, -1);
1505
+ rb_define_method(cBackend, "trace_proc=", Backend_trace_proc_set, 1);
1445
1506
 
1446
- rb_define_method(cBackend, "poll", Backend_poll, 3);
1507
+ rb_define_method(cBackend, "poll", Backend_poll, 1);
1447
1508
  rb_define_method(cBackend, "break", Backend_wakeup, 0);
1448
1509
  rb_define_method(cBackend, "kind", Backend_kind, 0);
1449
1510
  rb_define_method(cBackend, "chain", Backend_chain, -1);
1450
1511
  rb_define_method(cBackend, "idle_gc_period=", Backend_idle_gc_period_set, 1);
1512
+ rb_define_method(cBackend, "idle_proc=", Backend_idle_proc_set, 1);
1451
1513
  rb_define_method(cBackend, "splice_chunks", Backend_splice_chunks, 7);
1452
1514
 
1453
1515
  rb_define_method(cBackend, "accept", Backend_accept, 2);
1454
1516
  rb_define_method(cBackend, "accept_loop", Backend_accept_loop, 2);
1455
1517
  rb_define_method(cBackend, "connect", Backend_connect, 3);
1456
1518
  rb_define_method(cBackend, "feed_loop", Backend_feed_loop, 3);
1457
- rb_define_method(cBackend, "read", Backend_read, 4);
1458
- rb_define_method(cBackend, "read_loop", Backend_read_loop, 1);
1459
- rb_define_method(cBackend, "recv", Backend_recv, 3);
1460
- rb_define_method(cBackend, "recv_loop", Backend_read_loop, 1);
1519
+ rb_define_method(cBackend, "read", Backend_read, 5);
1520
+ rb_define_method(cBackend, "read_loop", Backend_read_loop, 2);
1521
+ rb_define_method(cBackend, "recv", Backend_recv, 4);
1522
+ rb_define_method(cBackend, "recv_loop", Backend_read_loop, 2);
1461
1523
  rb_define_method(cBackend, "recv_feed_loop", Backend_feed_loop, 3);
1462
1524
  rb_define_method(cBackend, "send", Backend_send, 3);
1463
1525
  rb_define_method(cBackend, "sendv", Backend_sendv, 3);
@@ -8,8 +8,8 @@ use_pidfd_open = false
8
8
  force_use_libev = ENV['POLYPHONY_USE_LIBEV'] != nil
9
9
  linux = RUBY_PLATFORM =~ /linux/
10
10
 
11
- if linux && `uname -sr` =~ /Linux 5\.([\d+])/
12
- kernel_minor_version = $1.gsub('.', '').to_i
11
+ if linux && `uname -sr` =~ /Linux 5\.(\d+)/
12
+ kernel_minor_version = $1.to_i
13
13
  use_liburing = !force_use_libev && kernel_minor_version >= 6
14
14
  use_pidfd_open = kernel_minor_version >= 3
15
15
  end
@@ -1,6 +1,5 @@
1
1
  #include "polyphony.h"
2
2
 
3
- ID ID_fiber_trace;
4
3
  ID ID_ivar_auto_watcher;
5
4
  ID ID_ivar_mailbox;
6
5
  ID ID_ivar_result;
@@ -82,34 +81,6 @@ static VALUE Fiber_state(VALUE self) {
82
81
  return SYM_waiting;
83
82
  }
84
83
 
85
- VALUE Fiber_await(VALUE self) {
86
- VALUE result;
87
-
88
- // we compare with false, since a fiber that has not yet started will have
89
- // @running set to nil
90
- if (rb_ivar_get(self, ID_ivar_running) == Qfalse) {
91
- result = rb_ivar_get(self, ID_ivar_result);
92
- RAISE_IF_EXCEPTION(result);
93
- return result;
94
- }
95
-
96
- VALUE fiber = rb_fiber_current();
97
- VALUE waiting_fibers = rb_ivar_get(self, ID_ivar_waiting_fibers);
98
- if (waiting_fibers == Qnil) {
99
- waiting_fibers = rb_hash_new();
100
- rb_ivar_set(self, ID_ivar_waiting_fibers, waiting_fibers);
101
- }
102
- rb_hash_aset(waiting_fibers, fiber, Qtrue);
103
-
104
- VALUE backend = rb_ivar_get(rb_thread_current(), ID_ivar_backend);
105
- result = Backend_wait_event(backend, Qnil);
106
-
107
- rb_hash_delete(waiting_fibers, fiber);
108
- RAISE_IF_EXCEPTION(result);
109
- RB_GC_GUARD(result);
110
- return result;
111
- }
112
-
113
84
  VALUE Fiber_send(VALUE self, VALUE value) {
114
85
  VALUE mailbox = rb_ivar_get(self, ID_ivar_mailbox);
115
86
  if (mailbox == Qnil) {
@@ -126,7 +97,7 @@ VALUE Fiber_receive(VALUE self) {
126
97
  mailbox = rb_funcall(cQueue, ID_new, 0);
127
98
  rb_ivar_set(self, ID_ivar_mailbox, mailbox);
128
99
  }
129
- return Queue_shift(mailbox);
100
+ return Queue_shift(mailbox);
130
101
  }
131
102
 
132
103
  VALUE Fiber_mailbox(VALUE self) {
@@ -151,9 +122,6 @@ void Init_Fiber() {
151
122
  rb_define_method(cFiber, "state", Fiber_state, 0);
152
123
  rb_define_method(cFiber, "auto_watcher", Fiber_auto_watcher, 0);
153
124
 
154
- rb_define_method(cFiber, "await", Fiber_await, 0);
155
- rb_define_method(cFiber, "join", Fiber_await, 0);
156
-
157
125
  rb_define_method(cFiber, "<<", Fiber_send, 1);
158
126
  rb_define_method(cFiber, "send", Fiber_send, 1);
159
127
  rb_define_method(cFiber, "receive", Fiber_receive, 0);
@@ -169,7 +137,6 @@ void Init_Fiber() {
169
137
  rb_global_variable(&SYM_runnable);
170
138
  rb_global_variable(&SYM_waiting);
171
139
 
172
- ID_fiber_trace = rb_intern("__fiber_trace__");
173
140
  ID_ivar_auto_watcher = rb_intern("@auto_watcher");
174
141
  ID_ivar_mailbox = rb_intern("@mailbox");
175
142
  ID_ivar_result = rb_intern("@result");
@@ -42,11 +42,6 @@ static VALUE Polyphony_suspend(VALUE self) {
42
42
  return ret;
43
43
  }
44
44
 
45
- VALUE Polyphony_trace(VALUE self, VALUE enabled) {
46
- __tracing_enabled__ = RTEST(enabled) ? 1 : 0;
47
- return Qnil;
48
- }
49
-
50
45
  VALUE Polyphony_backend_accept(VALUE self, VALUE server_socket, VALUE socket_class) {
51
46
  return Backend_accept(BACKEND(), server_socket, socket_class);
52
47
  }
@@ -63,20 +58,20 @@ VALUE Polyphony_backend_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE me
63
58
  return Backend_feed_loop(BACKEND(), io, receiver, method);
64
59
  }
65
60
 
66
- VALUE Polyphony_backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof) {
67
- return Backend_read(BACKEND(), io, str, length, to_eof);
61
+ VALUE Polyphony_backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof, VALUE pos) {
62
+ return Backend_read(BACKEND(), io, str, length, to_eof, pos);
68
63
  }
69
64
 
70
- VALUE Polyphony_backend_read_loop(VALUE self, VALUE io) {
71
- return Backend_read_loop(BACKEND(), io);
65
+ VALUE Polyphony_backend_read_loop(VALUE self, VALUE io, VALUE maxlen) {
66
+ return Backend_read_loop(BACKEND(), io, maxlen);
72
67
  }
73
68
 
74
- VALUE Polyphony_backend_recv(VALUE self, VALUE io, VALUE str, VALUE length) {
75
- return Backend_recv(BACKEND(), io, str, length);
69
+ VALUE Polyphony_backend_recv(VALUE self, VALUE io, VALUE str, VALUE length, VALUE pos) {
70
+ return Backend_recv(BACKEND(), io, str, length, pos);
76
71
  }
77
72
 
78
- VALUE Polyphony_backend_recv_loop(VALUE self, VALUE io) {
79
- return Backend_recv_loop(BACKEND(), io);
73
+ VALUE Polyphony_backend_recv_loop(VALUE self, VALUE io, VALUE maxlen) {
74
+ return Backend_recv_loop(BACKEND(), io, maxlen);
80
75
  }
81
76
 
82
77
  VALUE Polyphony_backend_recv_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE method) {
@@ -130,17 +125,15 @@ VALUE Polyphony_backend_write(int argc, VALUE *argv, VALUE self) {
130
125
  void Init_Polyphony() {
131
126
  mPolyphony = rb_define_module("Polyphony");
132
127
 
133
- rb_define_singleton_method(mPolyphony, "trace", Polyphony_trace, 1);
134
-
135
128
  // backend methods
136
129
  rb_define_singleton_method(mPolyphony, "backend_accept", Polyphony_backend_accept, 2);
137
130
  rb_define_singleton_method(mPolyphony, "backend_accept_loop", Polyphony_backend_accept_loop, 2);
138
131
  rb_define_singleton_method(mPolyphony, "backend_connect", Polyphony_backend_connect, 3);
139
132
  rb_define_singleton_method(mPolyphony, "backend_feed_loop", Polyphony_backend_feed_loop, 3);
140
- rb_define_singleton_method(mPolyphony, "backend_read", Polyphony_backend_read, 4);
141
- rb_define_singleton_method(mPolyphony, "backend_read_loop", Polyphony_backend_read_loop, 1);
142
- rb_define_singleton_method(mPolyphony, "backend_recv", Polyphony_backend_recv, 3);
143
- rb_define_singleton_method(mPolyphony, "backend_recv_loop", Polyphony_backend_recv_loop, 1);
133
+ rb_define_singleton_method(mPolyphony, "backend_read", Polyphony_backend_read, 5);
134
+ rb_define_singleton_method(mPolyphony, "backend_read_loop", Polyphony_backend_read_loop, 2);
135
+ rb_define_singleton_method(mPolyphony, "backend_recv", Polyphony_backend_recv, 4);
136
+ rb_define_singleton_method(mPolyphony, "backend_recv_loop", Polyphony_backend_recv_loop, 2);
144
137
  rb_define_singleton_method(mPolyphony, "backend_recv_feed_loop", Polyphony_backend_recv_feed_loop, 3);
145
138
  rb_define_singleton_method(mPolyphony, "backend_send", Polyphony_backend_send, 3);
146
139
  rb_define_singleton_method(mPolyphony, "backend_sendv", Polyphony_backend_sendv, 3);