polyphony 0.47.4 → 0.49.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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +321 -296
  3. data/Gemfile.lock +1 -1
  4. data/LICENSE +1 -1
  5. data/TODO.md +38 -29
  6. data/examples/core/supervisor.rb +3 -3
  7. data/examples/core/worker-thread.rb +3 -4
  8. data/examples/io/tcp_proxy.rb +32 -0
  9. data/examples/performance/line_splitting.rb +34 -0
  10. data/examples/performance/loop.rb +32 -0
  11. data/examples/performance/thread-vs-fiber/polyphony_server.rb +6 -0
  12. data/ext/polyphony/backend_common.h +2 -22
  13. data/ext/polyphony/backend_io_uring.c +38 -78
  14. data/ext/polyphony/backend_libev.c +22 -67
  15. data/ext/polyphony/event.c +1 -1
  16. data/ext/polyphony/polyphony.c +0 -2
  17. data/ext/polyphony/polyphony.h +5 -4
  18. data/ext/polyphony/queue.c +2 -2
  19. data/ext/polyphony/thread.c +9 -28
  20. data/lib/polyphony.rb +2 -1
  21. data/lib/polyphony/adapters/postgres.rb +3 -3
  22. data/lib/polyphony/adapters/process.rb +2 -0
  23. data/lib/polyphony/core/global_api.rb +14 -2
  24. data/lib/polyphony/core/thread_pool.rb +3 -1
  25. data/lib/polyphony/core/throttler.rb +1 -1
  26. data/lib/polyphony/core/timer.rb +72 -0
  27. data/lib/polyphony/extensions/fiber.rb +32 -8
  28. data/lib/polyphony/extensions/io.rb +8 -14
  29. data/lib/polyphony/extensions/openssl.rb +4 -4
  30. data/lib/polyphony/extensions/socket.rb +13 -10
  31. data/lib/polyphony/net.rb +3 -6
  32. data/lib/polyphony/version.rb +1 -1
  33. data/polyphony.gemspec +1 -1
  34. data/test/helper.rb +1 -0
  35. data/test/test_backend.rb +1 -1
  36. data/test/test_fiber.rb +64 -1
  37. data/test/test_global_api.rb +30 -0
  38. data/test/test_io.rb +26 -0
  39. data/test/test_socket.rb +32 -6
  40. data/test/test_supervise.rb +2 -1
  41. data/test/test_timer.rb +124 -0
  42. metadata +8 -4
  43. data/ext/polyphony/backend.h +0 -26
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- polyphony (0.47.4)
4
+ polyphony (0.49.1)
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,49 +1,58 @@
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
2
3
 
3
- - Add `Polyphony::GracefulShutdown` exception
4
- - Two exceptions for stopping fibers:
5
- - `Polyphony::GracefulShutdown` - graceful shutdown
6
- - `Polyphony::Terminate` - ungraceful shutdown
7
- - Fiber API:
8
- - `Fiber#shutdown_children` - graceful shutdown of all children
9
- - `Fiber#terminate_children` - ungraceful shutdown of all children
4
+ - Override stock `::SizedQueue` impl with Queue with capacity
10
5
 
11
- - Add `Fiber#graceful_shutdown?` method
12
- - Returns false unless a `Polyphony::GracefulShutdown` was raised
13
- - Override `Polyphony::Terminate#invoke` to reset the `@graceful_shutdown` fiber
14
- flag
6
+ - Add support for `break` and `StopIteration` in all loops (with tests)
15
7
 
16
- And then we have:
8
+ - Change `IO#gets` to use `String#split` to cut into lines, much faster (see
9
+ examples/performance/line_splitting.rb)
10
+
11
+ - More tight loops
12
+ - `IO#gets_loop`, `Socket#gets_loop`, `OpenSSL::Socket#gets_loop` (medium effort)
13
+ - `Fiber#receive_loop` (very little effort, should be implemented in C)
17
14
 
18
- ```ruby
19
- spin do
20
- loop { do_some_stuff }
21
- ensure
22
- return unless Fiber.current.graceful_shutdown?
23
15
 
24
- shutdown_gracefully
16
+ - Add `Backend#splice`, `Backend#splice_loop` for implementing stuff like proxying:
17
+
18
+ ```ruby
19
+ def two_way_proxy(socket1, socket2)
20
+ backend = Thread.current.backend
21
+ f1 = spin { backend.splice_loop(socket1, socket2) }
22
+ f2 = spin { backend.splice_loop(socket2, socket1) }
23
+ Fiber.await(f1, f2)
25
24
  end
26
25
  ```
27
26
 
28
- - When a fiber is stopped it should use `Polyphony::Terminate` to stop child
29
- fibers, *unless* it was stopped with a `Polyphony::GracefulShutdown` (which it
30
- can check with `@graceful_shutdown`).
31
-
32
- - More tight loops
33
- - IO#gets_loop, Socket#gets_loop, OpenSSL::Socket#gets_loop (medium effort)
34
- - Fiber#receive_loop (very little effort, should be implemented in C)
27
+ - Graceful shutdown again:
28
+ - What happens to children when doing a graceful shutdown?
29
+ - What are the implications of passing graceful shutdown flag to children?
30
+ - What about errors while doing a graceful shutdown?
31
+ - What about graceful restarts?
32
+ - Some interesting discussions:
33
+ - https://trio.discourse.group/search?q=graceful%20shutdown
34
+ - https://github.com/python-trio/trio/issues/147
35
+ - https://github.com/python-trio/trio/issues/143
36
+ - https://trio.discourse.group/t/graceful-shutdown/93/2
37
+ - https://250bpm.com/blog:146/
38
+ - https://www.rodrigoaraujo.me/posts/golang-pattern-graceful-shutdown-of-concurrent-events/
39
+ - https://github.com/tj/go-gracefully
40
+ - `Fiber#finalize_children` should pass graceful shutdown flag to children
41
+ - A good use case is an HTTP server that on graceful shutdown:
42
+ - stops listening
43
+ - waits for all ongoing requests to finish, optionally with a timeout
35
44
 
36
45
  ## Roadmap for Polyphony 1.0
37
46
 
38
47
  - check integration with rb-inotify
39
48
 
40
- - Check why worker-thread example doesn't work.
49
+ - Improve `#supervise`. It does not work as advertised, and seems to exhibit an
50
+ inconsistent behaviour (see supervisor example).
51
+
41
52
  - Add test that mimics the original design for Monocrono:
42
53
  - 256 fibers each waiting for a message
43
54
  - When message received do some blocking work using a `ThreadPool`
44
55
  - Send messages, collect responses, check for correctness
45
- - Improve `#supervise`. It does not work as advertised, and seems to exhibit an
46
- inconsistent behaviour (see supervisor example).
47
56
 
48
57
  - io_uring
49
58
  - Use playground.c to find out why we when submitting and waiting for
@@ -9,9 +9,9 @@ def my_sleep(t)
9
9
  puts "#{t} done"
10
10
  end
11
11
 
12
- spin { my_sleep(1) }
13
- spin { my_sleep(2) }
14
- spin { my_sleep(3) }
12
+ spin { my_sleep(0.1) }
13
+ spin { my_sleep(0.2) }
14
+ spin { my_sleep(0.3) }
15
15
  spin { puts "fiber count: #{Fiber.current.children.count}" }
16
16
  snooze
17
17
 
@@ -13,11 +13,9 @@ end
13
13
  $worker = Thread.new do
14
14
  Fiber.current.tag = :worker
15
15
  loop do
16
- client, block = receive
16
+ (client, block) = receive
17
17
  do_work(client, &block)
18
18
  end
19
- rescue Exception => e
20
- p e
21
19
  end
22
20
 
23
21
  def process(&block)
@@ -27,4 +25,5 @@ end
27
25
 
28
26
  sleep 0.1
29
27
 
30
- p process { 1 + 1 }
28
+ p process { 1 + 1 }
29
+ p process { 42 ** 2 }
@@ -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
+
@@ -29,6 +29,12 @@ end
29
29
  server = TCPServer.open('0.0.0.0', 1234)
30
30
  puts "pid #{Process.pid} Polyphony (#{Thread.current.backend.kind}) listening on port 1234"
31
31
 
32
+ spin_loop(interval: 10) do
33
+ p Thread.current.fiber_scheduling_stats
34
+ end
35
+
36
+ GC.disable
37
+
32
38
  server.accept_loop do |c|
33
39
  spin { handle_client(c) }
34
40
  end
@@ -3,26 +3,6 @@
3
3
  #include "ruby.h"
4
4
  #include "ruby/io.h"
5
5
 
6
- VALUE cTCPSocket;
7
- VALUE cTCPServer;
8
- VALUE cUNIXSocket;
9
- VALUE cUNIXServer;
10
-
11
- void Init_SocketClasses() {
12
- rb_require("socket");
13
- cTCPSocket = rb_const_get(rb_cObject, rb_intern("TCPSocket"));
14
- cTCPServer = rb_const_get(rb_cObject, rb_intern("TCPServer"));
15
- cUNIXSocket = rb_const_get(rb_cObject, rb_intern("UNIXSocket"));
16
- cUNIXServer = rb_const_get(rb_cObject, rb_intern("UNIXServer"));
17
- }
18
-
19
- VALUE ConnectionSocketClass(VALUE server) {
20
- if (RTEST(rb_obj_is_kind_of(server, cTCPServer))) return cTCPSocket;
21
- if (RTEST(rb_obj_is_kind_of(server, cUNIXServer))) return cUNIXSocket;
22
-
23
- rb_raise(rb_eRuntimeError, "Invalid server class");
24
- }
25
-
26
6
  //////////////////////////////////////////////////////////////////////
27
7
  //////////////////////////////////////////////////////////////////////
28
8
  // the following is copied verbatim from the Ruby source code (io.c)
@@ -90,9 +70,9 @@ inline VALUE io_enc_str(VALUE str, rb_io_t *fptr) {
90
70
 
91
71
  inline VALUE backend_await(Backend_t *backend) {
92
72
  VALUE ret;
93
- backend->ref_count++;
73
+ backend->pending_count++;
94
74
  ret = Thread_switch_fiber(rb_thread_current());
95
- backend->ref_count--;
75
+ backend->pending_count--;
96
76
  RB_GC_GUARD(ret);
97
77
  return ret;
98
78
  }
@@ -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) {
115
- Backend_t *backend;
116
- GetBackend(self, backend);
117
-
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) {
109
+ unsigned int Backend_pending_count(VALUE self) {
130
110
  Backend_t *backend;
131
111
  GetBackend(self, backend);
132
112
 
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,12 @@ 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++;
266
+ backend->pending_count++;
291
267
  switchpoint_result = backend_await(backend);
292
- backend->ref_count--;
268
+ backend->pending_count--;
293
269
 
294
270
  if (!ctx->completed) {
295
271
  ctx->result = -ECANCELED;
@@ -351,7 +327,7 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof)
351
327
 
352
328
  if (result < 0)
353
329
  rb_syserr_fail(-result, strerror(-result));
354
- else if (result == 0)
330
+ else if (!result)
355
331
  break; // EOF
356
332
  else {
357
333
  total += result;
@@ -373,7 +349,7 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof)
373
349
  io_set_read_length(str, total, shrinkable);
374
350
  io_enc_str(str, fptr);
375
351
 
376
- if (total == 0) return Qnil;
352
+ if (!total) return Qnil;
377
353
 
378
354
  return str;
379
355
  }
@@ -410,7 +386,7 @@ VALUE Backend_read_loop(VALUE self, VALUE io) {
410
386
 
411
387
  if (result < 0)
412
388
  rb_syserr_fail(-result, strerror(-result));
413
- else if (result == 0)
389
+ else if (!result)
414
390
  break; // EOF
415
391
  else {
416
392
  total = result;
@@ -581,7 +557,7 @@ VALUE Backend_recv(VALUE self, VALUE io, VALUE str, VALUE length) {
581
557
  io_set_read_length(str, total, shrinkable);
582
558
  io_enc_str(str, fptr);
583
559
 
584
- if (total == 0) return Qnil;
560
+ if (!total) return Qnil;
585
561
 
586
562
  return str;
587
563
  }
@@ -618,7 +594,7 @@ VALUE Backend_recv_loop(VALUE self, VALUE io) {
618
594
 
619
595
  if (result < 0)
620
596
  rb_syserr_fail(-result, strerror(-result));
621
- else if (result == 0)
597
+ else if (!result)
622
598
  break; // EOF
623
599
  else {
624
600
  total = result;
@@ -668,12 +644,11 @@ VALUE Backend_send(VALUE self, VALUE io, VALUE str) {
668
644
  return INT2NUM(len);
669
645
  }
670
646
 
671
- VALUE io_uring_backend_accept(Backend_t *backend, VALUE server_socket, int loop) {
647
+ VALUE io_uring_backend_accept(Backend_t *backend, VALUE server_socket, VALUE socket_class, int loop) {
672
648
  rb_io_t *fptr;
673
649
  struct sockaddr addr;
674
650
  socklen_t len = (socklen_t)sizeof addr;
675
651
  VALUE socket = Qnil;
676
- VALUE socket_class = ConnectionSocketClass(server_socket);
677
652
  VALUE underlying_sock = rb_ivar_get(server_socket, ID_ivar_io);
678
653
  if (underlying_sock != Qnil) server_socket = underlying_sock;
679
654
 
@@ -718,16 +693,16 @@ VALUE io_uring_backend_accept(Backend_t *backend, VALUE server_socket, int loop)
718
693
  return Qnil;
719
694
  }
720
695
 
721
- VALUE Backend_accept(VALUE self, VALUE sock) {
696
+ VALUE Backend_accept(VALUE self, VALUE server_socket, VALUE socket_class) {
722
697
  Backend_t *backend;
723
698
  GetBackend(self, backend);
724
- return io_uring_backend_accept(backend, sock, 0);
699
+ return io_uring_backend_accept(backend, server_socket, socket_class, 0);
725
700
  }
726
701
 
727
- VALUE Backend_accept_loop(VALUE self, VALUE sock) {
702
+ VALUE Backend_accept_loop(VALUE self, VALUE server_socket, VALUE socket_class) {
728
703
  Backend_t *backend;
729
704
  GetBackend(self, backend);
730
- io_uring_backend_accept(backend, sock, 1);
705
+ io_uring_backend_accept(backend, server_socket, socket_class, 1);
731
706
  return self;
732
707
  }
733
708
 
@@ -945,18 +920,12 @@ VALUE Backend_kind(VALUE self) {
945
920
  }
946
921
 
947
922
  void Init_Backend() {
948
- Init_SocketClasses();
949
-
950
923
  VALUE cBackend = rb_define_class_under(mPolyphony, "Backend", rb_cData);
951
924
  rb_define_alloc_func(cBackend, Backend_allocate);
952
925
 
953
926
  rb_define_method(cBackend, "initialize", Backend_initialize, 0);
954
927
  rb_define_method(cBackend, "finalize", Backend_finalize, 0);
955
928
  rb_define_method(cBackend, "post_fork", Backend_post_fork, 0);
956
- rb_define_method(cBackend, "pending_count", Backend_pending_count, 0);
957
-
958
- rb_define_method(cBackend, "ref", Backend_ref, 0);
959
- rb_define_method(cBackend, "unref", Backend_unref, 0);
960
929
 
961
930
  rb_define_method(cBackend, "poll", Backend_poll, 3);
962
931
  rb_define_method(cBackend, "break", Backend_wakeup, 0);
@@ -967,8 +936,8 @@ void Init_Backend() {
967
936
  rb_define_method(cBackend, "recv", Backend_recv, 3);
968
937
  rb_define_method(cBackend, "recv_loop", Backend_recv_loop, 1);
969
938
  rb_define_method(cBackend, "send", Backend_send, 2);
970
- rb_define_method(cBackend, "accept", Backend_accept, 1);
971
- rb_define_method(cBackend, "accept_loop", Backend_accept_loop, 1);
939
+ rb_define_method(cBackend, "accept", Backend_accept, 2);
940
+ rb_define_method(cBackend, "accept_loop", Backend_accept_loop, 2);
972
941
  rb_define_method(cBackend, "connect", Backend_connect, 3);
973
942
  rb_define_method(cBackend, "wait_io", Backend_wait_io, 2);
974
943
  rb_define_method(cBackend, "sleep", Backend_sleep, 1);
@@ -980,15 +949,6 @@ void Init_Backend() {
980
949
  rb_define_method(cBackend, "kind", Backend_kind, 0);
981
950
 
982
951
  SYM_io_uring = ID2SYM(rb_intern("io_uring"));
983
-
984
- __BACKEND__.pending_count = Backend_pending_count;
985
- __BACKEND__.poll = Backend_poll;
986
- __BACKEND__.ref = Backend_ref;
987
- __BACKEND__.ref_count = Backend_ref_count;
988
- __BACKEND__.reset_ref_count = Backend_reset_ref_count;
989
- __BACKEND__.unref = Backend_unref;
990
- __BACKEND__.wait_event = Backend_wait_event;
991
- __BACKEND__.wakeup = Backend_wakeup;
992
952
  }
993
953
 
994
954
  #endif // POLYPHONY_BACKEND_LIBURING