polyphony 0.45.5 → 0.46.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +2 -0
- data/.gitmodules +0 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +1 -1
- data/README.md +3 -3
- data/Rakefile +1 -1
- data/TODO.md +4 -4
- data/examples/performance/thread-vs-fiber/polyphony_server.rb +1 -2
- data/ext/liburing/liburing.h +585 -0
- data/ext/liburing/liburing/README.md +4 -0
- data/ext/liburing/liburing/barrier.h +73 -0
- data/ext/liburing/liburing/compat.h +15 -0
- data/ext/liburing/liburing/io_uring.h +343 -0
- data/ext/liburing/queue.c +333 -0
- data/ext/liburing/register.c +187 -0
- data/ext/liburing/setup.c +210 -0
- data/ext/liburing/syscall.c +54 -0
- data/ext/liburing/syscall.h +18 -0
- data/ext/polyphony/backend.h +0 -14
- data/ext/polyphony/backend_common.h +109 -0
- data/ext/polyphony/backend_io_uring.c +884 -0
- data/ext/polyphony/backend_io_uring_context.c +73 -0
- data/ext/polyphony/backend_io_uring_context.h +52 -0
- data/ext/polyphony/{libev_backend.c → backend_libev.c} +202 -294
- data/ext/polyphony/event.c +1 -1
- data/ext/polyphony/extconf.rb +31 -13
- data/ext/polyphony/fiber.c +29 -22
- data/ext/polyphony/libev.c +4 -0
- data/ext/polyphony/libev.h +8 -2
- data/ext/polyphony/liburing.c +8 -0
- data/ext/polyphony/playground.c +51 -0
- data/ext/polyphony/polyphony.c +5 -5
- data/ext/polyphony/polyphony.h +16 -12
- data/ext/polyphony/polyphony_ext.c +10 -4
- data/ext/polyphony/queue.c +1 -1
- data/ext/polyphony/thread.c +11 -9
- data/lib/polyphony/adapters/trace.rb +2 -2
- data/lib/polyphony/core/global_api.rb +1 -4
- data/lib/polyphony/extensions/debug.rb +13 -0
- data/lib/polyphony/extensions/fiber.rb +2 -2
- data/lib/polyphony/extensions/socket.rb +59 -10
- data/lib/polyphony/version.rb +1 -1
- data/test/helper.rb +36 -4
- data/test/io_uring_test.rb +55 -0
- data/test/stress.rb +5 -2
- data/test/test_backend.rb +4 -6
- data/test/test_ext.rb +1 -2
- data/test/test_fiber.rb +22 -16
- data/test/test_global_api.rb +33 -35
- data/test/test_throttler.rb +3 -6
- data/test/test_trace.rb +7 -5
- metadata +22 -3
data/ext/polyphony/event.c
CHANGED
@@ -69,7 +69,7 @@ VALUE Event_await(VALUE self) {
|
|
69
69
|
VALUE switchpoint_result = __BACKEND__.wait_event(backend, Qnil);
|
70
70
|
event->waiting_fiber = Qnil;
|
71
71
|
|
72
|
-
|
72
|
+
RAISE_IF_EXCEPTION(switchpoint_result);
|
73
73
|
RB_GC_GUARD(backend);
|
74
74
|
RB_GC_GUARD(switchpoint_result);
|
75
75
|
|
data/ext/polyphony/extconf.rb
CHANGED
@@ -1,20 +1,38 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'rubygems'
|
4
|
+
require 'mkmf'
|
4
5
|
|
5
|
-
|
6
|
+
use_liburing = false
|
7
|
+
force_use_libev = ENV['POLYPHONY_USE_LIBEV'] != nil
|
6
8
|
|
7
|
-
|
9
|
+
if !force_use_libev && RUBY_PLATFORM =~ /linux/ && `uname -sr` =~ /Linux 5\.([\d+])/
|
10
|
+
kernel_minor_version = $1.gsub('.', '').to_i
|
11
|
+
use_liburing = kernel_minor_version >= 6
|
12
|
+
end
|
8
13
|
|
9
|
-
|
10
|
-
$defs << "-
|
11
|
-
$
|
12
|
-
|
13
|
-
$defs << "-
|
14
|
-
$defs <<
|
15
|
-
$defs <<
|
14
|
+
if use_liburing
|
15
|
+
$defs << "-DPOLYPHONY_BACKEND_LIBURING"
|
16
|
+
$CFLAGS << " -Wno-pointer-arith"
|
17
|
+
else
|
18
|
+
$defs << "-DPOLYPHONY_BACKEND_LIBEV"
|
19
|
+
$defs << '-DEV_USE_LINUXAIO' if have_header('linux/aio_abi.h')
|
20
|
+
$defs << '-DEV_USE_SELECT' if have_header('sys/select.h')
|
21
|
+
$defs << '-DEV_USE_POLL' if have_type('port_event_t', 'poll.h')
|
22
|
+
$defs << '-DEV_USE_EPOLL' if have_header('sys/epoll.h')
|
23
|
+
$defs << '-DEV_USE_KQUEUE' if have_header('sys/event.h') && have_header('sys/queue.h')
|
24
|
+
$defs << '-DEV_USE_PORT' if have_type('port_event_t', 'port.h')
|
25
|
+
$defs << '-DHAVE_SYS_RESOURCE_H' if have_header('sys/resource.h')
|
26
|
+
$CFLAGS << " -Wno-comment"
|
27
|
+
$CFLAGS << " -Wno-unused-result"
|
28
|
+
$CFLAGS << " -Wno-dangling-else"
|
29
|
+
$CFLAGS << " -Wno-parentheses"
|
30
|
+
end
|
16
31
|
|
17
|
-
|
32
|
+
$defs << '-DPOLYPHONY_PLAYGROUND' if ENV['POLYPHONY_PLAYGROUND']
|
18
33
|
|
19
|
-
|
20
|
-
|
34
|
+
CONFIG['optflags'] << ' -fno-strict-aliasing' unless RUBY_PLATFORM =~ /mswin/
|
35
|
+
|
36
|
+
|
37
|
+
dir_config 'polyphony_ext'
|
38
|
+
create_makefile 'polyphony_ext'
|
data/ext/polyphony/fiber.c
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
ID ID_fiber_trace;
|
4
4
|
ID ID_ivar_auto_watcher;
|
5
5
|
ID ID_ivar_mailbox;
|
6
|
+
ID ID_ivar_result;
|
6
7
|
ID ID_ivar_waiting_fibers;
|
7
8
|
|
8
9
|
VALUE SYM_dead;
|
@@ -11,8 +12,8 @@ VALUE SYM_runnable;
|
|
11
12
|
VALUE SYM_waiting;
|
12
13
|
|
13
14
|
VALUE SYM_fiber_create;
|
14
|
-
VALUE
|
15
|
-
VALUE
|
15
|
+
VALUE SYM_fiber_event_poll_enter;
|
16
|
+
VALUE SYM_fiber_event_poll_leave;
|
16
17
|
VALUE SYM_fiber_run;
|
17
18
|
VALUE SYM_fiber_schedule;
|
18
19
|
VALUE SYM_fiber_switchpoint;
|
@@ -22,7 +23,7 @@ static VALUE Fiber_safe_transfer(int argc, VALUE *argv, VALUE self) {
|
|
22
23
|
VALUE arg = (argc == 0) ? Qnil : argv[0];
|
23
24
|
VALUE ret = rb_funcall(self, ID_transfer, 1, arg);
|
24
25
|
|
25
|
-
|
26
|
+
RAISE_IF_EXCEPTION(ret);
|
26
27
|
RB_GC_GUARD(ret);
|
27
28
|
return ret;
|
28
29
|
}
|
@@ -41,8 +42,12 @@ inline VALUE Fiber_auto_watcher(VALUE self) {
|
|
41
42
|
void Fiber_make_runnable(VALUE fiber, VALUE value) {
|
42
43
|
VALUE thread = rb_ivar_get(fiber, ID_ivar_thread);
|
43
44
|
if (thread == Qnil) {
|
44
|
-
|
45
|
-
|
45
|
+
INSPECT("Fiber with no thread", fiber);
|
46
|
+
TRACE_CALLER();
|
47
|
+
TRACE_C_STACK();
|
48
|
+
exit(-1);
|
49
|
+
rb_raise(rb_eRuntimeError, "No thread set for fiber");
|
50
|
+
// rb_warn("No thread set for fiber");
|
46
51
|
return;
|
47
52
|
}
|
48
53
|
|
@@ -52,8 +57,9 @@ void Fiber_make_runnable(VALUE fiber, VALUE value) {
|
|
52
57
|
void Fiber_make_runnable_with_priority(VALUE fiber, VALUE value) {
|
53
58
|
VALUE thread = rb_ivar_get(fiber, ID_ivar_thread);
|
54
59
|
if (thread == Qnil) {
|
55
|
-
|
56
|
-
|
60
|
+
INSPECT("Fiber with no thread", fiber);
|
61
|
+
rb_raise(rb_eRuntimeError, "No thread set for fiber");
|
62
|
+
// rb_warn("No thread set for fiber");
|
57
63
|
return;
|
58
64
|
}
|
59
65
|
|
@@ -88,7 +94,7 @@ VALUE Fiber_await(VALUE self) {
|
|
88
94
|
// @running set to nil
|
89
95
|
if (rb_ivar_get(self, ID_ivar_running) == Qfalse) {
|
90
96
|
result = rb_ivar_get(self, ID_ivar_result);
|
91
|
-
|
97
|
+
RAISE_IF_EXCEPTION(result);
|
92
98
|
return result;
|
93
99
|
}
|
94
100
|
|
@@ -103,7 +109,7 @@ VALUE Fiber_await(VALUE self) {
|
|
103
109
|
result = Thread_switch_fiber(rb_thread_current());
|
104
110
|
|
105
111
|
rb_hash_delete(waiting_fibers, fiber);
|
106
|
-
|
112
|
+
RAISE_IF_EXCEPTION(result);
|
107
113
|
RB_GC_GUARD(result);
|
108
114
|
return result;
|
109
115
|
}
|
@@ -158,22 +164,23 @@ void Init_Fiber() {
|
|
158
164
|
rb_global_variable(&SYM_runnable);
|
159
165
|
rb_global_variable(&SYM_waiting);
|
160
166
|
|
161
|
-
ID_fiber_trace
|
162
|
-
ID_ivar_auto_watcher
|
163
|
-
ID_ivar_mailbox
|
164
|
-
|
167
|
+
ID_fiber_trace = rb_intern("__fiber_trace__");
|
168
|
+
ID_ivar_auto_watcher = rb_intern("@auto_watcher");
|
169
|
+
ID_ivar_mailbox = rb_intern("@mailbox");
|
170
|
+
ID_ivar_result = rb_intern("@result");
|
171
|
+
ID_ivar_waiting_fibers = rb_intern("@waiting_fibers");
|
165
172
|
|
166
|
-
SYM_fiber_create
|
167
|
-
|
168
|
-
|
169
|
-
SYM_fiber_run
|
170
|
-
SYM_fiber_schedule
|
171
|
-
SYM_fiber_switchpoint
|
172
|
-
SYM_fiber_terminate
|
173
|
+
SYM_fiber_create = ID2SYM(rb_intern("fiber_create"));
|
174
|
+
SYM_fiber_event_poll_enter = ID2SYM(rb_intern("fiber_event_poll_enter"));
|
175
|
+
SYM_fiber_event_poll_leave = ID2SYM(rb_intern("fiber_event_poll_leave"));
|
176
|
+
SYM_fiber_run = ID2SYM(rb_intern("fiber_run"));
|
177
|
+
SYM_fiber_schedule = ID2SYM(rb_intern("fiber_schedule"));
|
178
|
+
SYM_fiber_switchpoint = ID2SYM(rb_intern("fiber_switchpoint"));
|
179
|
+
SYM_fiber_terminate = ID2SYM(rb_intern("fiber_terminate"));
|
173
180
|
|
174
181
|
rb_global_variable(&SYM_fiber_create);
|
175
|
-
rb_global_variable(&
|
176
|
-
rb_global_variable(&
|
182
|
+
rb_global_variable(&SYM_fiber_event_poll_enter);
|
183
|
+
rb_global_variable(&SYM_fiber_event_poll_leave);
|
177
184
|
rb_global_variable(&SYM_fiber_run);
|
178
185
|
rb_global_variable(&SYM_fiber_schedule);
|
179
186
|
rb_global_variable(&SYM_fiber_switchpoint);
|
data/ext/polyphony/libev.c
CHANGED
data/ext/polyphony/libev.h
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
#define EV_STANDALONE
|
1
|
+
#define EV_STANDALONE
|
2
|
+
|
3
|
+
#ifdef POLYPHONY_BACKEND_LIBEV
|
4
|
+
|
5
|
+
/* keeps ev from requiring config.h */
|
2
6
|
|
3
7
|
#ifdef _WIN32
|
4
8
|
#define EV_SELECT_IS_WINSOCKET 1
|
@@ -6,4 +10,6 @@
|
|
6
10
|
#define EV_USE_REALTIME 0
|
7
11
|
#endif
|
8
12
|
|
9
|
-
#include "../libev/ev.h"
|
13
|
+
#include "../libev/ev.h"
|
14
|
+
|
15
|
+
#endif // POLYPHONY_BACKEND_LIBEV
|
@@ -0,0 +1,51 @@
|
|
1
|
+
#ifdef POLYPHONY_PLAYGROUND
|
2
|
+
|
3
|
+
#include <netdb.h>
|
4
|
+
#include <sys/socket.h>
|
5
|
+
#include <sys/uio.h>
|
6
|
+
#include <unistd.h>
|
7
|
+
#include <fcntl.h>
|
8
|
+
#include <netinet/in.h>
|
9
|
+
#include <arpa/inet.h>
|
10
|
+
|
11
|
+
#include "polyphony.h"
|
12
|
+
#include "../liburing/liburing.h"
|
13
|
+
#include "ruby/thread.h"
|
14
|
+
|
15
|
+
#include <poll.h>
|
16
|
+
#include <sys/types.h>
|
17
|
+
#include <sys/eventfd.h>
|
18
|
+
#include <sys/wait.h>
|
19
|
+
#include <time.h>
|
20
|
+
#include <stdnoreturn.h>
|
21
|
+
|
22
|
+
void print(struct io_uring *ring, const char *str) {
|
23
|
+
struct io_uring_sqe *sqe = io_uring_get_sqe(ring);
|
24
|
+
io_uring_prep_write(sqe, 1, str, strlen(str), -1);
|
25
|
+
io_uring_sqe_set_data(sqe, (void *)42);
|
26
|
+
// io_uring_sqe_set_flags(sqe, IOSQE_ASYNC);
|
27
|
+
io_uring_submit(ring);
|
28
|
+
|
29
|
+
struct io_uring_cqe *cqe;
|
30
|
+
int ret = __io_uring_get_cqe(ring, &cqe, 0, 1, NULL);
|
31
|
+
if (ret != 0) {
|
32
|
+
printf("ret: %d\n", ret);
|
33
|
+
exit(1);
|
34
|
+
}
|
35
|
+
printf(" cqe res: %d\n", cqe->res);
|
36
|
+
io_uring_cqe_seen(ring, cqe);
|
37
|
+
}
|
38
|
+
|
39
|
+
noreturn void playground() {
|
40
|
+
struct io_uring ring;
|
41
|
+
io_uring_queue_init(1024, &ring, 0);
|
42
|
+
|
43
|
+
for (int i = 0; i < 10; i++) {
|
44
|
+
print(&ring, "hi\n");
|
45
|
+
}
|
46
|
+
|
47
|
+
io_uring_queue_exit(&ring);
|
48
|
+
exit(0);
|
49
|
+
}
|
50
|
+
|
51
|
+
#endif //POLYPHONY_PLAYGROUND
|
data/ext/polyphony/polyphony.c
CHANGED
@@ -9,7 +9,7 @@ ID ID_each;
|
|
9
9
|
ID ID_inspect;
|
10
10
|
ID ID_invoke;
|
11
11
|
ID ID_new;
|
12
|
-
ID
|
12
|
+
ID ID_ivar_io;
|
13
13
|
ID ID_ivar_runnable;
|
14
14
|
ID ID_ivar_running;
|
15
15
|
ID ID_ivar_thread;
|
@@ -29,7 +29,7 @@ VALUE Polyphony_snooze(VALUE self) {
|
|
29
29
|
|
30
30
|
Fiber_make_runnable(fiber, Qnil);
|
31
31
|
ret = Thread_switch_fiber(rb_thread_current());
|
32
|
-
|
32
|
+
RAISE_IF_EXCEPTION(ret);
|
33
33
|
RB_GC_GUARD(ret);
|
34
34
|
return ret;
|
35
35
|
}
|
@@ -37,7 +37,7 @@ VALUE Polyphony_snooze(VALUE self) {
|
|
37
37
|
static VALUE Polyphony_suspend(VALUE self) {
|
38
38
|
VALUE ret = Thread_switch_fiber(rb_thread_current());
|
39
39
|
|
40
|
-
|
40
|
+
RAISE_IF_EXCEPTION(ret);
|
41
41
|
RB_GC_GUARD(ret);
|
42
42
|
return ret;
|
43
43
|
}
|
@@ -61,8 +61,8 @@ void Init_Polyphony() {
|
|
61
61
|
ID_each = rb_intern("each");
|
62
62
|
ID_inspect = rb_intern("inspect");
|
63
63
|
ID_invoke = rb_intern("invoke");
|
64
|
-
|
65
|
-
ID_ivar_runnable = rb_intern("runnable");
|
64
|
+
ID_ivar_io = rb_intern("@io");
|
65
|
+
ID_ivar_runnable = rb_intern("@runnable");
|
66
66
|
ID_ivar_running = rb_intern("@running");
|
67
67
|
ID_ivar_thread = rb_intern("@thread");
|
68
68
|
ID_new = rb_intern("new");
|
data/ext/polyphony/polyphony.h
CHANGED
@@ -1,29 +1,33 @@
|
|
1
1
|
#ifndef POLYPHONY_H
|
2
2
|
#define POLYPHONY_H
|
3
3
|
|
4
|
+
#include <execinfo.h>
|
5
|
+
|
4
6
|
#include "ruby.h"
|
5
|
-
#include "ruby/io.h"
|
6
|
-
#include "libev.h"
|
7
7
|
#include "backend.h"
|
8
8
|
#include "runqueue_ring_buffer.h"
|
9
9
|
|
10
10
|
// debugging
|
11
11
|
#define OBJ_ID(obj) (NUM2LONG(rb_funcall(obj, rb_intern("object_id"), 0)))
|
12
|
-
#define INSPECT(str, obj) { printf(str); VALUE s = rb_funcall(obj, rb_intern("inspect"), 0); printf("%s\n", StringValueCStr(s)); }
|
12
|
+
#define INSPECT(str, obj) { printf(str); VALUE s = rb_funcall(obj, rb_intern("inspect"), 0); printf(": %s\n", StringValueCStr(s)); }
|
13
13
|
#define TRACE_CALLER() { VALUE c = rb_funcall(rb_mKernel, rb_intern("caller"), 0); INSPECT("caller: ", c); }
|
14
|
+
#define TRACE_C_STACK() { \
|
15
|
+
void *entries[10]; \
|
16
|
+
size_t size = backtrace(entries, 10); \
|
17
|
+
char **strings = backtrace_symbols(entries, size); \
|
18
|
+
for (unsigned long i = 0; i < size; i++) printf("%s\n", strings[i]); \
|
19
|
+
free(strings); \
|
20
|
+
}
|
14
21
|
|
15
22
|
// tracing
|
16
23
|
#define TRACE(...) rb_funcall(rb_cObject, ID_fiber_trace, __VA_ARGS__)
|
17
|
-
#define COND_TRACE(...) if (__tracing_enabled__) {
|
18
|
-
TRACE(__VA_ARGS__); \
|
19
|
-
}
|
24
|
+
#define COND_TRACE(...) if (__tracing_enabled__) { TRACE(__VA_ARGS__); }
|
20
25
|
|
21
26
|
#define TEST_EXCEPTION(ret) (RTEST(rb_obj_is_kind_of(ret, rb_eException)))
|
22
27
|
|
23
28
|
#define RAISE_EXCEPTION(e) rb_funcall(e, ID_invoke, 0);
|
24
|
-
#define
|
25
|
-
|
26
|
-
}
|
29
|
+
#define RAISE_IF_EXCEPTION(ret) if (RTEST(rb_obj_is_kind_of(ret, rb_eException))) { RAISE_EXCEPTION(ret); }
|
30
|
+
#define RAISE_IF_NOT_NIL(ret) if (ret != Qnil) { RAISE_EXCEPTION(ret); }
|
27
31
|
|
28
32
|
extern backend_interface_t backend_interface;
|
29
33
|
#define __BACKEND__ (backend_interface)
|
@@ -41,7 +45,7 @@ extern ID ID_fiber_trace;
|
|
41
45
|
extern ID ID_inspect;
|
42
46
|
extern ID ID_invoke;
|
43
47
|
extern ID ID_ivar_backend;
|
44
|
-
extern ID
|
48
|
+
extern ID ID_ivar_io;
|
45
49
|
extern ID ID_ivar_runnable;
|
46
50
|
extern ID ID_ivar_running;
|
47
51
|
extern ID ID_ivar_thread;
|
@@ -53,8 +57,8 @@ extern ID ID_switch_fiber;
|
|
53
57
|
extern ID ID_transfer;
|
54
58
|
|
55
59
|
extern VALUE SYM_fiber_create;
|
56
|
-
extern VALUE
|
57
|
-
extern VALUE
|
60
|
+
extern VALUE SYM_fiber_event_poll_enter;
|
61
|
+
extern VALUE SYM_fiber_event_poll_leave;
|
58
62
|
extern VALUE SYM_fiber_run;
|
59
63
|
extern VALUE SYM_fiber_schedule;
|
60
64
|
extern VALUE SYM_fiber_switchpoint;
|
@@ -2,23 +2,29 @@
|
|
2
2
|
|
3
3
|
void Init_Fiber();
|
4
4
|
void Init_Polyphony();
|
5
|
-
void
|
5
|
+
void Init_Backend();
|
6
6
|
void Init_Queue();
|
7
7
|
void Init_Event();
|
8
8
|
void Init_Runqueue();
|
9
9
|
void Init_Thread();
|
10
10
|
void Init_Tracing();
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
#ifdef POLYPHONY_PLAYGROUND
|
13
|
+
extern void playground();
|
14
|
+
#endif
|
14
15
|
|
16
|
+
void Init_polyphony_ext() {
|
15
17
|
Init_Polyphony();
|
16
18
|
|
17
|
-
|
19
|
+
Init_Backend();
|
18
20
|
Init_Queue();
|
19
21
|
Init_Event();
|
20
22
|
Init_Runqueue();
|
21
23
|
Init_Fiber();
|
22
24
|
Init_Thread();
|
23
25
|
Init_Tracing();
|
26
|
+
|
27
|
+
#ifdef POLYPHONY_PLAYGROUND
|
28
|
+
playground();
|
29
|
+
#endif
|
24
30
|
}
|
data/ext/polyphony/queue.c
CHANGED
@@ -89,7 +89,7 @@ VALUE Queue_shift(VALUE self) {
|
|
89
89
|
VALUE switchpoint_result = __BACKEND__.wait_event(backend, Qnil);
|
90
90
|
ring_buffer_delete(&queue->shift_queue, fiber);
|
91
91
|
|
92
|
-
|
92
|
+
RAISE_IF_EXCEPTION(switchpoint_result);
|
93
93
|
RB_GC_GUARD(switchpoint_result);
|
94
94
|
|
95
95
|
if (queue->values.count > 0)
|
data/ext/polyphony/thread.c
CHANGED
@@ -4,6 +4,7 @@ ID ID_deactivate_all_watchers_post_fork;
|
|
4
4
|
ID ID_ivar_backend;
|
5
5
|
ID ID_ivar_join_wait_queue;
|
6
6
|
ID ID_ivar_main_fiber;
|
7
|
+
ID ID_ivar_result;
|
7
8
|
ID ID_ivar_terminated;
|
8
9
|
ID ID_ivar_runqueue;
|
9
10
|
ID ID_stop;
|
@@ -125,7 +126,7 @@ VALUE Thread_reset_fiber_scheduling(VALUE self) {
|
|
125
126
|
return self;
|
126
127
|
}
|
127
128
|
|
128
|
-
VALUE
|
129
|
+
VALUE Thread_fiber_schedule_and_wakeup(VALUE self, VALUE fiber, VALUE resume_obj) {
|
129
130
|
VALUE backend = rb_ivar_get(self, ID_ivar_backend);
|
130
131
|
if (fiber != Qnil) {
|
131
132
|
Thread_schedule_fiber_with_priority(self, fiber, resume_obj);
|
@@ -148,7 +149,7 @@ void Init_Thread() {
|
|
148
149
|
rb_define_method(rb_cThread, "setup_fiber_scheduling", Thread_setup_fiber_scheduling, 0);
|
149
150
|
rb_define_method(rb_cThread, "reset_fiber_scheduling", Thread_reset_fiber_scheduling, 0);
|
150
151
|
rb_define_method(rb_cThread, "fiber_scheduling_stats", Thread_fiber_scheduling_stats, 0);
|
151
|
-
rb_define_method(rb_cThread, "
|
152
|
+
rb_define_method(rb_cThread, "schedule_and_wakeup", Thread_fiber_schedule_and_wakeup, 2);
|
152
153
|
|
153
154
|
rb_define_method(rb_cThread, "schedule_fiber", Thread_schedule_fiber, 2);
|
154
155
|
rb_define_method(rb_cThread, "schedule_fiber_with_priority",
|
@@ -157,13 +158,14 @@ void Init_Thread() {
|
|
157
158
|
|
158
159
|
rb_define_method(rb_cThread, "debug!", Thread_debug, 0);
|
159
160
|
|
160
|
-
ID_deactivate_all_watchers_post_fork
|
161
|
-
ID_ivar_backend
|
162
|
-
ID_ivar_join_wait_queue
|
163
|
-
ID_ivar_main_fiber
|
164
|
-
|
165
|
-
ID_ivar_terminated
|
166
|
-
|
161
|
+
ID_deactivate_all_watchers_post_fork = rb_intern("deactivate_all_watchers_post_fork");
|
162
|
+
ID_ivar_backend = rb_intern("@backend");
|
163
|
+
ID_ivar_join_wait_queue = rb_intern("@join_wait_queue");
|
164
|
+
ID_ivar_main_fiber = rb_intern("@main_fiber");
|
165
|
+
ID_ivar_result = rb_intern("@result");
|
166
|
+
ID_ivar_terminated = rb_intern("@terminated");
|
167
|
+
ID_ivar_runqueue = rb_intern("@runqueue");
|
168
|
+
ID_stop = rb_intern("stop");
|
167
169
|
|
168
170
|
SYM_scheduled_fibers = ID2SYM(rb_intern("scheduled_fibers"));
|
169
171
|
SYM_pending_watchers = ID2SYM(rb_intern("pending_watchers"));
|