polyphony 0.98 → 0.99.1

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 (267) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +1 -1
  3. data/.rubocop.yml +3 -3
  4. data/.yardopts +30 -0
  5. data/CHANGELOG.md +11 -0
  6. data/LICENSE +1 -1
  7. data/README.md +63 -29
  8. data/Rakefile +1 -5
  9. data/TODO.md +0 -4
  10. data/docs/{main-concepts/concurrency.md → concurrency.md} +2 -9
  11. data/docs/{main-concepts/design-principles.md → design-principles.md} +3 -9
  12. data/docs/{main-concepts/exception-handling.md → exception-handling.md} +2 -9
  13. data/docs/{main-concepts/extending.md → extending.md} +2 -9
  14. data/docs/faq.md +3 -16
  15. data/docs/{main-concepts/fiber-scheduling.md → fiber-scheduling.md} +1 -9
  16. data/docs/link_rewriter.rb +16 -0
  17. data/docs/{getting-started/overview.md → overview.md} +1 -30
  18. data/docs/{getting-started/tutorial.md → tutorial.md} +3 -28
  19. data/docs/{_posts/2020-07-26-polyphony-0.44.md → whats-new.md} +3 -1
  20. data/examples/adapters/redis_client.rb +3 -2
  21. data/examples/io/echo_server.rb +1 -1
  22. data/examples/io/echo_server_plain_ruby.rb +26 -0
  23. data/examples/io/https_server_sni_2.rb +14 -8
  24. data/ext/polyphony/backend_io_uring.c +154 -9
  25. data/ext/polyphony/backend_io_uring_context.c +21 -12
  26. data/ext/polyphony/backend_io_uring_context.h +12 -7
  27. data/ext/polyphony/backend_libev.c +1 -1
  28. data/ext/polyphony/extconf.rb +25 -8
  29. data/ext/polyphony/fiber.c +79 -2
  30. data/ext/polyphony/io_extensions.c +53 -0
  31. data/ext/polyphony/libev.h +0 -2
  32. data/ext/polyphony/pipe.c +42 -2
  33. data/ext/polyphony/polyphony.c +345 -31
  34. data/ext/polyphony/polyphony.h +9 -2
  35. data/ext/polyphony/queue.c +181 -0
  36. data/ext/polyphony/ring_buffer.c +0 -1
  37. data/ext/polyphony/runqueue.c +8 -1
  38. data/ext/polyphony/runqueue_ring_buffer.c +13 -0
  39. data/ext/polyphony/runqueue_ring_buffer.h +2 -1
  40. data/ext/polyphony/socket_extensions.c +6 -0
  41. data/ext/polyphony/thread.c +34 -2
  42. data/lib/polyphony/adapters/process.rb +11 -1
  43. data/lib/polyphony/adapters/sequel.rb +1 -1
  44. data/lib/polyphony/core/channel.rb +2 -0
  45. data/lib/polyphony/core/debug.rb +1 -1
  46. data/lib/polyphony/core/global_api.rb +25 -24
  47. data/lib/polyphony/core/resource_pool.rb +7 -6
  48. data/lib/polyphony/core/sync.rb +55 -2
  49. data/lib/polyphony/core/thread_pool.rb +3 -3
  50. data/lib/polyphony/core/timer.rb +8 -8
  51. data/lib/polyphony/extensions/exception.rb +2 -0
  52. data/lib/polyphony/extensions/fiber.rb +15 -13
  53. data/lib/polyphony/extensions/io.rb +161 -16
  54. data/lib/polyphony/extensions/kernel.rb +20 -2
  55. data/lib/polyphony/extensions/openssl.rb +101 -12
  56. data/lib/polyphony/extensions/pipe.rb +103 -7
  57. data/lib/polyphony/extensions/process.rb +13 -1
  58. data/lib/polyphony/extensions/socket.rb +93 -27
  59. data/lib/polyphony/extensions/thread.rb +9 -1
  60. data/lib/polyphony/extensions/timeout.rb +1 -1
  61. data/lib/polyphony/version.rb +2 -1
  62. data/lib/polyphony.rb +27 -7
  63. data/polyphony.gemspec +1 -8
  64. data/test/stress.rb +1 -1
  65. data/test/test_global_api.rb +45 -7
  66. data/test/test_io.rb +6 -7
  67. data/test/test_socket.rb +157 -0
  68. data/test/test_sync.rb +42 -1
  69. data/test/test_timer.rb +5 -5
  70. data/vendor/liburing/.github/workflows/build.yml +7 -16
  71. data/vendor/liburing/.gitignore +5 -0
  72. data/vendor/liburing/CHANGELOG +23 -1
  73. data/vendor/liburing/Makefile +4 -3
  74. data/vendor/liburing/Makefile.common +1 -0
  75. data/vendor/liburing/README +48 -0
  76. data/vendor/liburing/configure +76 -6
  77. data/vendor/liburing/debian/changelog +11 -0
  78. data/vendor/liburing/debian/control +7 -16
  79. data/vendor/liburing/debian/liburing-dev.manpages +3 -6
  80. data/vendor/liburing/debian/liburing2.install +1 -0
  81. data/vendor/liburing/debian/liburing2.symbols +56 -0
  82. data/vendor/liburing/debian/rules +15 -68
  83. data/vendor/liburing/examples/Makefile +4 -0
  84. data/vendor/liburing/examples/io_uring-close-test.c +123 -0
  85. data/vendor/liburing/examples/io_uring-udp.c +1 -1
  86. data/vendor/liburing/examples/send-zerocopy.c +315 -56
  87. data/vendor/liburing/examples/ucontext-cp.c +2 -17
  88. data/vendor/liburing/liburing-ffi.pc.in +12 -0
  89. data/vendor/liburing/liburing.pc.in +1 -1
  90. data/vendor/liburing/liburing.spec +1 -1
  91. data/vendor/liburing/make-debs.sh +3 -3
  92. data/vendor/liburing/man/IO_URING_CHECK_VERSION.3 +1 -0
  93. data/vendor/liburing/man/IO_URING_VERSION_MAJOR.3 +1 -0
  94. data/vendor/liburing/man/IO_URING_VERSION_MINOR.3 +1 -0
  95. data/vendor/liburing/man/io_uring_buf_ring_add.3 +6 -6
  96. data/vendor/liburing/man/io_uring_check_version.3 +72 -0
  97. data/vendor/liburing/man/io_uring_close_ring_fd.3 +43 -0
  98. data/vendor/liburing/man/io_uring_major_version.3 +1 -0
  99. data/vendor/liburing/man/io_uring_minor_version.3 +1 -0
  100. data/vendor/liburing/man/io_uring_prep_accept.3 +1 -1
  101. data/vendor/liburing/man/io_uring_prep_fgetxattr.3 +1 -0
  102. data/vendor/liburing/man/io_uring_prep_fsetxattr.3 +1 -0
  103. data/vendor/liburing/man/io_uring_prep_getxattr.3 +61 -0
  104. data/vendor/liburing/man/io_uring_prep_link_timeout.3 +94 -0
  105. data/vendor/liburing/man/io_uring_prep_msg_ring.3 +22 -2
  106. data/vendor/liburing/man/io_uring_prep_msg_ring_cqe_flags.3 +1 -0
  107. data/vendor/liburing/man/io_uring_prep_poll_add.3 +1 -1
  108. data/vendor/liburing/man/io_uring_prep_provide_buffers.3 +18 -9
  109. data/vendor/liburing/man/io_uring_prep_readv.3 +3 -3
  110. data/vendor/liburing/man/io_uring_prep_readv2.3 +3 -3
  111. data/vendor/liburing/man/io_uring_prep_recv.3 +5 -5
  112. data/vendor/liburing/man/io_uring_prep_recvmsg.3 +4 -4
  113. data/vendor/liburing/man/io_uring_prep_send.3 +9 -0
  114. data/vendor/liburing/man/io_uring_prep_send_set_addr.3 +38 -0
  115. data/vendor/liburing/man/io_uring_prep_send_zc.3 +39 -7
  116. data/vendor/liburing/man/io_uring_prep_send_zc_fixed.3 +1 -0
  117. data/vendor/liburing/man/io_uring_prep_sendmsg.3 +20 -0
  118. data/vendor/liburing/man/io_uring_prep_sendmsg_zc.3 +1 -0
  119. data/vendor/liburing/man/io_uring_prep_setxattr.3 +64 -0
  120. data/vendor/liburing/man/io_uring_prep_splice.3 +40 -0
  121. data/vendor/liburing/man/io_uring_prep_writev.3 +2 -2
  122. data/vendor/liburing/man/io_uring_prep_writev2.3 +2 -2
  123. data/vendor/liburing/man/io_uring_recvmsg_out.3 +13 -9
  124. data/vendor/liburing/man/io_uring_register.2 +15 -9
  125. data/vendor/liburing/man/io_uring_register_buf_ring.3 +4 -4
  126. data/vendor/liburing/man/io_uring_register_buffers.3 +49 -6
  127. data/vendor/liburing/man/io_uring_register_buffers_sparse.3 +1 -0
  128. data/vendor/liburing/man/io_uring_register_buffers_tags.3 +1 -0
  129. data/vendor/liburing/man/io_uring_register_buffers_update_tag.3 +1 -0
  130. data/vendor/liburing/man/io_uring_register_files.3 +60 -5
  131. data/vendor/liburing/man/io_uring_register_files_tags.3 +1 -0
  132. data/vendor/liburing/man/io_uring_register_files_update.3 +1 -0
  133. data/vendor/liburing/man/io_uring_register_files_update_tag.3 +1 -0
  134. data/vendor/liburing/man/io_uring_setup.2 +31 -2
  135. data/vendor/liburing/man/io_uring_wait_cqe_timeout.3 +1 -1
  136. data/vendor/liburing/src/Makefile +25 -3
  137. data/vendor/liburing/src/ffi.c +15 -0
  138. data/vendor/liburing/src/include/liburing/io_uring.h +30 -7
  139. data/vendor/liburing/src/include/liburing.h +190 -148
  140. data/vendor/liburing/src/int_flags.h +1 -0
  141. data/vendor/liburing/src/lib.h +5 -16
  142. data/vendor/liburing/src/liburing-ffi.map +172 -0
  143. data/vendor/liburing/src/liburing.map +11 -0
  144. data/vendor/liburing/src/nolibc.c +9 -2
  145. data/vendor/liburing/src/queue.c +2 -2
  146. data/vendor/liburing/src/register.c +66 -96
  147. data/vendor/liburing/src/setup.c +5 -4
  148. data/vendor/liburing/src/version.c +21 -0
  149. data/vendor/liburing/test/232c93d07b74.c +3 -3
  150. data/vendor/liburing/test/35fa71a030ca.c +3 -3
  151. data/vendor/liburing/test/500f9fbadef8.c +2 -0
  152. data/vendor/liburing/test/917257daa0fe.c +1 -1
  153. data/vendor/liburing/test/Makefile +27 -7
  154. data/vendor/liburing/test/a0908ae19763.c +2 -2
  155. data/vendor/liburing/test/a4c0b3decb33.c +2 -2
  156. data/vendor/liburing/test/accept-link.c +4 -4
  157. data/vendor/liburing/test/accept-reuse.c +5 -7
  158. data/vendor/liburing/test/accept.c +34 -31
  159. data/vendor/liburing/test/b19062a56726.c +1 -1
  160. data/vendor/liburing/test/buf-ring.c +58 -4
  161. data/vendor/liburing/test/ce593a6c480a.c +2 -2
  162. data/vendor/liburing/test/close-opath.c +2 -1
  163. data/vendor/liburing/test/connect.c +8 -0
  164. data/vendor/liburing/test/cq-overflow.c +14 -8
  165. data/vendor/liburing/test/d4ae271dfaae.c +1 -1
  166. data/vendor/liburing/test/defer-taskrun.c +64 -9
  167. data/vendor/liburing/test/defer.c +1 -1
  168. data/vendor/liburing/test/double-poll-crash.c +3 -3
  169. data/vendor/liburing/test/eeed8b54e0df.c +8 -3
  170. data/vendor/liburing/test/eploop.c +74 -0
  171. data/vendor/liburing/test/eventfd-ring.c +1 -1
  172. data/vendor/liburing/test/eventfd.c +1 -1
  173. data/vendor/liburing/test/evloop.c +73 -0
  174. data/vendor/liburing/test/exit-no-cleanup.c +1 -1
  175. data/vendor/liburing/test/fadvise.c +1 -1
  176. data/vendor/liburing/test/fc2a85cb02ef.c +3 -3
  177. data/vendor/liburing/test/fd-pass.c +35 -16
  178. data/vendor/liburing/test/file-register.c +61 -0
  179. data/vendor/liburing/test/file-verify.c +2 -2
  180. data/vendor/liburing/test/files-exit-hang-timeout.c +2 -2
  181. data/vendor/liburing/test/fixed-link.c +1 -1
  182. data/vendor/liburing/test/fsnotify.c +118 -0
  183. data/vendor/liburing/test/hardlink.c +1 -1
  184. data/vendor/liburing/test/helpers.c +54 -2
  185. data/vendor/liburing/test/helpers.h +4 -0
  186. data/vendor/liburing/test/io-cancel.c +3 -1
  187. data/vendor/liburing/test/io_uring_passthrough.c +39 -8
  188. data/vendor/liburing/test/io_uring_setup.c +3 -80
  189. data/vendor/liburing/test/iopoll-overflow.c +118 -0
  190. data/vendor/liburing/test/iopoll.c +90 -4
  191. data/vendor/liburing/test/lfs-openat-write.c +7 -9
  192. data/vendor/liburing/test/lfs-openat.c +6 -8
  193. data/vendor/liburing/test/link_drain.c +31 -5
  194. data/vendor/liburing/test/madvise.c +1 -1
  195. data/vendor/liburing/test/msg-ring-flags.c +192 -0
  196. data/vendor/liburing/test/msg-ring-overflow.c +159 -0
  197. data/vendor/liburing/test/msg-ring.c +173 -13
  198. data/vendor/liburing/test/multicqes_drain.c +22 -19
  199. data/vendor/liburing/test/nvme.h +4 -3
  200. data/vendor/liburing/test/pipe-bug.c +95 -0
  201. data/vendor/liburing/test/poll-link.c +3 -3
  202. data/vendor/liburing/test/poll-many.c +41 -19
  203. data/vendor/liburing/test/poll-mshot-overflow.c +105 -2
  204. data/vendor/liburing/test/poll-race-mshot.c +292 -0
  205. data/vendor/liburing/test/poll-race.c +105 -0
  206. data/vendor/liburing/test/poll.c +244 -26
  207. data/vendor/liburing/test/pollfree.c +5 -5
  208. data/vendor/liburing/test/read-before-exit.c +20 -3
  209. data/vendor/liburing/test/read-write.c +2 -0
  210. data/vendor/liburing/test/recv-multishot.c +96 -3
  211. data/vendor/liburing/test/reg-reg-ring.c +90 -0
  212. data/vendor/liburing/test/rename.c +1 -1
  213. data/vendor/liburing/test/ring-leak.c +0 -1
  214. data/vendor/liburing/test/ring-leak2.c +1 -1
  215. data/vendor/liburing/test/ringbuf-read.c +10 -6
  216. data/vendor/liburing/test/send-zerocopy.c +273 -103
  217. data/vendor/liburing/test/send_recv.c +7 -4
  218. data/vendor/liburing/test/sendmsg_fs_cve.c +2 -2
  219. data/vendor/liburing/test/single-issuer.c +7 -9
  220. data/vendor/liburing/test/skip-cqe.c +3 -4
  221. data/vendor/liburing/test/socket.c +0 -1
  222. data/vendor/liburing/test/sq-poll-dup.c +10 -3
  223. data/vendor/liburing/test/sq-poll-kthread.c +1 -1
  224. data/vendor/liburing/test/sq-poll-share.c +3 -2
  225. data/vendor/liburing/test/sqpoll-cancel-hang.c +17 -6
  226. data/vendor/liburing/test/sqpoll-disable-exit.c +4 -4
  227. data/vendor/liburing/test/symlink.c +2 -1
  228. data/vendor/liburing/test/test.h +2 -1
  229. data/vendor/liburing/test/timeout-new.c +11 -7
  230. data/vendor/liburing/test/timeout.c +1 -2
  231. data/vendor/liburing/test/unlink.c +1 -1
  232. data/vendor/liburing/test/version.c +25 -0
  233. data/vendor/liburing/test/wakeup-hang.c +1 -1
  234. data/vendor/liburing/test/xattr.c +8 -4
  235. metadata +57 -44
  236. data/docs/_config.yml +0 -64
  237. data/docs/_includes/head.html +0 -40
  238. data/docs/_includes/title.html +0 -1
  239. data/docs/_sass/custom/custom.scss +0 -10
  240. data/docs/_sass/overrides.scss +0 -0
  241. data/docs/api-reference/exception.md +0 -31
  242. data/docs/api-reference/fiber.md +0 -425
  243. data/docs/api-reference/index.md +0 -9
  244. data/docs/api-reference/io.md +0 -36
  245. data/docs/api-reference/object.md +0 -99
  246. data/docs/api-reference/polyphony-baseexception.md +0 -33
  247. data/docs/api-reference/polyphony-cancel.md +0 -26
  248. data/docs/api-reference/polyphony-moveon.md +0 -24
  249. data/docs/api-reference/polyphony-net.md +0 -20
  250. data/docs/api-reference/polyphony-process.md +0 -28
  251. data/docs/api-reference/polyphony-resourcepool.md +0 -59
  252. data/docs/api-reference/polyphony-restart.md +0 -18
  253. data/docs/api-reference/polyphony-terminate.md +0 -18
  254. data/docs/api-reference/polyphony-threadpool.md +0 -67
  255. data/docs/api-reference/polyphony-throttler.md +0 -77
  256. data/docs/api-reference/polyphony.md +0 -36
  257. data/docs/api-reference/thread.md +0 -88
  258. data/docs/favicon.ico +0 -0
  259. data/docs/getting-started/index.md +0 -10
  260. data/docs/getting-started/installing.md +0 -34
  261. data/vendor/liburing/debian/compat +0 -1
  262. data/vendor/liburing/debian/liburing1-udeb.install +0 -1
  263. data/vendor/liburing/debian/liburing1.install +0 -1
  264. data/vendor/liburing/debian/liburing1.symbols +0 -32
  265. /data/{docs/assets/img → assets}/echo-fibers.svg +0 -0
  266. /data/{docs → assets}/polyphony-logo.png +0 -0
  267. /data/{docs/assets/img → assets}/sleeping-fiber.svg +0 -0
@@ -93,17 +93,23 @@ static void *wait_cqe_fn(void *data)
93
93
  goto err;
94
94
  }
95
95
 
96
+ io_uring_cqe_seen(ring, cqe);
96
97
  return NULL;
97
98
  err:
99
+ io_uring_cqe_seen(ring, cqe);
98
100
  return (void *) (unsigned long) 1;
99
101
  }
100
102
 
101
103
  static int test_remote(struct io_uring *ring, struct io_uring *target)
102
104
  {
105
+ pthread_t thread;
106
+ void *tret;
103
107
  struct io_uring_cqe *cqe;
104
108
  struct io_uring_sqe *sqe;
105
109
  int ret;
106
110
 
111
+ pthread_create(&thread, NULL, wait_cqe_fn, target);
112
+
107
113
  sqe = io_uring_get_sqe(ring);
108
114
  if (!sqe) {
109
115
  fprintf(stderr, "get sqe failed\n");
@@ -134,6 +140,80 @@ static int test_remote(struct io_uring *ring, struct io_uring *target)
134
140
  }
135
141
 
136
142
  io_uring_cqe_seen(ring, cqe);
143
+ pthread_join(thread, &tret);
144
+ return 0;
145
+ err:
146
+ return 1;
147
+ }
148
+
149
+ static void *remote_submit_fn(void *data)
150
+ {
151
+ struct io_uring_sqe *sqe;
152
+ struct io_uring_cqe *cqe;
153
+ struct io_uring *target = data;
154
+ struct io_uring ring;
155
+ int ret;
156
+
157
+ ret = io_uring_queue_init(8, &ring, 0);
158
+ if (ret) {
159
+ fprintf(stderr, "thread ring setup failed: %d\n", ret);
160
+ goto err;
161
+ }
162
+ sqe = io_uring_get_sqe(&ring);
163
+ if (!sqe) {
164
+ fprintf(stderr, "get sqe failed\n");
165
+ goto err;
166
+ }
167
+
168
+ io_uring_prep_msg_ring(sqe, target->ring_fd, 0x20, 0x5aa5, 0);
169
+ sqe->user_data = 1;
170
+
171
+ ret = io_uring_submit(&ring);
172
+ if (ret <= 0) {
173
+ fprintf(stderr, "sqe submit failed: %d\n", ret);
174
+ goto err;
175
+ }
176
+
177
+ ret = io_uring_wait_cqe(&ring, &cqe);
178
+ if (ret < 0) {
179
+ fprintf(stderr, "wait completion %d\n", ret);
180
+ goto err;
181
+ }
182
+ if (cqe->res != 0 || cqe->user_data != 1) {
183
+ fprintf(stderr, "invalid cqe\n");
184
+ goto err;
185
+ }
186
+ io_uring_cqe_seen(&ring, cqe);
187
+ io_uring_queue_exit(&ring);
188
+ return NULL;
189
+ err:
190
+ return (void *) (unsigned long) 1;
191
+ }
192
+
193
+ static int test_remote_submit(struct io_uring *target)
194
+ {
195
+ struct io_uring_cqe *cqe;
196
+ pthread_t thread;
197
+ void *tret;
198
+ int ret;
199
+
200
+ pthread_create(&thread, NULL, remote_submit_fn, target);
201
+
202
+ ret = io_uring_wait_cqe(target, &cqe);
203
+ if (ret < 0) {
204
+ fprintf(stderr, "wait completion %d\n", ret);
205
+ goto err;
206
+ }
207
+ if (cqe->res != 0x20) {
208
+ fprintf(stderr, "cqe res %d\n", cqe->res);
209
+ return -1;
210
+ }
211
+ if (cqe->user_data != 0x5aa5) {
212
+ fprintf(stderr, "user_data %llx\n", (long long) cqe->user_data);
213
+ return -1;
214
+ }
215
+ io_uring_cqe_seen(target, cqe);
216
+ pthread_join(thread, &tret);
137
217
  return 0;
138
218
  err:
139
219
  return 1;
@@ -191,11 +271,52 @@ err:
191
271
  return 1;
192
272
  }
193
273
 
274
+ static int test_disabled_ring(struct io_uring *ring, int flags)
275
+ {
276
+ struct io_uring_cqe *cqe;
277
+ struct io_uring_sqe *sqe;
278
+ struct io_uring disabled_ring;
279
+ int ret;
280
+
281
+ flags |= IORING_SETUP_R_DISABLED;
282
+ ret = io_uring_queue_init(8, &disabled_ring, flags);
283
+ if (ret) {
284
+ fprintf(stderr, "ring setup failed: %d\n", ret);
285
+ return 1;
286
+ }
287
+
288
+ sqe = io_uring_get_sqe(ring);
289
+ io_uring_prep_msg_ring(sqe, disabled_ring.ring_fd, 0x10, 0x1234, 0);
290
+ sqe->user_data = 1;
291
+
292
+ ret = io_uring_submit(ring);
293
+ if (ret != 1) {
294
+ fprintf(stderr, "sqe submit failed: %d\n", ret);
295
+ return 1;
296
+ }
297
+
298
+ ret = io_uring_wait_cqe(ring, &cqe);
299
+ if (ret < 0) {
300
+ fprintf(stderr, "wait completion %d\n", ret);
301
+ return 1;
302
+ }
303
+ if (cqe->res != 0 && cqe->res != -EBADFD) {
304
+ fprintf(stderr, "cqe res %d\n", cqe->res);
305
+ return 1;
306
+ }
307
+ if (cqe->user_data != 1) {
308
+ fprintf(stderr, "user_data %llx\n", (long long) cqe->user_data);
309
+ return 1;
310
+ }
311
+
312
+ io_uring_cqe_seen(ring, cqe);
313
+ io_uring_queue_exit(&disabled_ring);
314
+ return 0;
315
+ }
316
+
194
317
  int main(int argc, char *argv[])
195
318
  {
196
319
  struct io_uring ring, ring2, pring;
197
- pthread_t thread;
198
- void *tret;
199
320
  int ret, i;
200
321
 
201
322
  if (argc > 1)
@@ -220,41 +341,80 @@ int main(int argc, char *argv[])
220
341
  ret = test_own(&ring);
221
342
  if (ret) {
222
343
  fprintf(stderr, "test_own failed\n");
223
- return ret;
344
+ return T_EXIT_FAIL;
224
345
  }
225
- if (no_msg) {
226
- fprintf(stdout, "Skipped\n");
346
+ if (no_msg)
227
347
  return T_EXIT_SKIP;
228
- }
229
348
  ret = test_own(&pring);
230
349
  if (ret) {
231
350
  fprintf(stderr, "test_own iopoll failed\n");
232
- return ret;
351
+ return T_EXIT_FAIL;
233
352
  }
234
353
 
235
354
  ret = test_invalid(&ring, 0);
236
355
  if (ret) {
237
356
  fprintf(stderr, "test_invalid failed\n");
238
- return ret;
357
+ return T_EXIT_FAIL;
239
358
  }
240
359
 
241
360
  for (i = 0; i < 2; i++) {
242
361
  ret = test_invalid(&ring, 1);
243
362
  if (ret) {
244
363
  fprintf(stderr, "test_invalid fixed failed\n");
245
- return ret;
364
+ return T_EXIT_FAIL;
246
365
  }
247
366
  }
248
367
 
249
- pthread_create(&thread, NULL, wait_cqe_fn, &ring2);
250
-
251
368
  ret = test_remote(&ring, &ring2);
252
369
  if (ret) {
253
370
  fprintf(stderr, "test_remote failed\n");
254
- return ret;
371
+ return T_EXIT_FAIL;
255
372
  }
256
373
 
257
- pthread_join(thread, &tret);
374
+ io_uring_queue_exit(&ring);
375
+ io_uring_queue_exit(&pring);
376
+
377
+ if (t_probe_defer_taskrun()) {
378
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
379
+ IORING_SETUP_DEFER_TASKRUN);
380
+ if (ret) {
381
+ fprintf(stderr, "deferred ring setup failed: %d\n", ret);
382
+ return T_EXIT_FAIL;
383
+ }
384
+
385
+ ret = test_own(&ring);
386
+ if (ret) {
387
+ fprintf(stderr, "test_own deferred failed\n");
388
+ return T_EXIT_FAIL;
389
+ }
390
+
391
+ for (i = 0; i < 2; i++) {
392
+ ret = test_invalid(&ring, i);
393
+ if (ret) {
394
+ fprintf(stderr, "test_invalid(0) deferred failed\n");
395
+ return T_EXIT_FAIL;
396
+ }
397
+ }
398
+
399
+ ret = test_remote_submit(&ring);
400
+ if (ret) {
401
+ fprintf(stderr, "test_remote_submit failed\n");
402
+ return T_EXIT_FAIL;
403
+ }
404
+ io_uring_queue_exit(&ring);
405
+
406
+ if (test_disabled_ring(&ring2, 0)) {
407
+ fprintf(stderr, "test_disabled_ring failed\n");
408
+ return T_EXIT_FAIL;
409
+ }
410
+
411
+ if (test_disabled_ring(&ring2, IORING_SETUP_SINGLE_ISSUER |
412
+ IORING_SETUP_DEFER_TASKRUN)) {
413
+ fprintf(stderr, "test_disabled_ring defer failed\n");
414
+ return T_EXIT_FAIL;
415
+ }
416
+ }
258
417
 
418
+ io_uring_queue_exit(&ring2);
259
419
  return T_EXIT_PASS;
260
420
  }
@@ -42,12 +42,16 @@ struct sqe_info {
42
42
  * up an entry in multi_sqes when form a cancellation sqe.
43
43
  * multi_cap: limitation of number of multishot sqes
44
44
  */
45
- const unsigned sqe_flags[4] = {0, IOSQE_IO_LINK, IOSQE_IO_DRAIN,
46
- IOSQE_IO_LINK | IOSQE_IO_DRAIN};
47
- int multi_sqes[max_entry], cnt = 0;
48
- int multi_cap = max_entry / 5;
45
+ static const unsigned sqe_flags[4] = {
46
+ 0,
47
+ IOSQE_IO_LINK,
48
+ IOSQE_IO_DRAIN,
49
+ IOSQE_IO_LINK | IOSQE_IO_DRAIN
50
+ };
51
+ static int multi_sqes[max_entry], cnt = 0;
52
+ static int multi_cap = max_entry / 5;
49
53
 
50
- int write_pipe(int pipe, char *str)
54
+ static int write_pipe(int pipe, char *str)
51
55
  {
52
56
  int ret;
53
57
  do {
@@ -57,7 +61,7 @@ int write_pipe(int pipe, char *str)
57
61
  return ret;
58
62
  }
59
63
 
60
- void read_pipe(int pipe)
64
+ static void read_pipe(int pipe)
61
65
  {
62
66
  char str[4] = {0};
63
67
  int ret;
@@ -67,18 +71,21 @@ void read_pipe(int pipe)
67
71
  perror("read");
68
72
  }
69
73
 
70
- int trigger_event(int p[])
74
+ static int trigger_event(struct io_uring *ring, int p[])
71
75
  {
72
76
  int ret;
73
77
  if ((ret = write_pipe(p[1], "foo")) != 3) {
74
78
  fprintf(stderr, "bad write return %d\n", ret);
75
79
  return 1;
76
80
  }
81
+ usleep(1000);
82
+ io_uring_get_events(ring);
77
83
  read_pipe(p[0]);
78
84
  return 0;
79
85
  }
80
86
 
81
- void io_uring_sqe_prep(int op, struct io_uring_sqe *sqe, unsigned sqe_flags, int arg)
87
+ static void io_uring_sqe_prep(int op, struct io_uring_sqe *sqe,
88
+ unsigned sqe_flags, int arg)
82
89
  {
83
90
  switch (op) {
84
91
  case multi:
@@ -98,7 +105,7 @@ void io_uring_sqe_prep(int op, struct io_uring_sqe *sqe, unsigned sqe_flags, int
98
105
  sqe->flags = sqe_flags;
99
106
  }
100
107
 
101
- __u8 generate_flags(int sqe_op)
108
+ static __u8 generate_flags(int sqe_op)
102
109
  {
103
110
  __u8 flags = 0;
104
111
  /*
@@ -136,7 +143,7 @@ __u8 generate_flags(int sqe_op)
136
143
  * - ensure number of multishot sqes doesn't exceed multi_cap
137
144
  * - don't generate multishot sqes after high watermark
138
145
  */
139
- int generate_opcode(int i, int pre_flags)
146
+ static int generate_opcode(int i, int pre_flags)
140
147
  {
141
148
  int sqe_op;
142
149
  int high_watermark = max_entry - max_entry / 5;
@@ -163,7 +170,7 @@ static inline void add_multishot_sqe(int index)
163
170
  multi_sqes[cnt++] = index;
164
171
  }
165
172
 
166
- int remove_multishot_sqe()
173
+ static int remove_multishot_sqe(void)
167
174
  {
168
175
  int ret;
169
176
 
@@ -231,10 +238,8 @@ static int test_generic_drain(struct io_uring *ring)
231
238
  if (si[i].op != multi && si[i].op != single)
232
239
  continue;
233
240
 
234
- if (trigger_event(pipes[i]))
241
+ if (trigger_event(ring, pipes[i]))
235
242
  goto err;
236
-
237
- io_uring_get_events(ring);
238
243
  }
239
244
  sleep(1);
240
245
  i = 0;
@@ -312,13 +317,11 @@ static int test_simple_drain(struct io_uring *ring)
312
317
  }
313
318
 
314
319
  for (i = 0; i < 2; i++) {
315
- if (trigger_event(pipe1))
320
+ if (trigger_event(ring, pipe1))
316
321
  goto err;
317
- io_uring_get_events(ring);
318
322
  }
319
- if (trigger_event(pipe2))
320
- goto err;
321
- io_uring_get_events(ring);
323
+ if (trigger_event(ring, pipe2))
324
+ goto err;
322
325
 
323
326
  for (i = 0; i < 2; i++) {
324
327
  sqe[i] = io_uring_get_sqe(ring);
@@ -57,8 +57,8 @@ enum nvme_io_opcode {
57
57
  nvme_cmd_read = 0x02,
58
58
  };
59
59
 
60
- int nsid;
61
- __u32 lba_shift;
60
+ static int nsid;
61
+ static __u32 lba_shift;
62
62
 
63
63
  struct nvme_lbaf {
64
64
  __le16 ms;
@@ -120,7 +120,8 @@ static inline int ilog2(uint32_t i)
120
120
  return log;
121
121
  }
122
122
 
123
- int nvme_get_info(const char *file)
123
+ __attribute__((__unused__))
124
+ static int nvme_get_info(const char *file)
124
125
  {
125
126
  struct nvme_id_ns ns;
126
127
  int fd, err;
@@ -0,0 +1,95 @@
1
+ // SPDX-License-Identifier: MIT
2
+
3
+ /*
4
+ * Description: tests bug fixed in
5
+ * "io_uring: don't gate task_work run on TIF_NOTIFY_SIGNAL"
6
+ *
7
+ * See: https://github.com/axboe/liburing/issues/665
8
+ */
9
+
10
+ #include <stdio.h>
11
+ #include <string.h>
12
+ #include <unistd.h>
13
+
14
+ #include "helpers.h"
15
+ #include "liburing.h"
16
+
17
+ #define CHECK(x) \
18
+ do { \
19
+ if (!(x)) { \
20
+ fprintf(stderr, "%s:%d %s failed\n", __FILE__, __LINE__, #x); \
21
+ return -1; \
22
+ } \
23
+ } while (0)
24
+
25
+ static int pipe_bug(void)
26
+ {
27
+ struct io_uring_params p;
28
+ struct io_uring ring;
29
+ struct io_uring_sqe *sqe;
30
+ struct io_uring_cqe *cqe;
31
+ char buf[1024];
32
+ int fds[2];
33
+ struct __kernel_timespec to = {
34
+ .tv_sec = 1
35
+ };
36
+
37
+ CHECK(pipe(fds) == 0);
38
+
39
+ memset(&p, 0, sizeof(p));
40
+ CHECK(t_create_ring_params(8, &ring, &p) == 0);
41
+
42
+ /* WRITE */
43
+ sqe = io_uring_get_sqe(&ring);
44
+ CHECK(sqe);
45
+ io_uring_prep_write(sqe, fds[1], "foobar", strlen("foobar"), 0); /* or -1 */
46
+ CHECK(io_uring_submit(&ring) == 1);
47
+ CHECK(io_uring_wait_cqe(&ring, &cqe) == 0);
48
+
49
+ io_uring_cqe_seen(&ring, cqe);
50
+
51
+ /* CLOSE */
52
+ sqe = io_uring_get_sqe(&ring);
53
+ CHECK(sqe);
54
+ io_uring_prep_close(sqe, fds[1]);
55
+ CHECK(io_uring_submit(&ring) == 1);
56
+ CHECK(io_uring_wait_cqe_timeout(&ring, &cqe, &to) == 0);
57
+ io_uring_cqe_seen(&ring, cqe);
58
+
59
+ /* READ */
60
+ sqe = io_uring_get_sqe(&ring);
61
+ CHECK(sqe);
62
+ io_uring_prep_read(sqe, fds[0], buf, sizeof(buf), 0); /* or -1 */
63
+ CHECK(io_uring_submit(&ring) == 1);
64
+ CHECK(io_uring_wait_cqe_timeout(&ring, &cqe, &to) == 0);
65
+ io_uring_cqe_seen(&ring, cqe);
66
+ memset(buf, 0, sizeof(buf));
67
+
68
+ /* READ */
69
+ sqe = io_uring_get_sqe(&ring);
70
+ CHECK(sqe);
71
+ io_uring_prep_read(sqe, fds[0], buf, sizeof(buf), 0); /* or -1 */
72
+ CHECK(io_uring_submit(&ring) == 1);
73
+ CHECK(io_uring_wait_cqe_timeout(&ring, &cqe, &to) == 0);
74
+ io_uring_cqe_seen(&ring, cqe);
75
+
76
+ close(fds[0]);
77
+ io_uring_queue_exit(&ring);
78
+
79
+ return 0;
80
+ }
81
+
82
+ int main(int argc, char *argv[])
83
+ {
84
+ int i;
85
+
86
+ if (argc > 1)
87
+ return T_EXIT_SKIP;
88
+
89
+ for (i = 0; i < 10000; i++) {
90
+ if (pipe_bug())
91
+ return T_EXIT_FAIL;
92
+ }
93
+
94
+ return T_EXIT_PASS;
95
+ }
@@ -16,8 +16,8 @@
16
16
  #include "helpers.h"
17
17
  #include "liburing.h"
18
18
 
19
- pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
20
- pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
19
+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
20
+ static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
21
21
 
22
22
  static int recv_thread_ready = 0;
23
23
  static int recv_thread_done = 0;
@@ -71,7 +71,7 @@ static void *send_thread(void *arg)
71
71
  return 0;
72
72
  }
73
73
 
74
- void *recv_thread(void *arg)
74
+ static void *recv_thread(void *arg)
75
75
  {
76
76
  struct sockaddr_in addr = { };
77
77
  struct data *data = arg;
@@ -14,6 +14,7 @@
14
14
  #include <fcntl.h>
15
15
 
16
16
  #include "liburing.h"
17
+ #include "helpers.h"
17
18
 
18
19
  #define NFILES 5000
19
20
  #define BATCH 500
@@ -137,6 +138,21 @@ static int arm_polls(struct io_uring *ring)
137
138
  return 0;
138
139
  }
139
140
 
141
+ static int do_test(struct io_uring *ring)
142
+ {
143
+ int i;
144
+
145
+ if (arm_polls(ring))
146
+ return 1;
147
+
148
+ for (i = 0; i < NLOOPS; i++) {
149
+ trigger_polls();
150
+ if (reap_polls(ring))
151
+ return 1;
152
+ }
153
+ return 0;
154
+ }
155
+
140
156
  int main(int argc, char *argv[])
141
157
  {
142
158
  struct io_uring ring;
@@ -149,7 +165,7 @@ int main(int argc, char *argv[])
149
165
 
150
166
  if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
151
167
  perror("getrlimit");
152
- goto err_noring;
168
+ return T_EXIT_FAIL;
153
169
  }
154
170
 
155
171
  if (rlim.rlim_cur < (2 * NFILES + 5)) {
@@ -159,14 +175,14 @@ int main(int argc, char *argv[])
159
175
  if (errno == EPERM)
160
176
  goto err_nofail;
161
177
  perror("setrlimit");
162
- goto err_noring;
178
+ return T_EXIT_FAIL;
163
179
  }
164
180
  }
165
181
 
166
182
  for (i = 0; i < NFILES; i++) {
167
183
  if (pipe(p[i].fd) < 0) {
168
184
  perror("pipe");
169
- goto err_noring;
185
+ return T_EXIT_FAIL;
170
186
  }
171
187
  }
172
188
 
@@ -176,31 +192,37 @@ int main(int argc, char *argv[])
176
192
  if (ret) {
177
193
  if (ret == -EINVAL) {
178
194
  fprintf(stdout, "No CQSIZE, trying without\n");
179
- ret = io_uring_queue_init(RING_SIZE, &ring, 0);
195
+
196
+ params.flags &= ~IORING_SETUP_CQSIZE;
197
+ params.cq_entries = 0;
198
+ ret = io_uring_queue_init_params(RING_SIZE, &ring, &params);
180
199
  if (ret) {
181
200
  fprintf(stderr, "ring setup failed: %d\n", ret);
182
- return 1;
201
+ return T_EXIT_FAIL;
183
202
  }
184
203
  }
185
204
  }
186
205
 
187
- if (arm_polls(&ring))
188
- goto err;
189
-
190
- for (i = 0; i < NLOOPS; i++) {
191
- trigger_polls();
192
- ret = reap_polls(&ring);
193
- if (ret)
194
- goto err;
206
+ if (do_test(&ring)) {
207
+ fprintf(stderr, "test (normal) failed\n");
208
+ return T_EXIT_FAIL;
195
209
  }
196
-
197
210
  io_uring_queue_exit(&ring);
211
+
212
+ if (t_probe_defer_taskrun()) {
213
+ params.flags |= IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN;
214
+ ret = io_uring_queue_init_params(RING_SIZE, &ring, &params);
215
+ if (ret) {
216
+ fprintf(stderr, "ring DEFER setup failed: %d\n", ret);
217
+ return T_EXIT_FAIL;
218
+ }
219
+ if (do_test(&ring)) {
220
+ fprintf(stderr, "test (DEFER) failed\n");
221
+ return T_EXIT_FAIL;
222
+ }
223
+ io_uring_queue_exit(&ring);
224
+ }
198
225
  return 0;
199
- err:
200
- io_uring_queue_exit(&ring);
201
- err_noring:
202
- fprintf(stderr, "poll-many failed\n");
203
- return 1;
204
226
  err_nofail:
205
227
  fprintf(stderr, "poll-many: not enough files available (and not root), "
206
228
  "skipped\n");