polyphony 1.5 → 1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/CHANGELOG.md +14 -0
  4. data/TODO.md +0 -4
  5. data/ext/polyphony/backend_io_uring.c +34 -1
  6. data/ext/polyphony/backend_io_uring_context.c +24 -18
  7. data/ext/polyphony/backend_io_uring_context.h +4 -2
  8. data/ext/polyphony/backend_libev.c +4 -7
  9. data/ext/polyphony/event.c +21 -0
  10. data/ext/polyphony/extconf.rb +20 -18
  11. data/ext/polyphony/fiber.c +0 -2
  12. data/ext/polyphony/polyphony.c +2 -0
  13. data/ext/polyphony/polyphony.h +5 -0
  14. data/ext/polyphony/ring_buffer.c +1 -0
  15. data/ext/polyphony/runqueue_ring_buffer.c +1 -0
  16. data/ext/polyphony/thread.c +63 -0
  17. data/lib/polyphony/adapters/open3.rb +190 -0
  18. data/lib/polyphony/core/sync.rb +83 -13
  19. data/lib/polyphony/core/timer.rb +7 -25
  20. data/lib/polyphony/extensions/exception.rb +15 -0
  21. data/lib/polyphony/extensions/fiber.rb +14 -13
  22. data/lib/polyphony/extensions/io.rb +56 -14
  23. data/lib/polyphony/extensions/kernel.rb +1 -1
  24. data/lib/polyphony/extensions/object.rb +1 -13
  25. data/lib/polyphony/extensions/process.rb +76 -1
  26. data/lib/polyphony/extensions/thread.rb +19 -27
  27. data/lib/polyphony/version.rb +1 -1
  28. data/lib/polyphony.rb +11 -5
  29. data/test/helper.rb +46 -4
  30. data/test/open3/envutil.rb +380 -0
  31. data/test/open3/find_executable.rb +24 -0
  32. data/test/stress.rb +11 -7
  33. data/test/test_backend.rb +7 -2
  34. data/test/test_event.rb +10 -3
  35. data/test/test_ext.rb +2 -1
  36. data/test/test_fiber.rb +16 -4
  37. data/test/test_global_api.rb +13 -12
  38. data/test/test_io.rb +39 -0
  39. data/test/test_kernel.rb +2 -2
  40. data/test/test_monitor.rb +356 -0
  41. data/test/test_open3.rb +338 -0
  42. data/test/test_signal.rb +5 -1
  43. data/test/test_socket.rb +6 -3
  44. data/test/test_sync.rb +46 -0
  45. data/test/test_thread.rb +10 -1
  46. data/test/test_thread_pool.rb +5 -0
  47. data/test/test_throttler.rb +1 -1
  48. data/test/test_timer.rb +8 -2
  49. data/test/test_trace.rb +2 -0
  50. data/vendor/liburing/.github/workflows/build.yml +8 -0
  51. data/vendor/liburing/.gitignore +1 -0
  52. data/vendor/liburing/CHANGELOG +8 -0
  53. data/vendor/liburing/configure +17 -25
  54. data/vendor/liburing/debian/liburing-dev.manpages +2 -0
  55. data/vendor/liburing/debian/rules +2 -1
  56. data/vendor/liburing/examples/Makefile +2 -1
  57. data/vendor/liburing/examples/io_uring-udp.c +11 -3
  58. data/vendor/liburing/examples/rsrc-update-bench.c +100 -0
  59. data/vendor/liburing/liburing.spec +1 -1
  60. data/vendor/liburing/make-debs.sh +4 -2
  61. data/vendor/liburing/src/Makefile +5 -5
  62. data/vendor/liburing/src/arch/aarch64/lib.h +1 -1
  63. data/vendor/liburing/src/include/liburing/io_uring.h +41 -16
  64. data/vendor/liburing/src/include/liburing.h +86 -11
  65. data/vendor/liburing/src/int_flags.h +1 -0
  66. data/vendor/liburing/src/liburing-ffi.map +12 -0
  67. data/vendor/liburing/src/liburing.map +8 -0
  68. data/vendor/liburing/src/register.c +7 -2
  69. data/vendor/liburing/src/setup.c +373 -81
  70. data/vendor/liburing/test/232c93d07b74.c +3 -3
  71. data/vendor/liburing/test/Makefile +10 -3
  72. data/vendor/liburing/test/accept.c +2 -1
  73. data/vendor/liburing/test/buf-ring.c +35 -75
  74. data/vendor/liburing/test/connect-rep.c +204 -0
  75. data/vendor/liburing/test/coredump.c +59 -0
  76. data/vendor/liburing/test/fallocate.c +9 -0
  77. data/vendor/liburing/test/fd-pass.c +34 -3
  78. data/vendor/liburing/test/file-verify.c +27 -6
  79. data/vendor/liburing/test/helpers.c +3 -1
  80. data/vendor/liburing/test/io_uring_register.c +25 -28
  81. data/vendor/liburing/test/io_uring_setup.c +1 -1
  82. data/vendor/liburing/test/poll-cancel-all.c +29 -5
  83. data/vendor/liburing/test/poll-race-mshot.c +6 -22
  84. data/vendor/liburing/test/read-write.c +53 -0
  85. data/vendor/liburing/test/recv-msgall.c +21 -23
  86. data/vendor/liburing/test/reg-fd-only.c +55 -0
  87. data/vendor/liburing/test/reg-hint.c +56 -0
  88. data/vendor/liburing/test/regbuf-merge.c +91 -0
  89. data/vendor/liburing/test/ringbuf-read.c +2 -10
  90. data/vendor/liburing/test/send_recvmsg.c +5 -16
  91. data/vendor/liburing/test/shutdown.c +2 -1
  92. data/vendor/liburing/test/socket-io-cmd.c +215 -0
  93. data/vendor/liburing/test/socket-rw-eagain.c +2 -1
  94. data/vendor/liburing/test/socket-rw-offset.c +2 -1
  95. data/vendor/liburing/test/socket-rw.c +2 -1
  96. data/vendor/liburing/test/timeout.c +276 -0
  97. data/vendor/liburing/test/xattr.c +38 -25
  98. metadata +14 -3
  99. data/vendor/liburing/test/timeout-overflow.c +0 -204
@@ -294,7 +294,6 @@ Exit:
294
294
  /* Test driver for failure cases of fsetxattr and fgetxattr. */
295
295
  static int test_failure_fxattr(void)
296
296
  {
297
- int rc = 0;
298
297
  struct io_uring ring;
299
298
  char value[XATTR_SIZE];
300
299
 
@@ -313,31 +312,36 @@ static int test_failure_fxattr(void)
313
312
  }
314
313
 
315
314
  /* Test writing attributes. */
316
- assert(io_uring_fsetxattr(&ring, -1, KEY1, VALUE1, strlen(VALUE1), 0) < 0);
317
- assert(io_uring_fsetxattr(&ring, fd, NULL, VALUE1, strlen(VALUE1), 0) < 0);
318
- assert(io_uring_fsetxattr(&ring, fd, KEY1, NULL, strlen(VALUE1), 0) < 0);
319
- assert(io_uring_fsetxattr(&ring, fd, KEY1, VALUE1, 0, 0) == 0);
320
- assert(io_uring_fsetxattr(&ring, fd, KEY1, VALUE1, -1, 0) < 0);
315
+ if (io_uring_fsetxattr(&ring, -1, KEY1, VALUE1, strlen(VALUE1), 0) >= 0)
316
+ return 1;
317
+ if (io_uring_fsetxattr(&ring, fd, NULL, VALUE1, strlen(VALUE1), 0) >= 0)
318
+ return 1;
319
+ if (io_uring_fsetxattr(&ring, fd, KEY1, NULL, strlen(VALUE1), 0) >= 0)
320
+ return 1;
321
+ if (io_uring_fsetxattr(&ring, fd, KEY1, VALUE1, 0, 0) != 0)
322
+ return 1;
323
+ if (io_uring_fsetxattr(&ring, fd, KEY1, VALUE1, -1, 0) >= 0)
324
+ return 1;
321
325
 
322
326
  /* Test reading attributes. */
323
- assert(io_uring_fgetxattr(&ring, -1, KEY1, value, XATTR_SIZE) < 0);
324
- assert(io_uring_fgetxattr(&ring, fd, NULL, value, XATTR_SIZE) < 0);
325
- assert(io_uring_fgetxattr(&ring, fd, KEY1, value, 0) == 0);
327
+ if (io_uring_fgetxattr(&ring, -1, KEY1, value, XATTR_SIZE) >= 0)
328
+ return 1;
329
+ if (io_uring_fgetxattr(&ring, fd, NULL, value, XATTR_SIZE) >= 0)
330
+ return 1;
331
+ if (io_uring_fgetxattr(&ring, fd, KEY1, value, 0) != 0)
332
+ return 1;
326
333
 
327
334
  /* Cleanup. */
328
335
  close(fd);
329
336
  unlink(FILENAME);
330
-
331
337
  io_uring_queue_exit(&ring);
332
-
333
- return rc;
338
+ return 0;
334
339
  }
335
340
 
336
341
 
337
342
  /* Test driver for failure cases for setxattr and getxattr. */
338
343
  static int test_failure_xattr(void)
339
344
  {
340
- int rc = 0;
341
345
  struct io_uring ring;
342
346
  char value[XATTR_SIZE];
343
347
 
@@ -352,24 +356,33 @@ static int test_failure_xattr(void)
352
356
  t_create_file(FILENAME, 0);
353
357
 
354
358
  /* Test writing attributes. */
355
- assert(io_uring_setxattr(&ring, "complete garbage", KEY1, VALUE1, strlen(VALUE1), 0) < 0);
356
- assert(io_uring_setxattr(&ring, NULL, KEY1, VALUE1, strlen(VALUE1), 0) < 0);
357
- assert(io_uring_setxattr(&ring, FILENAME, NULL, VALUE1, strlen(VALUE1), 0) < 0);
358
- assert(io_uring_setxattr(&ring, FILENAME, KEY1, NULL, strlen(VALUE1), 0) < 0);
359
- assert(io_uring_setxattr(&ring, FILENAME, KEY1, VALUE1, 0, 0) == 0);
359
+ if (io_uring_setxattr(&ring, "complete garbage", KEY1, VALUE1, strlen(VALUE1), 0) >= 0)
360
+ return 1;
361
+ if (io_uring_setxattr(&ring, NULL, KEY1, VALUE1, strlen(VALUE1), 0) >= 0)
362
+ return 1;
363
+ if (io_uring_setxattr(&ring, FILENAME, NULL, VALUE1, strlen(VALUE1), 0) >= 0)
364
+ return 1;
365
+ if (io_uring_setxattr(&ring, FILENAME, KEY1, NULL, strlen(VALUE1), 0) >= 0)
366
+ return 1;
367
+ if (io_uring_setxattr(&ring, FILENAME, KEY1, VALUE1, 0, 0) != 0)
368
+ return 1;
360
369
 
361
370
  /* Test reading attributes. */
362
- assert(io_uring_getxattr(&ring, "complete garbage", KEY1, value, XATTR_SIZE) < 0);
363
- assert(io_uring_getxattr(&ring, NULL, KEY1, value, XATTR_SIZE) < 0);
364
- assert(io_uring_getxattr(&ring, FILENAME, NULL, value, XATTR_SIZE) < 0);
365
- assert(io_uring_getxattr(&ring, FILENAME, KEY1, NULL, XATTR_SIZE) == 0);
366
- assert(io_uring_getxattr(&ring, FILENAME, KEY1, value, 0) == 0);
371
+ if (io_uring_getxattr(&ring, "complete garbage", KEY1, value, XATTR_SIZE) >= 0)
372
+ return 1;
373
+ if (io_uring_getxattr(&ring, NULL, KEY1, value, XATTR_SIZE) >= 0)
374
+ return 1;
375
+ if (io_uring_getxattr(&ring, FILENAME, NULL, value, XATTR_SIZE) >= 0)
376
+ return 1;
377
+ if (io_uring_getxattr(&ring, FILENAME, KEY1, NULL, XATTR_SIZE) != 0)
378
+ return 1;
379
+ if (io_uring_getxattr(&ring, FILENAME, KEY1, value, 0) != 0)
380
+ return 1;
367
381
 
368
382
  /* Cleanup. */
369
383
  io_uring_queue_exit(&ring);
370
384
  unlink(FILENAME);
371
-
372
- return rc;
385
+ return 0;
373
386
  }
374
387
 
375
388
  /* Test for invalid SQE, this will cause a segmentation fault if enabled. */
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: '1.5'
4
+ version: '1.6'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-29 00:00:00.000000000 Z
11
+ date: 2023-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -364,6 +364,7 @@ files:
364
364
  - lib/polyphony/adapters/fs.rb
365
365
  - lib/polyphony/adapters/irb.rb
366
366
  - lib/polyphony/adapters/mysql2.rb
367
+ - lib/polyphony/adapters/open3.rb
367
368
  - lib/polyphony/adapters/postgres.rb
368
369
  - lib/polyphony/adapters/process.rb
369
370
  - lib/polyphony/adapters/readline.rb
@@ -397,6 +398,8 @@ files:
397
398
  - test/eg.rb
398
399
  - test/helper.rb
399
400
  - test/io_uring_test.rb
401
+ - test/open3/envutil.rb
402
+ - test/open3/find_executable.rb
400
403
  - test/q.rb
401
404
  - test/run.rb
402
405
  - test/stress.rb
@@ -408,6 +411,8 @@ files:
408
411
  - test/test_global_api.rb
409
412
  - test/test_io.rb
410
413
  - test/test_kernel.rb
414
+ - test/test_monitor.rb
415
+ - test/test_open3.rb
411
416
  - test/test_pipe.rb
412
417
  - test/test_process_supervision.rb
413
418
  - test/test_queue.rb
@@ -459,6 +464,7 @@ files:
459
464
  - vendor/liburing/examples/io_uring-udp.c
460
465
  - vendor/liburing/examples/link-cp.c
461
466
  - vendor/liburing/examples/poll-bench.c
467
+ - vendor/liburing/examples/rsrc-update-bench.c
462
468
  - vendor/liburing/examples/send-zerocopy.c
463
469
  - vendor/liburing/examples/ucontext-cp.c
464
470
  - vendor/liburing/liburing-ffi.pc.in
@@ -508,7 +514,9 @@ files:
508
514
  - vendor/liburing/test/ce593a6c480a.c
509
515
  - vendor/liburing/test/close-opath.c
510
516
  - vendor/liburing/test/config
517
+ - vendor/liburing/test/connect-rep.c
511
518
  - vendor/liburing/test/connect.c
519
+ - vendor/liburing/test/coredump.c
512
520
  - vendor/liburing/test/cq-full.c
513
521
  - vendor/liburing/test/cq-overflow.c
514
522
  - vendor/liburing/test/cq-peek-batch.c
@@ -598,7 +606,10 @@ files:
598
606
  - vendor/liburing/test/recv-msgall-stream.c
599
607
  - vendor/liburing/test/recv-msgall.c
600
608
  - vendor/liburing/test/recv-multishot.c
609
+ - vendor/liburing/test/reg-fd-only.c
610
+ - vendor/liburing/test/reg-hint.c
601
611
  - vendor/liburing/test/reg-reg-ring.c
612
+ - vendor/liburing/test/regbuf-merge.c
602
613
  - vendor/liburing/test/register-restrictions.c
603
614
  - vendor/liburing/test/rename.c
604
615
  - vendor/liburing/test/ring-leak.c
@@ -620,6 +631,7 @@ files:
620
631
  - vendor/liburing/test/sigfd-deadlock.c
621
632
  - vendor/liburing/test/single-issuer.c
622
633
  - vendor/liburing/test/skip-cqe.c
634
+ - vendor/liburing/test/socket-io-cmd.c
623
635
  - vendor/liburing/test/socket-rw-eagain.c
624
636
  - vendor/liburing/test/socket-rw-offset.c
625
637
  - vendor/liburing/test/socket-rw.c
@@ -646,7 +658,6 @@ files:
646
658
  - vendor/liburing/test/test.h
647
659
  - vendor/liburing/test/thread-exit.c
648
660
  - vendor/liburing/test/timeout-new.c
649
- - vendor/liburing/test/timeout-overflow.c
650
661
  - vendor/liburing/test/timeout.c
651
662
  - vendor/liburing/test/tty-write-dpoll.c
652
663
  - vendor/liburing/test/unlink.c
@@ -1,204 +0,0 @@
1
- /* SPDX-License-Identifier: MIT */
2
- /*
3
- * Description: run timeout overflow test
4
- *
5
- */
6
- #include <errno.h>
7
- #include <stdio.h>
8
- #include <limits.h>
9
- #include <string.h>
10
- #include <sys/time.h>
11
-
12
- #include "liburing.h"
13
- #include "helpers.h"
14
-
15
- #define TIMEOUT_MSEC 200
16
- static int not_supported;
17
-
18
- static void msec_to_ts(struct __kernel_timespec *ts, unsigned int msec)
19
- {
20
- ts->tv_sec = msec / 1000;
21
- ts->tv_nsec = (msec % 1000) * 1000000;
22
- }
23
-
24
- static int check_timeout_support(void)
25
- {
26
- struct io_uring_sqe *sqe;
27
- struct io_uring_cqe *cqe;
28
- struct __kernel_timespec ts;
29
- struct io_uring_params p;
30
- struct io_uring ring;
31
- int ret;
32
-
33
- memset(&p, 0, sizeof(p));
34
- ret = io_uring_queue_init_params(1, &ring, &p);
35
- if (ret) {
36
- fprintf(stderr, "ring setup failed: %d\n", ret);
37
- return T_EXIT_FAIL;
38
- }
39
-
40
- /* not really a match, but same kernel added batched completions */
41
- if (p.features & IORING_FEAT_POLL_32BITS) {
42
- not_supported = 1;
43
- return T_EXIT_SKIP;
44
- }
45
-
46
- sqe = io_uring_get_sqe(&ring);
47
- msec_to_ts(&ts, TIMEOUT_MSEC);
48
- io_uring_prep_timeout(sqe, &ts, 1, 0);
49
-
50
- ret = io_uring_submit(&ring);
51
- if (ret < 0) {
52
- fprintf(stderr, "sqe submit failed: %d\n", ret);
53
- goto err;
54
- }
55
-
56
- ret = io_uring_wait_cqe(&ring, &cqe);
57
- if (ret < 0) {
58
- fprintf(stderr, "wait completion %d\n", ret);
59
- goto err;
60
- }
61
-
62
- if (cqe->res == -EINVAL) {
63
- not_supported = 1;
64
- fprintf(stdout, "Timeout not supported, ignored\n");
65
- return 0;
66
- }
67
-
68
- io_uring_cqe_seen(&ring, cqe);
69
- io_uring_queue_exit(&ring);
70
- return T_EXIT_PASS;
71
- err:
72
- io_uring_queue_exit(&ring);
73
- return T_EXIT_FAIL;
74
- }
75
-
76
- /*
77
- * We first setup 4 timeout requests, which require a count value of 1, 1, 2,
78
- * UINT_MAX, so the sequence is 1, 2, 4, 2. Before really timeout, this 4
79
- * requests will not lead the change of cq_cached_tail, so as sq_dropped.
80
- *
81
- * And before this patch. The order of this four requests will be req1->req2->
82
- * req4->req3. Actually, it should be req1->req2->req3->req4.
83
- *
84
- * Then, if there is 2 nop req. All timeout requests expect req4 will completed
85
- * successful after the patch. And req1/req2 will completed successful with
86
- * req3/req4 return -ETIME without this patch!
87
- */
88
- static int test_timeout_overflow(void)
89
- {
90
- struct io_uring_sqe *sqe;
91
- struct io_uring_cqe *cqe;
92
- struct __kernel_timespec ts;
93
- struct io_uring ring;
94
- int i, ret;
95
-
96
- ret = io_uring_queue_init(16, &ring, 0);
97
- if (ret) {
98
- fprintf(stderr, "ring setup failed: %d\n", ret);
99
- return 1;
100
- }
101
-
102
- msec_to_ts(&ts, TIMEOUT_MSEC);
103
- for (i = 0; i < 4; i++) {
104
- unsigned num = 0;
105
- sqe = io_uring_get_sqe(&ring);
106
- switch (i) {
107
- case 0:
108
- case 1:
109
- num = 1;
110
- break;
111
- case 2:
112
- num = 2;
113
- break;
114
- case 3:
115
- num = UINT_MAX;
116
- break;
117
- }
118
- io_uring_prep_timeout(sqe, &ts, num, 0);
119
- }
120
-
121
- for (i = 0; i < 2; i++) {
122
- sqe = io_uring_get_sqe(&ring);
123
- io_uring_prep_nop(sqe);
124
- io_uring_sqe_set_data(sqe, (void *) 1);
125
- }
126
- ret = io_uring_submit(&ring);
127
- if (ret < 0) {
128
- fprintf(stderr, "sqe submit failed: %d\n", ret);
129
- goto err;
130
- }
131
-
132
- i = 0;
133
- while (i < 6) {
134
- ret = io_uring_wait_cqe(&ring, &cqe);
135
- if (ret < 0) {
136
- fprintf(stderr, "wait completion %d\n", ret);
137
- goto err;
138
- }
139
-
140
- /*
141
- * cqe1: first nop req
142
- * cqe2: first timeout req, because of cqe1
143
- * cqe3: second timeout req because of cqe1 + cqe2
144
- * cqe4: second nop req
145
- * cqe5~cqe6: the left three timeout req
146
- */
147
- switch (i) {
148
- case 0:
149
- case 3:
150
- if (io_uring_cqe_get_data(cqe) != (void *) 1) {
151
- fprintf(stderr, "nop not seen as 1 or 2\n");
152
- goto err;
153
- }
154
- break;
155
- case 1:
156
- case 2:
157
- case 4:
158
- if (cqe->res == -ETIME) {
159
- fprintf(stderr, "expected not return -ETIME "
160
- "for the #%d timeout req\n", i - 1);
161
- goto err;
162
- }
163
- break;
164
- case 5:
165
- if (cqe->res != -ETIME) {
166
- fprintf(stderr, "expected return -ETIME for "
167
- "the #%d timeout req\n", i - 1);
168
- goto err;
169
- }
170
- break;
171
- }
172
- io_uring_cqe_seen(&ring, cqe);
173
- i++;
174
- }
175
-
176
- return 0;
177
- err:
178
- return 1;
179
- }
180
-
181
- int main(int argc, char *argv[])
182
- {
183
- int ret;
184
-
185
- if (argc > 1)
186
- return T_EXIT_SKIP;
187
-
188
- ret = check_timeout_support();
189
- if (ret == T_EXIT_FAIL) {
190
- fprintf(stderr, "check_timeout_support failed: %d\n", ret);
191
- return T_EXIT_FAIL;
192
- }
193
-
194
- if (not_supported)
195
- return T_EXIT_SKIP;
196
-
197
- ret = test_timeout_overflow();
198
- if (ret) {
199
- fprintf(stderr, "test_timeout_overflow failed\n");
200
- return T_EXIT_FAIL;
201
- }
202
-
203
- return T_EXIT_PASS;
204
- }