polyphony 0.59 → 0.62

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,12 +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 %p %d (%s)\n", ctx, ctx->id, op_type_to_str(type));
41
43
  ctx->prev = NULL;
42
44
  ctx->next = store->taken;
43
45
  if (store->taken) store->taken->prev = ctx;
@@ -49,6 +51,10 @@ inline op_context_t *context_store_acquire(op_context_store_t *store, enum op_ty
49
51
  ctx->ref_count = 2;
50
52
  ctx->result = 0;
51
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
+
52
58
  return ctx;
53
59
  }
54
60
 
@@ -61,6 +67,9 @@ inline int context_store_release(op_context_store_t *store, op_context_t *ctx) {
61
67
  ctx->ref_count--;
62
68
  if (ctx->ref_count) return 0;
63
69
 
70
+ store->taken_count--;
71
+ store->available_count++;
72
+
64
73
  if (ctx->next) ctx->next->prev = ctx->prev;
65
74
  if (ctx->prev) ctx->prev->next = ctx->next;
66
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);
@@ -164,6 +164,8 @@ inline VALUE Backend_poll(VALUE self, VALUE blocking) {
164
164
  Backend_t *backend;
165
165
  GetBackend(self, backend);
166
166
 
167
+ backend->base.poll_count++;
168
+
167
169
  COND_TRACE(&backend->base, 2, SYM_fiber_event_poll_enter, rb_fiber_current());
168
170
  backend->base.currently_polling = 1;
169
171
  ev_run(backend->ev_loop, blocking == Qtrue ? EVRUN_ONCE : EVRUN_NOWAIT);
@@ -211,15 +213,11 @@ VALUE Backend_wakeup(VALUE self) {
211
213
  return Qnil;
212
214
  }
213
215
 
214
- inline struct backend_stats Backend_stats(VALUE self) {
216
+ inline struct backend_stats backend_get_stats(VALUE self) {
215
217
  Backend_t *backend;
216
218
  GetBackend(self, backend);
217
219
 
218
- return (struct backend_stats){
219
- .scheduled_fibers = runqueue_len(&backend->base.runqueue),
220
- .waiting_fibers = 0,
221
- .pending_ops = backend->base.pending_count
222
- };
220
+ return backend_base_stats(&backend->base);
223
221
  }
224
222
 
225
223
  struct libev_io {
@@ -261,14 +259,20 @@ VALUE libev_wait_fd(Backend_t *backend, int fd, int events, int raise_exception)
261
259
  return switchpoint_result;
262
260
  }
263
261
 
264
- VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof) {
262
+ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof, VALUE pos) {
265
263
  Backend_t *backend;
266
264
  struct libev_io watcher;
267
265
  rb_io_t *fptr;
268
266
  long dynamic_len = length == Qnil;
269
267
  long len = dynamic_len ? 4096 : NUM2INT(length);
270
- int shrinkable = io_setstrbuf(&str, len);
271
- char *buf = RSTRING_PTR(str);
268
+ long buf_pos = NUM2INT(pos);
269
+ if (str != Qnil) {
270
+ int current_len = RSTRING_LEN(str);
271
+ if (buf_pos < 0 || buf_pos > current_len) buf_pos = current_len;
272
+ }
273
+ else buf_pos = 0;
274
+ int shrinkable = io_setstrbuf(&str, buf_pos + len);
275
+ char *buf = RSTRING_PTR(str) + buf_pos;
272
276
  long total = 0;
273
277
  VALUE switchpoint_result = Qnil;
274
278
  int read_to_eof = RTEST(to_eof);
@@ -284,6 +288,7 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof)
284
288
  OBJ_TAINT(str);
285
289
 
286
290
  while (1) {
291
+ backend->base.op_count++;
287
292
  ssize_t n = read(fptr->fd, buf, len - total);
288
293
  if (n < 0) {
289
294
  int e = errno;
@@ -304,9 +309,9 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof)
304
309
  if (total == len) {
305
310
  if (!dynamic_len) break;
306
311
 
307
- rb_str_resize(str, total);
312
+ rb_str_resize(str, buf_pos + total);
308
313
  rb_str_modify_expand(str, len);
309
- buf = RSTRING_PTR(str) + total;
314
+ buf = RSTRING_PTR(str) + buf_pos + total;
310
315
  shrinkable = 0;
311
316
  len += len;
312
317
  }
@@ -314,7 +319,7 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof)
314
319
  }
315
320
  }
316
321
 
317
- io_set_read_length(str, total, shrinkable);
322
+ io_set_read_length(str, buf_pos + total, shrinkable);
318
323
  io_enc_str(str, fptr);
319
324
 
320
325
  if (total == 0) return Qnil;
@@ -327,17 +332,17 @@ error:
327
332
  return RAISE_EXCEPTION(switchpoint_result);
328
333
  }
329
334
 
330
- VALUE Backend_recv(VALUE self, VALUE io, VALUE str, VALUE length) {
331
- 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);
332
337
  }
333
338
 
334
- VALUE Backend_read_loop(VALUE self, VALUE io) {
339
+ VALUE Backend_read_loop(VALUE self, VALUE io, VALUE maxlen) {
335
340
  Backend_t *backend;
336
341
  struct libev_io watcher;
337
342
  rb_io_t *fptr;
338
343
  VALUE str;
339
344
  long total;
340
- long len = 8192;
345
+ long len = NUM2INT(maxlen);
341
346
  int shrinkable;
342
347
  char *buf;
343
348
  VALUE switchpoint_result = Qnil;
@@ -354,6 +359,7 @@ VALUE Backend_read_loop(VALUE self, VALUE io) {
354
359
  watcher.fiber = Qnil;
355
360
 
356
361
  while (1) {
362
+ backend->base.op_count++;
357
363
  ssize_t n = read(fptr->fd, buf, len);
358
364
  if (n < 0) {
359
365
  int e = errno;
@@ -406,6 +412,7 @@ VALUE Backend_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE method) {
406
412
  watcher.fiber = Qnil;
407
413
 
408
414
  while (1) {
415
+ backend->base.op_count++;
409
416
  ssize_t n = read(fptr->fd, buf, len);
410
417
  if (n < 0) {
411
418
  int e = errno;
@@ -453,6 +460,7 @@ VALUE Backend_write(VALUE self, VALUE io, VALUE str) {
453
460
  watcher.fiber = Qnil;
454
461
 
455
462
  while (left > 0) {
463
+ backend->base.op_count++;
456
464
  ssize_t n = write(fptr->fd, buf, left);
457
465
  if (n < 0) {
458
466
  int e = errno;
@@ -512,6 +520,7 @@ VALUE Backend_writev(VALUE self, VALUE io, int argc, VALUE *argv) {
512
520
  iov_ptr = iov;
513
521
 
514
522
  while (1) {
523
+ backend->base.op_count++;
515
524
  ssize_t n = writev(fptr->fd, iov_ptr, iov_count);
516
525
  if (n < 0) {
517
526
  int e = errno;
@@ -583,6 +592,7 @@ VALUE Backend_accept(VALUE self, VALUE server_socket, VALUE socket_class) {
583
592
  io_verify_blocking_mode(fptr, server_socket, Qfalse);
584
593
  watcher.fiber = Qnil;
585
594
  while (1) {
595
+ backend->base.op_count++;
586
596
  fd = accept(fptr->fd, &addr, &len);
587
597
  if (fd < 0) {
588
598
  int e = errno;
@@ -641,6 +651,7 @@ VALUE Backend_accept_loop(VALUE self, VALUE server_socket, VALUE socket_class) {
641
651
  watcher.fiber = Qnil;
642
652
 
643
653
  while (1) {
654
+ backend->base.op_count++;
644
655
  fd = accept(fptr->fd, &addr, &len);
645
656
  if (fd < 0) {
646
657
  int e = errno;
@@ -700,6 +711,7 @@ VALUE Backend_connect(VALUE self, VALUE sock, VALUE host, VALUE port) {
700
711
  addr.sin_addr.s_addr = inet_addr(host_buf);
701
712
  addr.sin_port = htons(NUM2INT(port));
702
713
 
714
+ backend->base.op_count++;
703
715
  int result = connect(fptr->fd, (struct sockaddr *)&addr, sizeof(addr));
704
716
  if (result < 0) {
705
717
  int e = errno;
@@ -740,6 +752,7 @@ VALUE Backend_send(VALUE self, VALUE io, VALUE str, VALUE flags) {
740
752
  watcher.fiber = Qnil;
741
753
 
742
754
  while (left > 0) {
755
+ backend->base.op_count++;
743
756
  ssize_t n = send(fptr->fd, buf, left, flags_int);
744
757
  if (n < 0) {
745
758
  int e = errno;
@@ -847,6 +860,7 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
847
860
 
848
861
  watcher.ctx.fiber = Qnil;
849
862
  while (1) {
863
+ backend->base.op_count++;
850
864
  len = splice(src_fptr->fd, 0, dest_fptr->fd, 0, NUM2INT(maxlen), 0);
851
865
  if (len < 0) {
852
866
  int e = errno;
@@ -898,6 +912,7 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
898
912
 
899
913
  watcher.ctx.fiber = Qnil;
900
914
  while (1) {
915
+ backend->base.op_count++;
901
916
  len = splice(src_fptr->fd, 0, dest_fptr->fd, 0, NUM2INT(maxlen), 0);
902
917
  if (len < 0) {
903
918
  int e = errno;
@@ -957,6 +972,7 @@ VALUE Backend_fake_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
957
972
  watcher.fiber = Qnil;
958
973
 
959
974
  while (1) {
975
+ backend->base.op_count++;
960
976
  ssize_t n = read(src_fptr->fd, buf, len);
961
977
  if (n < 0) {
962
978
  int e = errno;
@@ -972,6 +988,7 @@ VALUE Backend_fake_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
972
988
  }
973
989
 
974
990
  while (left > 0) {
991
+ backend->base.op_count++;
975
992
  ssize_t n = write(dest_fptr->fd, buf, left);
976
993
  if (n < 0) {
977
994
  int e = errno;
@@ -1032,6 +1049,7 @@ VALUE Backend_fake_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen
1032
1049
  while (1) {
1033
1050
  char *ptr = buf;
1034
1051
  while (1) {
1052
+ backend->base.op_count++;
1035
1053
  ssize_t n = read(src_fptr->fd, ptr, len);
1036
1054
  if (n < 0) {
1037
1055
  int e = errno;
@@ -1049,6 +1067,7 @@ VALUE Backend_fake_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen
1049
1067
  }
1050
1068
 
1051
1069
  while (left > 0) {
1070
+ backend->base.op_count++;
1052
1071
  ssize_t n = write(dest_fptr->fd, ptr, left);
1053
1072
  if (n < 0) {
1054
1073
  int e = errno;
@@ -1088,6 +1107,7 @@ VALUE Backend_wait_io(VALUE self, VALUE io, VALUE write) {
1088
1107
  GetBackend(self, backend);
1089
1108
  GetOpenFile(io, fptr);
1090
1109
 
1110
+ backend->base.op_count++;
1091
1111
  return libev_wait_fd(backend, fptr->fd, events, 1);
1092
1112
  }
1093
1113
 
@@ -1111,6 +1131,7 @@ VALUE Backend_sleep(VALUE self, VALUE duration) {
1111
1131
  watcher.fiber = rb_fiber_current();
1112
1132
  ev_timer_init(&watcher.timer, Backend_timer_callback, NUM2DBL(duration), 0.);
1113
1133
  ev_timer_start(backend->ev_loop, &watcher.timer);
1134
+ backend->base.op_count++;
1114
1135
 
1115
1136
  switchpoint_result = backend_await((struct Backend_base *)backend);
1116
1137
 
@@ -1140,6 +1161,7 @@ noreturn VALUE Backend_timer_loop(VALUE self, VALUE interval) {
1140
1161
  VALUE switchpoint_result = Qnil;
1141
1162
  ev_timer_init(&watcher.timer, Backend_timer_callback, sleep_duration, 0.);
1142
1163
  ev_timer_start(backend->ev_loop, &watcher.timer);
1164
+ backend->base.op_count++;
1143
1165
  switchpoint_result = backend_await((struct Backend_base *)backend);
1144
1166
  ev_timer_stop(backend->ev_loop, &watcher.timer);
1145
1167
  RAISE_IF_EXCEPTION(switchpoint_result);
@@ -1191,6 +1213,7 @@ VALUE Backend_timeout(int argc,VALUE *argv, VALUE self) {
1191
1213
  watcher.resume_value = timeout;
1192
1214
  ev_timer_init(&watcher.timer, Backend_timeout_callback, NUM2DBL(duration), 0.);
1193
1215
  ev_timer_start(backend->ev_loop, &watcher.timer);
1216
+ backend->base.op_count++;
1194
1217
 
1195
1218
  struct Backend_timeout_ctx timeout_ctx = {backend, &watcher};
1196
1219
  result = rb_ensure(Backend_timeout_ensure_safe, Qnil, Backend_timeout_ensure, (VALUE)&timeout_ctx);
@@ -1213,6 +1236,7 @@ VALUE Backend_waitpid(VALUE self, VALUE pid) {
1213
1236
  if (fd >= 0) {
1214
1237
  Backend_t *backend;
1215
1238
  GetBackend(self, backend);
1239
+ backend->base.op_count++;
1216
1240
 
1217
1241
  VALUE resume_value = libev_wait_fd(backend, fd, EV_READ, 0);
1218
1242
  close(fd);
@@ -1256,6 +1280,7 @@ VALUE Backend_waitpid(VALUE self, VALUE pid) {
1256
1280
  watcher.fiber = rb_fiber_current();
1257
1281
  ev_child_init(&watcher.child, Backend_child_callback, NUM2INT(pid), 0);
1258
1282
  ev_child_start(backend->ev_loop, &watcher.child);
1283
+ backend->base.op_count++;
1259
1284
 
1260
1285
  switchpoint_result = backend_await((struct Backend_base *)backend);
1261
1286
 
@@ -1278,6 +1303,7 @@ VALUE Backend_wait_event(VALUE self, VALUE raise) {
1278
1303
 
1279
1304
  ev_async_init(&async, Backend_async_callback);
1280
1305
  ev_async_start(backend->ev_loop, &async);
1306
+ backend->base.op_count++;
1281
1307
 
1282
1308
  switchpoint_result = backend_await((struct Backend_base *)backend);
1283
1309
 
@@ -1341,6 +1367,7 @@ inline int splice_chunks_write(Backend_t *backend, int fd, VALUE str, struct lib
1341
1367
  int len = RSTRING_LEN(str);
1342
1368
  int left = len;
1343
1369
  while (left > 0) {
1370
+ backend->base.op_count++;
1344
1371
  ssize_t n = write(fd, buf, left);
1345
1372
  if (n < 0) {
1346
1373
  int err = errno;
@@ -1401,6 +1428,7 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
1401
1428
  int chunk_len;
1402
1429
  // splice to pipe
1403
1430
  while (1) {
1431
+ backend->base.op_count++;
1404
1432
  chunk_len = splice(src_fptr->fd, 0, pipefd[1], 0, maxlen, 0);
1405
1433
  if (chunk_len < 0) {
1406
1434
  err = errno;
@@ -1426,6 +1454,7 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
1426
1454
 
1427
1455
  int left = chunk_len;
1428
1456
  while (1) {
1457
+ backend->base.op_count++;
1429
1458
  int n = splice(pipefd[0], 0, dest_fptr->fd, 0, left, 0);
1430
1459
  if (n < 0) {
1431
1460
  err = errno;
@@ -1498,6 +1527,7 @@ void Init_Backend() {
1498
1527
  rb_define_method(cBackend, "post_fork", Backend_post_fork, 0);
1499
1528
  rb_define_method(cBackend, "trace", Backend_trace, -1);
1500
1529
  rb_define_method(cBackend, "trace_proc=", Backend_trace_proc_set, 1);
1530
+ rb_define_method(cBackend, "stats", Backend_stats, 0);
1501
1531
 
1502
1532
  rb_define_method(cBackend, "poll", Backend_poll, 1);
1503
1533
  rb_define_method(cBackend, "break", Backend_wakeup, 0);
@@ -1511,10 +1541,10 @@ void Init_Backend() {
1511
1541
  rb_define_method(cBackend, "accept_loop", Backend_accept_loop, 2);
1512
1542
  rb_define_method(cBackend, "connect", Backend_connect, 3);
1513
1543
  rb_define_method(cBackend, "feed_loop", Backend_feed_loop, 3);
1514
- rb_define_method(cBackend, "read", Backend_read, 4);
1515
- rb_define_method(cBackend, "read_loop", Backend_read_loop, 1);
1516
- rb_define_method(cBackend, "recv", Backend_recv, 3);
1517
- rb_define_method(cBackend, "recv_loop", Backend_read_loop, 1);
1544
+ rb_define_method(cBackend, "read", Backend_read, 5);
1545
+ rb_define_method(cBackend, "read_loop", Backend_read_loop, 2);
1546
+ rb_define_method(cBackend, "recv", Backend_recv, 4);
1547
+ rb_define_method(cBackend, "recv_loop", Backend_read_loop, 2);
1518
1548
  rb_define_method(cBackend, "recv_feed_loop", Backend_feed_loop, 3);
1519
1549
  rb_define_method(cBackend, "send", Backend_send, 3);
1520
1550
  rb_define_method(cBackend, "sendv", Backend_sendv, 3);
@@ -1540,6 +1570,8 @@ void Init_Backend() {
1540
1570
  SYM_send = ID2SYM(rb_intern("send"));
1541
1571
  SYM_splice = ID2SYM(rb_intern("splice"));
1542
1572
  SYM_write = ID2SYM(rb_intern("write"));
1573
+
1574
+ backend_setup_stats_symbols();
1543
1575
  }
1544
1576
 
1545
1577
  #endif // POLYPHONY_BACKEND_LIBEV
@@ -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
@@ -81,34 +81,6 @@ static VALUE Fiber_state(VALUE self) {
81
81
  return SYM_waiting;
82
82
  }
83
83
 
84
- VALUE Fiber_await(VALUE self) {
85
- VALUE result;
86
-
87
- // we compare with false, since a fiber that has not yet started will have
88
- // @running set to nil
89
- if (rb_ivar_get(self, ID_ivar_running) == Qfalse) {
90
- result = rb_ivar_get(self, ID_ivar_result);
91
- RAISE_IF_EXCEPTION(result);
92
- return result;
93
- }
94
-
95
- VALUE fiber = rb_fiber_current();
96
- VALUE waiting_fibers = rb_ivar_get(self, ID_ivar_waiting_fibers);
97
- if (waiting_fibers == Qnil) {
98
- waiting_fibers = rb_hash_new();
99
- rb_ivar_set(self, ID_ivar_waiting_fibers, waiting_fibers);
100
- }
101
- rb_hash_aset(waiting_fibers, fiber, Qtrue);
102
-
103
- VALUE backend = rb_ivar_get(rb_thread_current(), ID_ivar_backend);
104
- result = Backend_wait_event(backend, Qnil);
105
-
106
- rb_hash_delete(waiting_fibers, fiber);
107
- RAISE_IF_EXCEPTION(result);
108
- RB_GC_GUARD(result);
109
- return result;
110
- }
111
-
112
84
  VALUE Fiber_send(VALUE self, VALUE value) {
113
85
  VALUE mailbox = rb_ivar_get(self, ID_ivar_mailbox);
114
86
  if (mailbox == Qnil) {
@@ -125,7 +97,7 @@ VALUE Fiber_receive(VALUE self) {
125
97
  mailbox = rb_funcall(cQueue, ID_new, 0);
126
98
  rb_ivar_set(self, ID_ivar_mailbox, mailbox);
127
99
  }
128
- return Queue_shift(mailbox);
100
+ return Queue_shift(mailbox);
129
101
  }
130
102
 
131
103
  VALUE Fiber_mailbox(VALUE self) {
@@ -150,9 +122,6 @@ void Init_Fiber() {
150
122
  rb_define_method(cFiber, "state", Fiber_state, 0);
151
123
  rb_define_method(cFiber, "auto_watcher", Fiber_auto_watcher, 0);
152
124
 
153
- rb_define_method(cFiber, "await", Fiber_await, 0);
154
- rb_define_method(cFiber, "join", Fiber_await, 0);
155
-
156
125
  rb_define_method(cFiber, "<<", Fiber_send, 1);
157
126
  rb_define_method(cFiber, "send", Fiber_send, 1);
158
127
  rb_define_method(cFiber, "receive", Fiber_receive, 0);
@@ -58,20 +58,20 @@ VALUE Polyphony_backend_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE me
58
58
  return Backend_feed_loop(BACKEND(), io, receiver, method);
59
59
  }
60
60
 
61
- VALUE Polyphony_backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof) {
62
- 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);
63
63
  }
64
64
 
65
- VALUE Polyphony_backend_read_loop(VALUE self, VALUE io) {
66
- 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);
67
67
  }
68
68
 
69
- VALUE Polyphony_backend_recv(VALUE self, VALUE io, VALUE str, VALUE length) {
70
- 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);
71
71
  }
72
72
 
73
- VALUE Polyphony_backend_recv_loop(VALUE self, VALUE io) {
74
- 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);
75
75
  }
76
76
 
77
77
  VALUE Polyphony_backend_recv_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE method) {
@@ -130,10 +130,10 @@ void Init_Polyphony() {
130
130
  rb_define_singleton_method(mPolyphony, "backend_accept_loop", Polyphony_backend_accept_loop, 2);
131
131
  rb_define_singleton_method(mPolyphony, "backend_connect", Polyphony_backend_connect, 3);
132
132
  rb_define_singleton_method(mPolyphony, "backend_feed_loop", Polyphony_backend_feed_loop, 3);
133
- rb_define_singleton_method(mPolyphony, "backend_read", Polyphony_backend_read, 4);
134
- rb_define_singleton_method(mPolyphony, "backend_read_loop", Polyphony_backend_read_loop, 1);
135
- rb_define_singleton_method(mPolyphony, "backend_recv", Polyphony_backend_recv, 3);
136
- 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);
137
137
  rb_define_singleton_method(mPolyphony, "backend_recv_feed_loop", Polyphony_backend_recv_feed_loop, 3);
138
138
  rb_define_singleton_method(mPolyphony, "backend_send", Polyphony_backend_send, 3);
139
139
  rb_define_singleton_method(mPolyphony, "backend_sendv", Polyphony_backend_sendv, 3);