polyphony 0.47.3 → 0.49.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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +318 -295
  3. data/Gemfile.lock +1 -1
  4. data/LICENSE +1 -1
  5. data/TODO.md +40 -27
  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/io/unix_socket.rb +26 -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 -0
  13. data/ext/polyphony/backend_common.h +2 -2
  14. data/ext/polyphony/backend_io_uring.c +42 -83
  15. data/ext/polyphony/backend_libev.c +32 -77
  16. data/ext/polyphony/event.c +1 -1
  17. data/ext/polyphony/polyphony.c +0 -2
  18. data/ext/polyphony/polyphony.h +5 -4
  19. data/ext/polyphony/queue.c +2 -2
  20. data/ext/polyphony/thread.c +9 -28
  21. data/lib/polyphony.rb +1 -0
  22. data/lib/polyphony/adapters/postgres.rb +3 -3
  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 +68 -16
  31. data/lib/polyphony/version.rb +1 -1
  32. data/polyphony.gemspec +1 -1
  33. data/test/helper.rb +1 -0
  34. data/test/test_backend.rb +1 -1
  35. data/test/test_fiber.rb +64 -1
  36. data/test/test_global_api.rb +30 -0
  37. data/test/test_io.rb +26 -0
  38. data/test/test_socket.rb +32 -6
  39. data/test/test_supervise.rb +2 -1
  40. data/test/test_timer.rb +122 -0
  41. metadata +9 -4
  42. data/ext/polyphony/backend.h +0 -26
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- polyphony (0.47.3)
4
+ polyphony (0.49.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,44 +1,57 @@
1
- Graceful shutdown again:
1
+ - Check segfault when doing lots of `cancel_after` calls
2
2
 
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
3
+ - Override stock `SizedQueue` impl with Queue with capacity
10
4
 
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
5
+ - Add support for `break` and `StopIteration` in all loops (with tests)
15
6
 
16
- And then we have:
7
+ - Change `IO#gets` to use `String#split` to cut into lines, much faster (see
8
+ examples/performance/line_splitting.rb)
17
9
 
18
- ```ruby
19
- spin do
20
- loop { do_some_stuff }
21
- ensure
22
- return unless Fiber.current.graceful_shutdown?
10
+ - More tight loops
11
+ - `IO#gets_loop`, `Socket#gets_loop`, `OpenSSL::Socket#gets_loop` (medium effort)
12
+ - `Fiber#receive_loop` (very little effort, should be implemented in C)
23
13
 
24
- shutdown_gracefully
25
- end
26
- ```
27
14
 
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`).
15
+ - Add `Backend#splice`, `Backend#splice_loop` for implementing stuff like proxying:
31
16
 
17
+ ```ruby
18
+ def two_way_proxy(socket1, socket2)
19
+ backend = Thread.current.backend
20
+ f1 = spin { backend.splice_loop(socket1, socket2) }
21
+ f2 = spin { backend.splice_loop(socket2, socket1) }
22
+ Fiber.await(f1, f2)
23
+ end
24
+ ```
25
+
26
+ - Graceful shutdown again:
27
+ - What happens to children when doing a graceful shutdown?
28
+ - What are the implications of passing graceful shutdown flag to children?
29
+ - What about errors while doing a graceful shutdown?
30
+ - What about graceful restarts?
31
+ - Some interesting discussions:
32
+ - https://trio.discourse.group/search?q=graceful%20shutdown
33
+ - https://github.com/python-trio/trio/issues/147
34
+ - https://github.com/python-trio/trio/issues/143
35
+ - https://trio.discourse.group/t/graceful-shutdown/93/2
36
+ - https://250bpm.com/blog:146/
37
+ - https://www.rodrigoaraujo.me/posts/golang-pattern-graceful-shutdown-of-concurrent-events/
38
+ - https://github.com/tj/go-gracefully
39
+ - `Fiber#finalize_children` should pass graceful shutdown flag to children
40
+ - A good use case is an HTTP server that on graceful shutdown:
41
+ - stops listening
42
+ - waits for all ongoing requests to finish, optionally with a timeout
32
43
 
33
44
  ## Roadmap for Polyphony 1.0
34
45
 
35
- - Check why worker-thread example doesn't work.
46
+ - check integration with rb-inotify
47
+
48
+ - Improve `#supervise`. It does not work as advertised, and seems to exhibit an
49
+ inconsistent behaviour (see supervisor example).
50
+
36
51
  - Add test that mimics the original design for Monocrono:
37
52
  - 256 fibers each waiting for a message
38
53
  - When message received do some blocking work using a `ThreadPool`
39
54
  - Send messages, collect responses, check for correctness
40
- - Improve `#supervise`. It does not work as advertised, and seems to exhibit an
41
- inconsistent behaviour (see supervisor example).
42
55
 
43
56
  - io_uring
44
57
  - 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,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'polyphony'
5
+ require 'fileutils'
6
+
7
+ unix_path = '/tmp/polyphony-unix-socket'
8
+
9
+ FileUtils.rm unix_path rescue nil
10
+ server = UNIXServer.new(unix_path)
11
+ spin do
12
+ server.accept_loop do |socket|
13
+ p [:accept, socket]
14
+ spin do
15
+ while (line = socket.gets)
16
+ socket.puts line
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ snooze
23
+ client = UNIXSocket.new('/tmp/polyphony-unix-socket')
24
+ p [:connected, client]
25
+ client.puts 'hello!'
26
+ p client.gets
@@ -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
@@ -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
  }
@@ -27,15 +27,17 @@ static int pidfd_open(pid_t pid, unsigned int flags) {
27
27
  return syscall(__NR_pidfd_open, pid, flags);
28
28
  }
29
29
 
30
- VALUE cTCPSocket;
31
30
  VALUE SYM_io_uring;
32
31
 
33
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
34
39
  struct io_uring ring;
35
40
  op_context_store_t store;
36
- int waiting_for_cqe;
37
- unsigned int ref_count;
38
- unsigned int run_no_wait_count;
39
41
  unsigned int pending_sqes;
40
42
  unsigned int prepared_limit;
41
43
  int event_fd;
@@ -66,11 +68,11 @@ static VALUE Backend_initialize(VALUE self) {
66
68
  Backend_t *backend;
67
69
  GetBackend(self, backend);
68
70
 
69
- backend->waiting_for_cqe = 0;
70
- backend->ref_count = 0;
71
- backend->run_no_wait_count = 0;
71
+ backend->currently_polling = 0;
72
+ backend->pending_count = 0;
73
+ backend->poll_no_wait_count = 0;
72
74
  backend->pending_sqes = 0;
73
- backend->prepared_limit = 1024;
75
+ backend->prepared_limit = 256;
74
76
 
75
77
  context_store_initialize(&backend->store);
76
78
  io_uring_queue_init(backend->prepared_limit, &backend->ring, 0);
@@ -96,46 +98,19 @@ VALUE Backend_post_fork(VALUE self) {
96
98
  io_uring_queue_exit(&backend->ring);
97
99
  io_uring_queue_init(backend->prepared_limit, &backend->ring, 0);
98
100
  context_store_free(&backend->store);
99
- backend->waiting_for_cqe = 0;
100
- backend->ref_count = 0;
101
- backend->run_no_wait_count = 0;
101
+ backend->currently_polling = 0;
102
+ backend->pending_count = 0;
103
+ backend->poll_no_wait_count = 0;
102
104
  backend->pending_sqes = 0;
103
105
 
104
106
  return self;
105
107
  }
106
108
 
107
- VALUE Backend_ref(VALUE self) {
108
- Backend_t *backend;
109
- GetBackend(self, backend);
110
-
111
- backend->ref_count++;
112
- return self;
113
- }
114
-
115
- VALUE Backend_unref(VALUE self) {
109
+ unsigned int Backend_pending_count(VALUE self) {
116
110
  Backend_t *backend;
117
111
  GetBackend(self, backend);
118
112
 
119
- backend->ref_count--;
120
- return self;
121
- }
122
-
123
- int Backend_ref_count(VALUE self) {
124
- Backend_t *backend;
125
- GetBackend(self, backend);
126
-
127
- return backend->ref_count;
128
- }
129
-
130
- void Backend_reset_ref_count(VALUE self) {
131
- Backend_t *backend;
132
- GetBackend(self, backend);
133
-
134
- backend->ref_count = 0;
135
- }
136
-
137
- VALUE Backend_pending_count(VALUE self) {
138
- return INT2NUM(0);
113
+ return backend->pending_count;
139
114
  }
140
115
 
141
116
  typedef struct poll_context {
@@ -159,7 +134,7 @@ static inline bool cq_ring_needs_flush(struct io_uring *ring) {
159
134
 
160
135
  void io_uring_backend_handle_completion(struct io_uring_cqe *cqe, Backend_t *backend) {
161
136
  op_context_t *ctx = io_uring_cqe_get_data(cqe);
162
- if (ctx == 0) return;
137
+ if (!ctx) return;
163
138
 
164
139
  ctx->result = cqe->res;
165
140
 
@@ -212,9 +187,9 @@ void io_uring_backend_poll(Backend_t *backend) {
212
187
  io_uring_submit(&backend->ring);
213
188
  }
214
189
 
215
- backend->waiting_for_cqe = 1;
190
+ backend->currently_polling = 1;
216
191
  rb_thread_call_without_gvl(io_uring_backend_poll_without_gvl, (void *)&poll_ctx, RUBY_UBF_IO, 0);
217
- backend->waiting_for_cqe = 0;
192
+ backend->currently_polling = 0;
218
193
  if (poll_ctx.result < 0) return;
219
194
 
220
195
  io_uring_backend_handle_completion(poll_ctx.cqe, backend);
@@ -227,14 +202,14 @@ VALUE Backend_poll(VALUE self, VALUE nowait, VALUE current_fiber, VALUE runqueue
227
202
  GetBackend(self, backend);
228
203
 
229
204
  if (is_nowait) {
230
- backend->run_no_wait_count++;
231
- 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;
232
207
 
233
208
  long runnable_count = Runqueue_len(runqueue);
234
- if (backend->run_no_wait_count < runnable_count) return self;
209
+ if (backend->poll_no_wait_count < runnable_count) return self;
235
210
  }
236
211
 
237
- backend->run_no_wait_count = 0;
212
+ backend->poll_no_wait_count = 0;
238
213
 
239
214
  if (is_nowait && backend->pending_sqes) {
240
215
  backend->pending_sqes = 0;
@@ -253,7 +228,7 @@ VALUE Backend_wakeup(VALUE self) {
253
228
  Backend_t *backend;
254
229
  GetBackend(self, backend);
255
230
 
256
- if (backend->waiting_for_cqe) {
231
+ if (backend->currently_polling) {
257
232
  // Since we're currently blocking while waiting for a completion, we add a
258
233
  // NOP which would cause the io_uring_enter syscall to return
259
234
  struct io_uring_sqe *sqe = io_uring_get_sqe(&backend->ring);
@@ -285,12 +260,12 @@ int io_uring_backend_defer_submit_and_await(
285
260
  VALUE switchpoint_result = Qnil;
286
261
 
287
262
  io_uring_sqe_set_data(sqe, ctx);
288
- io_uring_sqe_set_flags(sqe, IOSQE_ASYNC);
263
+ // io_uring_sqe_set_flags(sqe, IOSQE_ASYNC);
289
264
  io_uring_backend_defer_submit(backend);
290
265
 
291
- backend->ref_count++;
266
+ backend->pending_count++;
292
267
  switchpoint_result = backend_await(backend);
293
- backend->ref_count--;
268
+ backend->pending_count--;
294
269
 
295
270
  if (!ctx->completed) {
296
271
  ctx->result = -ECANCELED;
@@ -352,7 +327,7 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof)
352
327
 
353
328
  if (result < 0)
354
329
  rb_syserr_fail(-result, strerror(-result));
355
- else if (result == 0)
330
+ else if (!result)
356
331
  break; // EOF
357
332
  else {
358
333
  total += result;
@@ -374,7 +349,7 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof)
374
349
  io_set_read_length(str, total, shrinkable);
375
350
  io_enc_str(str, fptr);
376
351
 
377
- if (total == 0) return Qnil;
352
+ if (!total) return Qnil;
378
353
 
379
354
  return str;
380
355
  }
@@ -411,7 +386,7 @@ VALUE Backend_read_loop(VALUE self, VALUE io) {
411
386
 
412
387
  if (result < 0)
413
388
  rb_syserr_fail(-result, strerror(-result));
414
- else if (result == 0)
389
+ else if (!result)
415
390
  break; // EOF
416
391
  else {
417
392
  total = result;
@@ -582,7 +557,7 @@ VALUE Backend_recv(VALUE self, VALUE io, VALUE str, VALUE length) {
582
557
  io_set_read_length(str, total, shrinkable);
583
558
  io_enc_str(str, fptr);
584
559
 
585
- if (total == 0) return Qnil;
560
+ if (!total) return Qnil;
586
561
 
587
562
  return str;
588
563
  }
@@ -619,7 +594,7 @@ VALUE Backend_recv_loop(VALUE self, VALUE io) {
619
594
 
620
595
  if (result < 0)
621
596
  rb_syserr_fail(-result, strerror(-result));
622
- else if (result == 0)
597
+ else if (!result)
623
598
  break; // EOF
624
599
  else {
625
600
  total = result;
@@ -669,15 +644,15 @@ VALUE Backend_send(VALUE self, VALUE io, VALUE str) {
669
644
  return INT2NUM(len);
670
645
  }
671
646
 
672
- VALUE io_uring_backend_accept(Backend_t *backend, VALUE sock, int loop) {
647
+ VALUE io_uring_backend_accept(Backend_t *backend, VALUE server_socket, VALUE socket_class, int loop) {
673
648
  rb_io_t *fptr;
674
649
  struct sockaddr addr;
675
650
  socklen_t len = (socklen_t)sizeof addr;
676
- VALUE underlying_sock = rb_ivar_get(sock, ID_ivar_io);
677
651
  VALUE socket = Qnil;
678
- if (underlying_sock != Qnil) sock = underlying_sock;
652
+ VALUE underlying_sock = rb_ivar_get(server_socket, ID_ivar_io);
653
+ if (underlying_sock != Qnil) server_socket = underlying_sock;
679
654
 
680
- GetOpenFile(sock, fptr);
655
+ GetOpenFile(server_socket, fptr);
681
656
  while (1) {
682
657
  VALUE resume_value = Qnil;
683
658
  op_context_t *ctx = OP_CONTEXT_ACQUIRE(&backend->store, OP_ACCEPT);
@@ -695,7 +670,7 @@ VALUE io_uring_backend_accept(Backend_t *backend, VALUE sock, int loop) {
695
670
  else {
696
671
  rb_io_t *fp;
697
672
 
698
- socket = rb_obj_alloc(cTCPSocket);
673
+ socket = rb_obj_alloc(socket_class);
699
674
  MakeOpenFile(socket, fp);
700
675
  rb_update_max_fd(fd);
701
676
  fp->fd = fd;
@@ -718,16 +693,16 @@ VALUE io_uring_backend_accept(Backend_t *backend, VALUE sock, 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,19 +920,12 @@ VALUE Backend_kind(VALUE self) {
945
920
  }
946
921
 
947
922
  void Init_Backend() {
948
- rb_require("socket");
949
- cTCPSocket = rb_const_get(rb_cObject, rb_intern("TCPSocket"));
950
-
951
923
  VALUE cBackend = rb_define_class_under(mPolyphony, "Backend", rb_cData);
952
924
  rb_define_alloc_func(cBackend, Backend_allocate);
953
925
 
954
926
  rb_define_method(cBackend, "initialize", Backend_initialize, 0);
955
927
  rb_define_method(cBackend, "finalize", Backend_finalize, 0);
956
928
  rb_define_method(cBackend, "post_fork", Backend_post_fork, 0);
957
- rb_define_method(cBackend, "pending_count", Backend_pending_count, 0);
958
-
959
- rb_define_method(cBackend, "ref", Backend_ref, 0);
960
- rb_define_method(cBackend, "unref", Backend_unref, 0);
961
929
 
962
930
  rb_define_method(cBackend, "poll", Backend_poll, 3);
963
931
  rb_define_method(cBackend, "break", Backend_wakeup, 0);
@@ -968,8 +936,8 @@ void Init_Backend() {
968
936
  rb_define_method(cBackend, "recv", Backend_recv, 3);
969
937
  rb_define_method(cBackend, "recv_loop", Backend_recv_loop, 1);
970
938
  rb_define_method(cBackend, "send", Backend_send, 2);
971
- rb_define_method(cBackend, "accept", Backend_accept, 1);
972
- 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);
973
941
  rb_define_method(cBackend, "connect", Backend_connect, 3);
974
942
  rb_define_method(cBackend, "wait_io", Backend_wait_io, 2);
975
943
  rb_define_method(cBackend, "sleep", Backend_sleep, 1);
@@ -981,15 +949,6 @@ void Init_Backend() {
981
949
  rb_define_method(cBackend, "kind", Backend_kind, 0);
982
950
 
983
951
  SYM_io_uring = ID2SYM(rb_intern("io_uring"));
984
-
985
- __BACKEND__.pending_count = Backend_pending_count;
986
- __BACKEND__.poll = Backend_poll;
987
- __BACKEND__.ref = Backend_ref;
988
- __BACKEND__.ref_count = Backend_ref_count;
989
- __BACKEND__.reset_ref_count = Backend_reset_ref_count;
990
- __BACKEND__.unref = Backend_unref;
991
- __BACKEND__.wait_event = Backend_wait_event;
992
- __BACKEND__.wakeup = Backend_wakeup;
993
952
  }
994
953
 
995
954
  #endif // POLYPHONY_BACKEND_LIBURING