polyphony 0.59 → 0.62
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 +24 -0
- data/Gemfile.lock +15 -29
- data/examples/core/message_based_supervision.rb +51 -0
- data/examples/io/echo_server.rb +16 -7
- data/ext/polyphony/backend_common.c +83 -16
- data/ext/polyphony/backend_common.h +15 -3
- data/ext/polyphony/backend_io_uring.c +58 -25
- data/ext/polyphony/backend_io_uring_context.c +10 -1
- data/ext/polyphony/backend_io_uring_context.h +5 -3
- data/ext/polyphony/backend_libev.c +52 -20
- data/ext/polyphony/extconf.rb +2 -2
- data/ext/polyphony/fiber.c +1 -32
- data/ext/polyphony/polyphony.c +12 -12
- data/ext/polyphony/polyphony.h +4 -5
- data/ext/polyphony/queue.c +12 -12
- data/ext/polyphony/runqueue.c +11 -19
- data/ext/polyphony/runqueue.h +2 -2
- data/ext/polyphony/thread.c +0 -18
- data/lib/polyphony/core/timer.rb +2 -2
- data/lib/polyphony/extensions/fiber.rb +100 -80
- data/lib/polyphony/extensions/io.rb +10 -9
- data/lib/polyphony/extensions/openssl.rb +14 -4
- data/lib/polyphony/extensions/socket.rb +15 -15
- data/lib/polyphony/version.rb +1 -1
- data/polyphony.gemspec +0 -7
- data/test/test_backend.rb +43 -6
- data/test/test_ext.rb +1 -1
- data/test/test_fiber.rb +106 -18
- data/test/test_global_api.rb +1 -1
- data/test/test_io.rb +29 -0
- data/test/test_supervise.rb +100 -100
- data/test/test_thread_pool.rb +1 -1
- data/test/test_trace.rb +5 -4
- metadata +4 -107
@@ -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
|
35
|
-
op_context_t
|
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
|
216
|
+
inline struct backend_stats backend_get_stats(VALUE self) {
|
215
217
|
Backend_t *backend;
|
216
218
|
GetBackend(self, backend);
|
217
219
|
|
218
|
-
return (
|
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
|
-
|
271
|
-
|
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 =
|
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,
|
1515
|
-
rb_define_method(cBackend, "read_loop", Backend_read_loop,
|
1516
|
-
rb_define_method(cBackend, "recv", Backend_recv,
|
1517
|
-
rb_define_method(cBackend, "recv_loop", Backend_read_loop,
|
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
|
data/ext/polyphony/extconf.rb
CHANGED
@@ -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\.(
|
12
|
-
kernel_minor_version = $1.
|
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
|
data/ext/polyphony/fiber.c
CHANGED
@@ -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);
|
data/ext/polyphony/polyphony.c
CHANGED
@@ -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,
|
134
|
-
rb_define_singleton_method(mPolyphony, "backend_read_loop", Polyphony_backend_read_loop,
|
135
|
-
rb_define_singleton_method(mPolyphony, "backend_recv", Polyphony_backend_recv,
|
136
|
-
rb_define_singleton_method(mPolyphony, "backend_recv_loop", Polyphony_backend_recv_loop,
|
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);
|