polyphony 0.49.2 → 0.53.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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +1 -1
  3. data/CHANGELOG.md +34 -0
  4. data/Gemfile.lock +7 -68
  5. data/TODO.md +37 -3
  6. data/examples/core/forking.rb +2 -2
  7. data/examples/core/nested.rb +21 -0
  8. data/examples/core/suspend.rb +13 -0
  9. data/examples/core/terminate_main_fiber.rb +12 -0
  10. data/examples/io/echo_server.rb +1 -0
  11. data/examples/io/tcp_proxy.rb +2 -2
  12. data/ext/polyphony/backend_common.h +58 -8
  13. data/ext/polyphony/backend_io_uring.c +223 -41
  14. data/ext/polyphony/backend_io_uring_context.c +1 -0
  15. data/ext/polyphony/backend_io_uring_context.h +1 -0
  16. data/ext/polyphony/backend_libev.c +322 -34
  17. data/ext/polyphony/event.c +1 -1
  18. data/ext/polyphony/extconf.rb +9 -2
  19. data/ext/polyphony/fiber.c +2 -1
  20. data/ext/polyphony/polyphony.c +102 -0
  21. data/ext/polyphony/polyphony.h +33 -2
  22. data/ext/polyphony/polyphony_ext.c +3 -0
  23. data/ext/polyphony/queue.c +1 -1
  24. data/ext/polyphony/runqueue.c +7 -1
  25. data/ext/polyphony/runqueue_ring_buffer.c +9 -0
  26. data/ext/polyphony/runqueue_ring_buffer.h +1 -0
  27. data/ext/polyphony/socket_extensions.c +33 -0
  28. data/ext/polyphony/thread.c +14 -0
  29. data/lib/polyphony/adapters/irb.rb +1 -1
  30. data/lib/polyphony/adapters/mysql2.rb +1 -1
  31. data/lib/polyphony/adapters/postgres.rb +5 -5
  32. data/lib/polyphony/adapters/process.rb +4 -4
  33. data/lib/polyphony/core/exceptions.rb +1 -0
  34. data/lib/polyphony/core/global_api.rb +6 -6
  35. data/lib/polyphony/core/sync.rb +1 -1
  36. data/lib/polyphony/core/throttler.rb +1 -1
  37. data/lib/polyphony/core/timer.rb +63 -20
  38. data/lib/polyphony/extensions/core.rb +5 -5
  39. data/lib/polyphony/extensions/fiber.rb +2 -0
  40. data/lib/polyphony/extensions/io.rb +21 -22
  41. data/lib/polyphony/extensions/openssl.rb +6 -6
  42. data/lib/polyphony/extensions/socket.rb +56 -47
  43. data/lib/polyphony/version.rb +1 -1
  44. data/polyphony.gemspec +6 -5
  45. data/test/helper.rb +1 -1
  46. data/test/stress.rb +2 -0
  47. data/test/test_backend.rb +69 -5
  48. data/test/test_fiber.rb +16 -0
  49. data/test/test_global_api.rb +2 -2
  50. data/test/test_io.rb +84 -1
  51. data/test/test_kernel.rb +1 -1
  52. data/test/test_signal.rb +1 -1
  53. data/test/test_socket.rb +61 -0
  54. data/test/test_timer.rb +41 -8
  55. metadata +22 -60
@@ -77,7 +77,7 @@ VALUE Event_await(VALUE self) {
77
77
  }
78
78
 
79
79
  void Init_Event() {
80
- cEvent = rb_define_class_under(mPolyphony, "Event", rb_cData);
80
+ cEvent = rb_define_class_under(mPolyphony, "Event", rb_cObject);
81
81
  rb_define_alloc_func(cEvent, Event_allocate);
82
82
 
83
83
  rb_define_method(cEvent, "initialize", Event_initialize, 0);
@@ -4,18 +4,24 @@ require 'rubygems'
4
4
  require 'mkmf'
5
5
 
6
6
  use_liburing = false
7
+ use_pidfd_open = false
7
8
  force_use_libev = ENV['POLYPHONY_USE_LIBEV'] != nil
9
+ linux = RUBY_PLATFORM =~ /linux/
8
10
 
9
- if !force_use_libev && RUBY_PLATFORM =~ /linux/ && `uname -sr` =~ /Linux 5\.([\d+])/
11
+ if linux && `uname -sr` =~ /Linux 5\.([\d+])/
10
12
  kernel_minor_version = $1.gsub('.', '').to_i
11
- use_liburing = kernel_minor_version >= 6
13
+ use_liburing = !force_use_libev && kernel_minor_version >= 6
14
+ use_pidfd_open = kernel_minor_version >= 3
12
15
  end
13
16
 
17
+ $defs << '-DPOLYPHONY_USE_PIDFD_OPEN' if use_pidfd_open
14
18
  if use_liburing
15
19
  $defs << "-DPOLYPHONY_BACKEND_LIBURING"
20
+ $defs << "-DPOLYPHONY_UNSET_NONBLOCK" if RUBY_VERSION =~ /^3/
16
21
  $CFLAGS << " -Wno-pointer-arith"
17
22
  else
18
23
  $defs << "-DPOLYPHONY_BACKEND_LIBEV"
24
+ $defs << "-DPOLYPHONY_LINUX" if linux
19
25
  $defs << '-DEV_USE_LINUXAIO' if have_header('linux/aio_abi.h')
20
26
  $defs << '-DEV_USE_SELECT' if have_header('sys/select.h')
21
27
  $defs << '-DEV_USE_POLL' if have_type('port_event_t', 'poll.h')
@@ -23,6 +29,7 @@ else
23
29
  $defs << '-DEV_USE_KQUEUE' if have_header('sys/event.h') && have_header('sys/queue.h')
24
30
  $defs << '-DEV_USE_PORT' if have_type('port_event_t', 'port.h')
25
31
  $defs << '-DHAVE_SYS_RESOURCE_H' if have_header('sys/resource.h')
32
+
26
33
  $CFLAGS << " -Wno-comment"
27
34
  $CFLAGS << " -Wno-unused-result"
28
35
  $CFLAGS << " -Wno-dangling-else"
@@ -101,7 +101,8 @@ VALUE Fiber_await(VALUE self) {
101
101
  }
102
102
  rb_hash_aset(waiting_fibers, fiber, Qtrue);
103
103
 
104
- result = Thread_switch_fiber(rb_thread_current());
104
+ VALUE backend = rb_ivar_get(rb_thread_current(), ID_ivar_backend);
105
+ result = Backend_wait_event(backend, Qnil);
105
106
 
106
107
  rb_hash_delete(waiting_fibers, fiber);
107
108
  RAISE_IF_EXCEPTION(result);
@@ -46,11 +46,113 @@ VALUE Polyphony_trace(VALUE self, VALUE enabled) {
46
46
  return Qnil;
47
47
  }
48
48
 
49
+ VALUE Polyphony_backend_accept(VALUE self, VALUE server_socket, VALUE socket_class) {
50
+ return Backend_accept(BACKEND(), server_socket, socket_class);
51
+ }
52
+
53
+ VALUE Polyphony_backend_accept_loop(VALUE self, VALUE server_socket, VALUE socket_class) {
54
+ return Backend_accept_loop(BACKEND(), server_socket, socket_class);
55
+ }
56
+
57
+ VALUE Polyphony_backend_connect(VALUE self, VALUE io, VALUE addr, VALUE port) {
58
+ return Backend_connect(BACKEND(), io, addr, port);
59
+ }
60
+
61
+ VALUE Polyphony_backend_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE method) {
62
+ return Backend_feed_loop(BACKEND(), io, receiver, method);
63
+ }
64
+
65
+ VALUE Polyphony_backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof) {
66
+ return Backend_read(BACKEND(), io, str, length, to_eof);
67
+ }
68
+
69
+ VALUE Polyphony_backend_read_loop(VALUE self, VALUE io) {
70
+ return Backend_read_loop(BACKEND(), io);
71
+ }
72
+
73
+ VALUE Polyphony_backend_recv(VALUE self, VALUE io, VALUE str, VALUE length) {
74
+ return Backend_recv(BACKEND(), io, str, length);
75
+ }
76
+
77
+ VALUE Polyphony_backend_recv_loop(VALUE self, VALUE io) {
78
+ return Backend_recv_loop(BACKEND(), io);
79
+ }
80
+
81
+ VALUE Polyphony_backend_recv_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE method) {
82
+ return Backend_recv_feed_loop(BACKEND(), io, receiver, method);
83
+ }
84
+
85
+ VALUE Polyphony_backend_send(VALUE self, VALUE io, VALUE msg, VALUE flags) {
86
+ return Backend_send(BACKEND(), io, msg, flags);
87
+ }
88
+
89
+ VALUE Polyphony_backend_sendv(VALUE self, VALUE io, VALUE ary, VALUE flags) {
90
+ return Backend_sendv(BACKEND(), io, ary, flags);
91
+ }
92
+
93
+ VALUE Polyphony_backend_sleep(VALUE self, VALUE duration) {
94
+ return Backend_sleep(BACKEND(), duration);
95
+ }
96
+
97
+ VALUE Polyphony_backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
98
+ return Backend_splice(BACKEND(), src, dest, maxlen);
99
+ }
100
+
101
+ VALUE Polyphony_backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE chunksize) {
102
+ return Backend_splice_to_eof(BACKEND(), src, dest, chunksize);
103
+ }
104
+
105
+ VALUE Polyphony_backend_timeout(int argc,VALUE *argv, VALUE self) {
106
+ return Backend_timeout(argc, argv, BACKEND());
107
+ }
108
+
109
+ VALUE Polyphony_backend_timer_loop(VALUE self, VALUE interval) {
110
+ return Backend_timer_loop(BACKEND(), interval);
111
+ }
112
+
113
+ VALUE Polyphony_backend_wait_event(VALUE self, VALUE raise) {
114
+ return Backend_wait_event(BACKEND(), raise);
115
+ }
116
+
117
+ VALUE Polyphony_backend_wait_io(VALUE self, VALUE io, VALUE write) {
118
+ return Backend_wait_io(BACKEND(), io, write);
119
+ }
120
+
121
+ VALUE Polyphony_backend_waitpid(VALUE self, VALUE pid) {
122
+ return Backend_waitpid(BACKEND(), pid);
123
+ }
124
+
125
+ VALUE Polyphony_backend_write(int argc, VALUE *argv, VALUE self) {
126
+ return Backend_write_m(argc, argv, BACKEND());
127
+ }
128
+
49
129
  void Init_Polyphony() {
50
130
  mPolyphony = rb_define_module("Polyphony");
51
131
 
52
132
  rb_define_singleton_method(mPolyphony, "trace", Polyphony_trace, 1);
53
133
 
134
+ // backend methods
135
+ rb_define_singleton_method(mPolyphony, "backend_accept", Polyphony_backend_accept, 2);
136
+ rb_define_singleton_method(mPolyphony, "backend_accept_loop", Polyphony_backend_accept_loop, 2);
137
+ rb_define_singleton_method(mPolyphony, "backend_connect", Polyphony_backend_connect, 3);
138
+ rb_define_singleton_method(mPolyphony, "backend_feed_loop", Polyphony_backend_feed_loop, 3);
139
+ rb_define_singleton_method(mPolyphony, "backend_read", Polyphony_backend_read, 4);
140
+ rb_define_singleton_method(mPolyphony, "backend_read_loop", Polyphony_backend_read_loop, 1);
141
+ rb_define_singleton_method(mPolyphony, "backend_recv", Polyphony_backend_recv, 3);
142
+ rb_define_singleton_method(mPolyphony, "backend_recv_loop", Polyphony_backend_recv_loop, 1);
143
+ rb_define_singleton_method(mPolyphony, "backend_recv_feed_loop", Polyphony_backend_recv_feed_loop, 3);
144
+ rb_define_singleton_method(mPolyphony, "backend_send", Polyphony_backend_send, 3);
145
+ rb_define_singleton_method(mPolyphony, "backend_sendv", Polyphony_backend_sendv, 3);
146
+ rb_define_singleton_method(mPolyphony, "backend_sleep", Polyphony_backend_sleep, 1);
147
+ rb_define_singleton_method(mPolyphony, "backend_splice", Polyphony_backend_splice, 3);
148
+ rb_define_singleton_method(mPolyphony, "backend_splice_to_eof", Polyphony_backend_splice_to_eof, 3);
149
+ rb_define_singleton_method(mPolyphony, "backend_timeout", Polyphony_backend_timeout, -1);
150
+ rb_define_singleton_method(mPolyphony, "backend_timer_loop", Polyphony_backend_timer_loop, 1);
151
+ rb_define_singleton_method(mPolyphony, "backend_wait_event", Polyphony_backend_wait_event, 1);
152
+ rb_define_singleton_method(mPolyphony, "backend_wait_io", Polyphony_backend_wait_io, 2);
153
+ rb_define_singleton_method(mPolyphony, "backend_waitpid", Polyphony_backend_waitpid, 1);
154
+ rb_define_singleton_method(mPolyphony, "backend_write", Polyphony_backend_write, -1);
155
+
54
156
  rb_define_global_function("snooze", Polyphony_snooze, 0);
55
157
  rb_define_global_function("suspend", Polyphony_suspend, 0);
56
158
 
@@ -23,14 +23,16 @@
23
23
  #define COND_TRACE(...) if (__tracing_enabled__) { TRACE(__VA_ARGS__); }
24
24
 
25
25
  // exceptions
26
- #define TEST_EXCEPTION(ret) (RTEST(rb_obj_is_kind_of(ret, rb_eException)))
26
+ #define TEST_EXCEPTION(ret) (rb_obj_is_kind_of(ret, rb_eException) == Qtrue)
27
27
  #define RAISE_EXCEPTION(e) rb_funcall(e, ID_invoke, 0);
28
- #define RAISE_IF_EXCEPTION(ret) if (RTEST(rb_obj_is_kind_of(ret, rb_eException))) { RAISE_EXCEPTION(ret); }
28
+ #define RAISE_IF_EXCEPTION(ret) if (rb_obj_is_kind_of(ret, rb_eException) == Qtrue) { RAISE_EXCEPTION(ret); }
29
29
  #define RAISE_IF_NOT_NIL(ret) if (ret != Qnil) { RAISE_EXCEPTION(ret); }
30
30
 
31
31
  // Fiber#transfer
32
32
  #define FIBER_TRANSFER(fiber, value) rb_funcall(fiber, ID_transfer, 1, value)
33
33
 
34
+ #define BACKEND() (rb_ivar_get(rb_thread_current(), ID_ivar_backend))
35
+
34
36
  extern VALUE mPolyphony;
35
37
  extern VALUE cQueue;
36
38
  extern VALUE cEvent;
@@ -84,10 +86,39 @@ void Runqueue_push(VALUE self, VALUE fiber, VALUE value, int reschedule);
84
86
  void Runqueue_unshift(VALUE self, VALUE fiber, VALUE value, int reschedule);
85
87
  runqueue_entry Runqueue_shift(VALUE self);
86
88
  void Runqueue_delete(VALUE self, VALUE fiber);
89
+ int Runqueue_index_of(VALUE self, VALUE fiber);
87
90
  void Runqueue_clear(VALUE self);
88
91
  long Runqueue_len(VALUE self);
89
92
  int Runqueue_empty_p(VALUE self);
90
93
 
94
+ #ifdef POLYPHONY_BACKEND_LIBEV
95
+ #define Backend_recv_loop Backend_read_loop
96
+ #define Backend_recv_feed_loop Backend_feed_loop
97
+ #endif
98
+
99
+ // Backend public interface
100
+
101
+ VALUE Backend_accept(VALUE self, VALUE server_socket, VALUE socket_class);
102
+ VALUE Backend_accept_loop(VALUE self, VALUE server_socket, VALUE socket_class);
103
+ VALUE Backend_connect(VALUE self, VALUE io, VALUE addr, VALUE port);
104
+ VALUE Backend_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE method);
105
+ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof);
106
+ VALUE Backend_read_loop(VALUE self, VALUE io);
107
+ VALUE Backend_recv(VALUE self, VALUE io, VALUE str, VALUE length);
108
+ VALUE Backend_recv_loop(VALUE self, VALUE io);
109
+ VALUE Backend_recv_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE method);
110
+ VALUE Backend_send(VALUE self, VALUE io, VALUE msg, VALUE flags);
111
+ VALUE Backend_sendv(VALUE self, VALUE io, VALUE ary, VALUE flags);
112
+ VALUE Backend_sleep(VALUE self, VALUE duration);
113
+ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen);
114
+ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE chunksize);
115
+ VALUE Backend_timeout(int argc,VALUE *argv, VALUE self);
116
+ VALUE Backend_timer_loop(VALUE self, VALUE interval);
117
+ VALUE Backend_wait_event(VALUE self, VALUE raise);
118
+ VALUE Backend_wait_io(VALUE self, VALUE io, VALUE write);
119
+ VALUE Backend_waitpid(VALUE self, VALUE pid);
120
+ VALUE Backend_write_m(int argc, VALUE *argv, VALUE self);
121
+
91
122
  unsigned int Backend_pending_count(VALUE self);
92
123
  VALUE Backend_poll(VALUE self, VALUE nowait, VALUE current_fiber, VALUE runqueue);
93
124
  VALUE Backend_wait_event(VALUE self, VALUE raise_on_exception);
@@ -6,6 +6,7 @@ void Init_Backend();
6
6
  void Init_Queue();
7
7
  void Init_Event();
8
8
  void Init_Runqueue();
9
+ void Init_SocketExtensions();
9
10
  void Init_Thread();
10
11
  void Init_Tracing();
11
12
 
@@ -24,6 +25,8 @@ void Init_polyphony_ext() {
24
25
  Init_Thread();
25
26
  Init_Tracing();
26
27
 
28
+ Init_SocketExtensions();
29
+
27
30
  #ifdef POLYPHONY_PLAYGROUND
28
31
  playground();
29
32
  #endif
@@ -247,7 +247,7 @@ VALUE Queue_size_m(VALUE self) {
247
247
  }
248
248
 
249
249
  void Init_Queue() {
250
- cQueue = rb_define_class_under(mPolyphony, "Queue", rb_cData);
250
+ cQueue = rb_define_class_under(mPolyphony, "Queue", rb_cObject);
251
251
  rb_define_alloc_func(cQueue, Queue_allocate);
252
252
 
253
253
  rb_define_method(cQueue, "initialize", Queue_initialize, -1);
@@ -74,6 +74,12 @@ void Runqueue_delete(VALUE self, VALUE fiber) {
74
74
  runqueue_ring_buffer_delete(&runqueue->entries, fiber);
75
75
  }
76
76
 
77
+ int Runqueue_index_of(VALUE self, VALUE fiber) {
78
+ Runqueue_t *runqueue;
79
+ GetRunqueue(self, runqueue);
80
+ return runqueue_ring_buffer_index_of(&runqueue->entries, fiber);
81
+ }
82
+
77
83
  void Runqueue_clear(VALUE self) {
78
84
  Runqueue_t *runqueue;
79
85
  GetRunqueue(self, runqueue);
@@ -95,7 +101,7 @@ int Runqueue_empty_p(VALUE self) {
95
101
  }
96
102
 
97
103
  void Init_Runqueue() {
98
- cRunqueue = rb_define_class_under(mPolyphony, "Runqueue", rb_cData);
104
+ cRunqueue = rb_define_class_under(mPolyphony, "Runqueue", rb_cObject);
99
105
  rb_define_alloc_func(cRunqueue, Runqueue_allocate);
100
106
 
101
107
  rb_define_method(cRunqueue, "initialize", Runqueue_initialize, 0);
@@ -80,6 +80,15 @@ void runqueue_ring_buffer_delete(runqueue_ring_buffer *buffer, VALUE fiber) {
80
80
  }
81
81
  }
82
82
 
83
+ int runqueue_ring_buffer_index_of(runqueue_ring_buffer *buffer, VALUE fiber) {
84
+ for (unsigned int i = 0; i < buffer->count; i++) {
85
+ unsigned int idx = (buffer->head + i) % buffer->size;
86
+ if (buffer->entries[idx].fiber == fiber)
87
+ return i;
88
+ }
89
+ return -1;
90
+ }
91
+
83
92
  void runqueue_ring_buffer_clear(runqueue_ring_buffer *buffer) {
84
93
  buffer->count = buffer->head = buffer->tail = 0;
85
94
  }
@@ -27,5 +27,6 @@ void runqueue_ring_buffer_unshift(runqueue_ring_buffer *buffer, VALUE fiber, VAL
27
27
  void runqueue_ring_buffer_push(runqueue_ring_buffer *buffer, VALUE fiber, VALUE value);
28
28
 
29
29
  void runqueue_ring_buffer_delete(runqueue_ring_buffer *buffer, VALUE fiber);
30
+ int runqueue_ring_buffer_index_of(runqueue_ring_buffer *buffer, VALUE fiber);
30
31
 
31
32
  #endif /* RUNQUEUE_RING_BUFFER_H */
@@ -0,0 +1,33 @@
1
+ #include "polyphony.h"
2
+
3
+ VALUE Socket_send(VALUE self, VALUE msg, VALUE flags) {
4
+ return Backend_send(BACKEND(), self, msg, flags);
5
+ }
6
+
7
+ VALUE Socket_write(int argc, VALUE *argv, VALUE self) {
8
+ VALUE ary = rb_ary_new_from_values(argc, argv);
9
+ VALUE result = Backend_sendv(BACKEND(), self, ary, INT2NUM(0));
10
+ RB_GC_GUARD(ary);
11
+ return result;
12
+ }
13
+
14
+ VALUE Socket_double_chevron(VALUE self, VALUE msg) {
15
+ Backend_send(BACKEND(), self, msg, INT2NUM(0));
16
+ return self;
17
+ }
18
+
19
+ void Init_SocketExtensions() {
20
+ rb_require("socket");
21
+
22
+ VALUE cSocket = rb_const_get(rb_cObject, rb_intern("Socket"));
23
+ VALUE cTCPSocket = rb_const_get(rb_cObject, rb_intern("TCPSocket"));
24
+
25
+ rb_define_method(cSocket, "send", Socket_send, 2);
26
+ rb_define_method(cTCPSocket, "send", Socket_send, 2);
27
+
28
+ rb_define_method(cSocket, "write", Socket_write, -1);
29
+ rb_define_method(cTCPSocket, "write", Socket_write, -1);
30
+
31
+ rb_define_method(cSocket, "<<", Socket_double_chevron, 1);
32
+ rb_define_method(cTCPSocket, "<<", Socket_double_chevron, 1);
33
+ }
@@ -59,6 +59,18 @@ void schedule_fiber(VALUE self, VALUE fiber, VALUE value, int prioritize) {
59
59
  }
60
60
  }
61
61
 
62
+ VALUE Thread_fiber_scheduling_index(VALUE self, VALUE fiber) {
63
+ VALUE runqueue = rb_ivar_get(self, ID_ivar_runqueue);
64
+
65
+ return INT2NUM(Runqueue_index_of(runqueue, fiber));
66
+ }
67
+
68
+ VALUE Thread_fiber_unschedule(VALUE self, VALUE fiber) {
69
+ VALUE runqueue = rb_ivar_get(self, ID_ivar_runqueue);
70
+ Runqueue_delete(runqueue, fiber);
71
+ return self;
72
+ }
73
+
62
74
  VALUE Thread_schedule_fiber(VALUE self, VALUE fiber, VALUE value) {
63
75
  schedule_fiber(self, fiber, value, 0);
64
76
  return self;
@@ -135,6 +147,8 @@ void Init_Thread() {
135
147
  rb_define_method(rb_cThread, "schedule_fiber_with_priority",
136
148
  Thread_schedule_fiber_with_priority, 2);
137
149
  rb_define_method(rb_cThread, "switch_fiber", Thread_switch_fiber, 0);
150
+ rb_define_method(rb_cThread, "fiber_scheduling_index", Thread_fiber_scheduling_index, 1);
151
+ rb_define_method(rb_cThread, "fiber_unschedule", Thread_fiber_unschedule, 1);
138
152
 
139
153
  rb_define_method(rb_cThread, "debug!", Thread_debug, 0);
140
154
 
@@ -16,7 +16,7 @@ if Object.constants.include?(:Reline)
16
16
  fiber.cancel
17
17
  end
18
18
  read_ios.each do |io|
19
- Thread.current.backend.wait_io(io, false)
19
+ Polyphony.backend_wait_io(io, false)
20
20
  return [io]
21
21
  end
22
22
  rescue Polyphony::Cancel
@@ -13,7 +13,7 @@ Mysql2::Client.prepend(Module.new do
13
13
 
14
14
  def query(sql, **options)
15
15
  super
16
- Thread.current.backend.wait_io(@io, false)
16
+ Polyphony.backend_wait_io(@io, false)
17
17
  async_result
18
18
  end
19
19
  end)
@@ -15,8 +15,8 @@ module ::PG
15
15
  res = conn.connect_poll
16
16
  case res
17
17
  when PGRES_POLLING_FAILED then raise Error, conn.error_message
18
- when PGRES_POLLING_READING then Thread.current.backend.wait_io(socket_io, false)
19
- when PGRES_POLLING_WRITING then Thread.current.backend.wait_io(socket_io, true)
18
+ when PGRES_POLLING_READING then Polyphony.backend_wait_io(socket_io, false)
19
+ when PGRES_POLLING_WRITING then Polyphony.backend_wait_io(socket_io, true)
20
20
  when PGRES_POLLING_OK then return conn.setnonblocking(true)
21
21
  end
22
22
  end
@@ -42,7 +42,7 @@ class ::PG::Connection
42
42
 
43
43
  def get_result(&block)
44
44
  while is_busy
45
- Thread.current.backend.wait_io(socket_io, false)
45
+ Polyphony.backend_wait_io(socket_io, false)
46
46
  consume_input
47
47
  end
48
48
  orig_get_result(&block)
@@ -59,7 +59,7 @@ class ::PG::Connection
59
59
 
60
60
  def block(_timeout = 0)
61
61
  while is_busy
62
- Thread.current.backend.wait_io(socket_io, false)
62
+ Polyphony.backend_wait_io(socket_io, false)
63
63
  consume_input
64
64
  end
65
65
  end
@@ -97,7 +97,7 @@ class ::PG::Connection
97
97
  return move_on_after(timeout) { wait_for_notify(&block) } if timeout
98
98
 
99
99
  while true
100
- Thread.current.backend.wait_io(socket_io, false)
100
+ Polyphony.backend_wait_io(socket_io, false)
101
101
  consume_input
102
102
  notice = notifies
103
103
  next unless notice
@@ -7,7 +7,7 @@ module Polyphony
7
7
  def watch(cmd = nil, &block)
8
8
  terminated = nil
9
9
  pid = cmd ? Kernel.spawn(cmd) : Polyphony.fork(&block)
10
- Thread.current.backend.waitpid(pid)
10
+ Polyphony.backend_waitpid(pid)
11
11
  terminated = true
12
12
  ensure
13
13
  kill_process(pid) unless terminated || pid.nil?
@@ -23,9 +23,9 @@ module Polyphony
23
23
 
24
24
  def kill_and_await(sig, pid)
25
25
  ::Process.kill(sig, pid)
26
- Thread.current.backend.waitpid(pid)
27
- rescue Errno::ERSCH
28
- # ignore
26
+ Polyphony.backend_waitpid(pid)
27
+ rescue Errno::ESRCH
28
+ # process doesn't exist
29
29
  end
30
30
  end
31
31
  end