polyphony 0.59.1 → 0.63
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -0
- data/Gemfile.lock +15 -29
- data/Rakefile +1 -1
- 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/extensions/fiber.rb +100 -80
- data/lib/polyphony/extensions/io.rb +15 -10
- data/lib/polyphony/extensions/openssl.rb +28 -4
- data/lib/polyphony/extensions/socket.rb +66 -15
- data/lib/polyphony/version.rb +1 -1
- data/polyphony.gemspec +0 -7
- data/test/test_backend.rb +69 -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 +49 -0
- data/test/test_socket.rb +39 -1
- 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);
|