polyphony 0.47.5.1 → 0.50.0

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +29 -0
  3. data/Gemfile.lock +1 -1
  4. data/LICENSE +1 -1
  5. data/TODO.md +37 -17
  6. data/examples/core/nested.rb +21 -0
  7. data/examples/core/suspend.rb +13 -0
  8. data/examples/core/terminate_main_fiber.rb +12 -0
  9. data/examples/io/tcp_proxy.rb +32 -0
  10. data/examples/performance/line_splitting.rb +34 -0
  11. data/examples/performance/loop.rb +32 -0
  12. data/examples/performance/thread-vs-fiber/polyphony_server.rb +6 -2
  13. data/ext/polyphony/backend_common.h +3 -3
  14. data/ext/polyphony/backend_io_uring.c +29 -68
  15. data/ext/polyphony/backend_libev.c +18 -59
  16. data/ext/polyphony/event.c +1 -1
  17. data/ext/polyphony/fiber.c +2 -1
  18. data/ext/polyphony/polyphony.c +0 -2
  19. data/ext/polyphony/polyphony.h +6 -4
  20. data/ext/polyphony/queue.c +2 -2
  21. data/ext/polyphony/runqueue.c +6 -0
  22. data/ext/polyphony/runqueue_ring_buffer.c +9 -0
  23. data/ext/polyphony/runqueue_ring_buffer.h +1 -0
  24. data/ext/polyphony/thread.c +23 -28
  25. data/lib/polyphony.rb +2 -1
  26. data/lib/polyphony/adapters/postgres.rb +3 -3
  27. data/lib/polyphony/adapters/process.rb +2 -0
  28. data/lib/polyphony/core/exceptions.rb +1 -0
  29. data/lib/polyphony/core/global_api.rb +15 -3
  30. data/lib/polyphony/core/thread_pool.rb +3 -1
  31. data/lib/polyphony/core/throttler.rb +1 -1
  32. data/lib/polyphony/core/timer.rb +115 -0
  33. data/lib/polyphony/extensions/core.rb +4 -4
  34. data/lib/polyphony/extensions/fiber.rb +30 -13
  35. data/lib/polyphony/extensions/io.rb +8 -14
  36. data/lib/polyphony/extensions/openssl.rb +4 -4
  37. data/lib/polyphony/extensions/socket.rb +1 -1
  38. data/lib/polyphony/extensions/thread.rb +1 -2
  39. data/lib/polyphony/net.rb +3 -6
  40. data/lib/polyphony/version.rb +1 -1
  41. data/polyphony.gemspec +1 -1
  42. data/test/helper.rb +2 -2
  43. data/test/test_backend.rb +26 -1
  44. data/test/test_fiber.rb +95 -1
  45. data/test/test_global_api.rb +30 -0
  46. data/test/test_io.rb +26 -0
  47. data/test/test_signal.rb +1 -2
  48. data/test/test_socket.rb +5 -5
  49. data/test/test_supervise.rb +1 -1
  50. data/test/test_timer.rb +157 -0
  51. metadata +11 -4
  52. data/ext/polyphony/backend.h +0 -26
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d4b0d95763e1c95248c83f2b649bdafa609e5a3877ea381afa1ce7253b340904
4
- data.tar.gz: c25589fd2a4433d21778281a631b364b5505ce27c9fe3f349d2a357a3dd30f97
3
+ metadata.gz: 2aac80a08ca16498c3ee0044b0ba6de039b179425051cbcee67af4c9b948c349
4
+ data.tar.gz: bbe016d6b2ad3c5c89129089f9ebb8457a37159e03be2ff84f2572454880b0c2
5
5
  SHA512:
6
- metadata.gz: 2637f2f6aa6531e6b8bc62035a028caffd027d65668b1a1f6b957c9f89045d148b790003856ece2213ccf882e1eab12068578cce8ba0c8882213f3e8f9a125f3
7
- data.tar.gz: '0009c9eae3b3fc52239d26bc836d7a1b4d2bd24d922c02f9a986fbed5d26f76b618777422efe9909aaff27164cc53de9d7083f9b784bc5534b387e6735dc7be6'
6
+ metadata.gz: 2f91d0b40bceb4600e4bbd22f39cdbd6bfd4ac5b5fc038f77deb7d26a464ce3cad177884f9aadde60c78bc48df170ab6909c44d133283af3abf77a090ac58332
7
+ data.tar.gz: 37dfa412a25f41dd704a203a865817bf273a23db0ccbe1bbec1a3f6017b9cd953301d67077e3b58601485f4dd96db94bef77da3d46cabd57fb563d3652173175
@@ -1,3 +1,32 @@
1
+ ## 0.50.0
2
+
3
+ - Use `Process::CLOCK_MONOTONIC` in Timer
4
+ - Add `Timer#sleep`, `Timer#after`, `Timer#every`
5
+ - Prevent fiber from being resumed after terminating
6
+ - Add `Thread#fiber_index_of` method
7
+ - Use `Backend#wait_event` in `Fiber#await`
8
+
9
+ ## 0.49.2
10
+
11
+ - Fix hang with 100s or more child fibers when terminating
12
+ - Fix double pending_count increment in io_uring backend
13
+
14
+ ## 0.49.1
15
+
16
+ - Use `TCPSocket` instead of `Socket` in `Net.tcp_connect`
17
+ - Catch `Errno::ERSCH` in `Process.kill_and_await`
18
+ - Set io_uring queue size to 2048
19
+
20
+ ## 0.49.0
21
+
22
+ - Implement `Polyphony::Timer` for performant timeouts
23
+
24
+ ## 0.48.0
25
+
26
+ - Implement graceful shutdown
27
+ - Add support for `break` / `StopIteration` in `spin_loop`
28
+ - Fix `IO#gets`, `IO#readpartial`
29
+
1
30
  ## 0.47.5.1
2
31
 
3
32
  - Add missing `Socket#accept_loop` method
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- polyphony (0.47.5.1)
4
+ polyphony (0.50.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2020 Sharon Rosner
3
+ Copyright (c) 2021 Sharon Rosner
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/TODO.md CHANGED
@@ -1,29 +1,49 @@
1
- - Graceful shutdown again:
1
+ - Check segfault when resetting a `cancel_after` timeout lots of times at very high rate
2
+ - Check why `throttled_loop` inside of `move_on_after` fails to stop
3
+
4
+ - Commented out `io_uring_sqe_set_flags(sqe, IOSQE_ASYNC);` in `io_uring_backend_defer_submit_and_await`:
5
+ - This flag should be set for I/O ops, not for other stuff
6
+
7
+ - Override stock `::SizedQueue` impl with Queue with capacity
2
8
 
3
- - Fiber API:
4
- - `Fiber#terminate(graceul)` - with a graceful flag
5
- - `Fiber#terminate_all_children(graceful)` - with a graceful flag
6
- - `Fiber#shutdown_all_children(graceful)` - with a graceful flag
9
+ - Add support for `break` and `StopIteration` in all loops (with tests)
7
10
 
8
- - Set graceful termination in `@graceful_shutdown`
9
- - Add `Fiber#graceful_shutdown?` method
10
- - Returns `@graceful_shutdown`
11
+ - Change `IO#gets` to use `String#split` to cut into lines, much faster (see
12
+ examples/performance/line_splitting.rb)
13
+
14
+ - More tight loops
15
+ - `IO#gets_loop`, `Socket#gets_loop`, `OpenSSL::Socket#gets_loop` (medium effort)
16
+ - `Fiber#receive_loop` (very little effort, should be implemented in C)
11
17
 
12
- And then we have:
18
+
19
+ - Add `Backend#splice`, `Backend#splice_loop` for implementing stuff like proxying:
13
20
 
14
21
  ```ruby
15
- spin do
16
- loop { do_some_stuff }
17
- ensure
18
- shutdown_gracefully if Fiber.current.graceful_shutdown?
22
+ def two_way_proxy(socket1, socket2)
23
+ backend = Thread.current.backend
24
+ f1 = spin { backend.splice_loop(socket1, socket2) }
25
+ f2 = spin { backend.splice_loop(socket2, socket1) }
26
+ Fiber.await(f1, f2)
19
27
  end
20
28
  ```
21
29
 
30
+ - Graceful shutdown again:
31
+ - What happens to children when doing a graceful shutdown?
32
+ - What are the implications of passing graceful shutdown flag to children?
33
+ - What about errors while doing a graceful shutdown?
34
+ - What about graceful restarts?
35
+ - Some interesting discussions:
36
+ - https://trio.discourse.group/search?q=graceful%20shutdown
37
+ - https://github.com/python-trio/trio/issues/147
38
+ - https://github.com/python-trio/trio/issues/143
39
+ - https://trio.discourse.group/t/graceful-shutdown/93/2
40
+ - https://250bpm.com/blog:146/
41
+ - https://www.rodrigoaraujo.me/posts/golang-pattern-graceful-shutdown-of-concurrent-events/
42
+ - https://github.com/tj/go-gracefully
22
43
  - `Fiber#finalize_children` should pass graceful shutdown flag to children
23
-
24
- - More tight loops
25
- - IO#gets_loop, Socket#gets_loop, OpenSSL::Socket#gets_loop (medium effort)
26
- - Fiber#receive_loop (very little effort, should be implemented in C)
44
+ - A good use case is an HTTP server that on graceful shutdown:
45
+ - stops listening
46
+ - waits for all ongoing requests to finish, optionally with a timeout
27
47
 
28
48
  ## Roadmap for Polyphony 1.0
29
49
 
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'polyphony'
5
+
6
+ def process
7
+ p :b_start
8
+ sleep 1
9
+ p :b_stop
10
+ end
11
+
12
+ spin do
13
+ p :a_start
14
+ spin { process }
15
+ sleep 60
16
+ p :a_stop
17
+ end
18
+
19
+ p :main_start
20
+ sleep 120
21
+ p :main_stop
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'polyphony'
5
+
6
+ main = Fiber.current
7
+ spin do
8
+ sleep 0.1
9
+ main.schedule(:foo)
10
+ end
11
+
12
+ v = suspend
13
+ puts "v => #{v.inspect}"
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'polyphony'
5
+
6
+ main = Fiber.current
7
+ spin do
8
+ sleep 0.1
9
+ main.terminate
10
+ end
11
+
12
+ sleep
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'polyphony'
5
+
6
+ server1 = TCPServer.open('127.0.0.1', 1234)
7
+ server2 = TCPServer.open('127.0.0.1', 1235)
8
+
9
+ puts "Pid: #{Process.pid}"
10
+ puts 'Proxying port 1234 => port 1235'
11
+
12
+ client1 = client2 = nil
13
+
14
+ f1 = spin {
15
+ client1 = server1.accept
16
+ loop do
17
+ if client2
18
+ Thread.current.backend.splice_loop(client1, client2)
19
+ end
20
+ end
21
+ }
22
+
23
+ f2 = spin {
24
+ client2 = server2.accept
25
+ loop do
26
+ if client1
27
+ Thread.current.backend.splice_loop(client2, client1)
28
+ end
29
+ end
30
+ }
31
+
32
+ Fiber.await(f1, f2)
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "benchmark/ips"
4
+
5
+ def slice
6
+ str = ('*' * 40) + "\n" + ('*' * 40) + "\n" + ('*' * 40) + "\n" + ('*' * 40) + "\n" + ('*' * 40)
7
+ lines = []
8
+ while true
9
+ idx = str.index("\n")
10
+ break unless idx
11
+
12
+ lines << str.slice!(0, idx + 1)
13
+ end
14
+ raise unless lines.size == 4
15
+ raise unless str == ('*' * 40)
16
+ end
17
+
18
+ def split
19
+ str = ('*' * 40) + "\n" + ('*' * 40) + "\n" + ('*' * 40) + "\n" + ('*' * 40) + "\n" + ('*' * 40)
20
+ lines = str.split("\n")
21
+ if str[-1] == "\n"
22
+ str = ''
23
+ else
24
+ str = lines.pop
25
+ end
26
+ raise unless lines.size == 4
27
+ raise unless str == ('*' * 40)
28
+ end
29
+
30
+ Benchmark.ips do |x|
31
+ x.report("slice") { slice }
32
+ x.report("split") { split }
33
+ x.compare!
34
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'benchmark'
4
+
5
+ LIMIT = 1_000_0
6
+
7
+ def do_while
8
+ i = 0
9
+ while true
10
+ i += 1
11
+ break if i == LIMIT
12
+ end
13
+ end
14
+
15
+ def do_loop
16
+ i = 0
17
+ loop do
18
+ i += 1
19
+ break if i == LIMIT
20
+ end
21
+ end
22
+
23
+ GC.disable
24
+ Benchmark.bm do |x|
25
+ x.report('while') do
26
+ LIMIT.times { do_while }
27
+ end
28
+ x.report('loop') do
29
+ LIMIT.times { do_loop }
30
+ end
31
+ end
32
+
@@ -26,8 +26,12 @@ def write_response(socket)
26
26
  socket.write "HTTP/1.1 #{status_code}\r\n#{headers}\r\n#{data}"
27
27
  end
28
28
 
29
- server = TCPServer.open('0.0.0.0', 1234)
30
- puts "pid #{Process.pid} Polyphony (#{Thread.current.backend.kind}) listening on port 1234"
29
+ server = TCPServer.open('0.0.0.0', 4411)
30
+ puts "pid #{Process.pid} Polyphony (#{Thread.current.backend.kind}) listening on port 4411"
31
+
32
+ spin_loop(interval: 10) do
33
+ p Thread.current.fiber_scheduling_stats
34
+ end
31
35
 
32
36
  server.accept_loop do |c|
33
37
  spin { handle_client(c) }
@@ -70,9 +70,9 @@ inline VALUE io_enc_str(VALUE str, rb_io_t *fptr) {
70
70
 
71
71
  inline VALUE backend_await(Backend_t *backend) {
72
72
  VALUE ret;
73
- backend->ref_count++;
73
+ backend->pending_count++;
74
74
  ret = Thread_switch_fiber(rb_thread_current());
75
- backend->ref_count--;
75
+ backend->pending_count--;
76
76
  RB_GC_GUARD(ret);
77
77
  return ret;
78
78
  }
@@ -114,7 +114,7 @@ inline double current_time() {
114
114
  struct timespec ts;
115
115
  clock_gettime(CLOCK_MONOTONIC, &ts);
116
116
  long long ns = ts.tv_sec;
117
- ns = ns * 1000000000 + ts.tv_nsec;
117
+ ns = ns * 1e9 + ts.tv_nsec;
118
118
  double t = ns;
119
119
  return t / 1e9;
120
120
  }
@@ -30,11 +30,14 @@ static int pidfd_open(pid_t pid, unsigned int flags) {
30
30
  VALUE SYM_io_uring;
31
31
 
32
32
  typedef struct Backend_t {
33
+ // common fields
34
+ unsigned int currently_polling;
35
+ unsigned int pending_count;
36
+ unsigned int poll_no_wait_count;
37
+
38
+ // implementation-specific fields
33
39
  struct io_uring ring;
34
40
  op_context_store_t store;
35
- int waiting_for_cqe;
36
- unsigned int ref_count;
37
- unsigned int run_no_wait_count;
38
41
  unsigned int pending_sqes;
39
42
  unsigned int prepared_limit;
40
43
  int event_fd;
@@ -65,11 +68,11 @@ static VALUE Backend_initialize(VALUE self) {
65
68
  Backend_t *backend;
66
69
  GetBackend(self, backend);
67
70
 
68
- backend->waiting_for_cqe = 0;
69
- backend->ref_count = 0;
70
- backend->run_no_wait_count = 0;
71
+ backend->currently_polling = 0;
72
+ backend->pending_count = 0;
73
+ backend->poll_no_wait_count = 0;
71
74
  backend->pending_sqes = 0;
72
- backend->prepared_limit = 1024;
75
+ backend->prepared_limit = 2048;
73
76
 
74
77
  context_store_initialize(&backend->store);
75
78
  io_uring_queue_init(backend->prepared_limit, &backend->ring, 0);
@@ -95,46 +98,19 @@ VALUE Backend_post_fork(VALUE self) {
95
98
  io_uring_queue_exit(&backend->ring);
96
99
  io_uring_queue_init(backend->prepared_limit, &backend->ring, 0);
97
100
  context_store_free(&backend->store);
98
- backend->waiting_for_cqe = 0;
99
- backend->ref_count = 0;
100
- backend->run_no_wait_count = 0;
101
+ backend->currently_polling = 0;
102
+ backend->pending_count = 0;
103
+ backend->poll_no_wait_count = 0;
101
104
  backend->pending_sqes = 0;
102
105
 
103
106
  return self;
104
107
  }
105
108
 
106
- VALUE Backend_ref(VALUE self) {
107
- Backend_t *backend;
108
- GetBackend(self, backend);
109
-
110
- backend->ref_count++;
111
- return self;
112
- }
113
-
114
- VALUE Backend_unref(VALUE self) {
109
+ unsigned int Backend_pending_count(VALUE self) {
115
110
  Backend_t *backend;
116
111
  GetBackend(self, backend);
117
112
 
118
- backend->ref_count--;
119
- return self;
120
- }
121
-
122
- int Backend_ref_count(VALUE self) {
123
- Backend_t *backend;
124
- GetBackend(self, backend);
125
-
126
- return backend->ref_count;
127
- }
128
-
129
- void Backend_reset_ref_count(VALUE self) {
130
- Backend_t *backend;
131
- GetBackend(self, backend);
132
-
133
- backend->ref_count = 0;
134
- }
135
-
136
- VALUE Backend_pending_count(VALUE self) {
137
- return INT2NUM(0);
113
+ return backend->pending_count;
138
114
  }
139
115
 
140
116
  typedef struct poll_context {
@@ -158,7 +134,7 @@ static inline bool cq_ring_needs_flush(struct io_uring *ring) {
158
134
 
159
135
  void io_uring_backend_handle_completion(struct io_uring_cqe *cqe, Backend_t *backend) {
160
136
  op_context_t *ctx = io_uring_cqe_get_data(cqe);
161
- if (ctx == 0) return;
137
+ if (!ctx) return;
162
138
 
163
139
  ctx->result = cqe->res;
164
140
 
@@ -211,9 +187,9 @@ void io_uring_backend_poll(Backend_t *backend) {
211
187
  io_uring_submit(&backend->ring);
212
188
  }
213
189
 
214
- backend->waiting_for_cqe = 1;
190
+ backend->currently_polling = 1;
215
191
  rb_thread_call_without_gvl(io_uring_backend_poll_without_gvl, (void *)&poll_ctx, RUBY_UBF_IO, 0);
216
- backend->waiting_for_cqe = 0;
192
+ backend->currently_polling = 0;
217
193
  if (poll_ctx.result < 0) return;
218
194
 
219
195
  io_uring_backend_handle_completion(poll_ctx.cqe, backend);
@@ -226,14 +202,14 @@ VALUE Backend_poll(VALUE self, VALUE nowait, VALUE current_fiber, VALUE runqueue
226
202
  GetBackend(self, backend);
227
203
 
228
204
  if (is_nowait) {
229
- backend->run_no_wait_count++;
230
- if (backend->run_no_wait_count < 10) return self;
205
+ backend->poll_no_wait_count++;
206
+ if (backend->poll_no_wait_count < 10) return self;
231
207
 
232
208
  long runnable_count = Runqueue_len(runqueue);
233
- if (backend->run_no_wait_count < runnable_count) return self;
209
+ if (backend->poll_no_wait_count < runnable_count) return self;
234
210
  }
235
211
 
236
- backend->run_no_wait_count = 0;
212
+ backend->poll_no_wait_count = 0;
237
213
 
238
214
  if (is_nowait && backend->pending_sqes) {
239
215
  backend->pending_sqes = 0;
@@ -252,7 +228,7 @@ VALUE Backend_wakeup(VALUE self) {
252
228
  Backend_t *backend;
253
229
  GetBackend(self, backend);
254
230
 
255
- if (backend->waiting_for_cqe) {
231
+ if (backend->currently_polling) {
256
232
  // Since we're currently blocking while waiting for a completion, we add a
257
233
  // NOP which would cause the io_uring_enter syscall to return
258
234
  struct io_uring_sqe *sqe = io_uring_get_sqe(&backend->ring);
@@ -284,12 +260,10 @@ int io_uring_backend_defer_submit_and_await(
284
260
  VALUE switchpoint_result = Qnil;
285
261
 
286
262
  io_uring_sqe_set_data(sqe, ctx);
287
- io_uring_sqe_set_flags(sqe, IOSQE_ASYNC);
263
+ // io_uring_sqe_set_flags(sqe, IOSQE_ASYNC);
288
264
  io_uring_backend_defer_submit(backend);
289
265
 
290
- backend->ref_count++;
291
266
  switchpoint_result = backend_await(backend);
292
- backend->ref_count--;
293
267
 
294
268
  if (!ctx->completed) {
295
269
  ctx->result = -ECANCELED;
@@ -351,7 +325,7 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof)
351
325
 
352
326
  if (result < 0)
353
327
  rb_syserr_fail(-result, strerror(-result));
354
- else if (result == 0)
328
+ else if (!result)
355
329
  break; // EOF
356
330
  else {
357
331
  total += result;
@@ -373,7 +347,7 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof)
373
347
  io_set_read_length(str, total, shrinkable);
374
348
  io_enc_str(str, fptr);
375
349
 
376
- if (total == 0) return Qnil;
350
+ if (!total) return Qnil;
377
351
 
378
352
  return str;
379
353
  }
@@ -410,7 +384,7 @@ VALUE Backend_read_loop(VALUE self, VALUE io) {
410
384
 
411
385
  if (result < 0)
412
386
  rb_syserr_fail(-result, strerror(-result));
413
- else if (result == 0)
387
+ else if (!result)
414
388
  break; // EOF
415
389
  else {
416
390
  total = result;
@@ -581,7 +555,7 @@ VALUE Backend_recv(VALUE self, VALUE io, VALUE str, VALUE length) {
581
555
  io_set_read_length(str, total, shrinkable);
582
556
  io_enc_str(str, fptr);
583
557
 
584
- if (total == 0) return Qnil;
558
+ if (!total) return Qnil;
585
559
 
586
560
  return str;
587
561
  }
@@ -618,7 +592,7 @@ VALUE Backend_recv_loop(VALUE self, VALUE io) {
618
592
 
619
593
  if (result < 0)
620
594
  rb_syserr_fail(-result, strerror(-result));
621
- else if (result == 0)
595
+ else if (!result)
622
596
  break; // EOF
623
597
  else {
624
598
  total = result;
@@ -950,10 +924,6 @@ void Init_Backend() {
950
924
  rb_define_method(cBackend, "initialize", Backend_initialize, 0);
951
925
  rb_define_method(cBackend, "finalize", Backend_finalize, 0);
952
926
  rb_define_method(cBackend, "post_fork", Backend_post_fork, 0);
953
- rb_define_method(cBackend, "pending_count", Backend_pending_count, 0);
954
-
955
- rb_define_method(cBackend, "ref", Backend_ref, 0);
956
- rb_define_method(cBackend, "unref", Backend_unref, 0);
957
927
 
958
928
  rb_define_method(cBackend, "poll", Backend_poll, 3);
959
929
  rb_define_method(cBackend, "break", Backend_wakeup, 0);
@@ -977,15 +947,6 @@ void Init_Backend() {
977
947
  rb_define_method(cBackend, "kind", Backend_kind, 0);
978
948
 
979
949
  SYM_io_uring = ID2SYM(rb_intern("io_uring"));
980
-
981
- __BACKEND__.pending_count = Backend_pending_count;
982
- __BACKEND__.poll = Backend_poll;
983
- __BACKEND__.ref = Backend_ref;
984
- __BACKEND__.ref_count = Backend_ref_count;
985
- __BACKEND__.reset_ref_count = Backend_reset_ref_count;
986
- __BACKEND__.unref = Backend_unref;
987
- __BACKEND__.wait_event = Backend_wait_event;
988
- __BACKEND__.wakeup = Backend_wakeup;
989
950
  }
990
951
 
991
952
  #endif // POLYPHONY_BACKEND_LIBURING