-
-
Notifications
You must be signed in to change notification settings - Fork 937
Expand file tree
/
Copy pathFiberScheduler.java
More file actions
214 lines (163 loc) · 9.6 KB
/
FiberScheduler.java
File metadata and controls
214 lines (163 loc) · 9.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
package org.jruby;
import jnr.constants.platform.Errno;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.io.OpenFile;
import java.nio.ByteBuffer;
import static org.jruby.api.Convert.asFixnum;
import static org.jruby.api.Convert.toInt;
import static org.jruby.api.Error.argumentError;
public class FiberScheduler {
// MRI: rb_fiber_scheduler_kernel_sleep
public static IRubyObject kernelSleep(ThreadContext context, IRubyObject scheduler, IRubyObject timeout) {
return scheduler.callMethod(context, "kernel_sleep", timeout);
}
// MRI: rb_fiber_scheduler_kernel_sleepv
public static IRubyObject kernelSleep(ThreadContext context, IRubyObject scheduler, IRubyObject[] args) {
return scheduler.callMethod(context, "kernel_sleep", args);
}
// MRI: rb_fiber_scheduler_process_wait
public static IRubyObject processWait(ThreadContext context, IRubyObject scheduler, long pid, int flags) {
return Helpers.invokeChecked(context, scheduler, "process_wait", asFixnum(context, pid), asFixnum(context, flags));
}
// MRI: rb_fiber_scheduler_block
public static IRubyObject block(ThreadContext context, IRubyObject scheduler, IRubyObject blocker, IRubyObject timeout) {
return Helpers.invoke(context, scheduler, "block", blocker, timeout);
}
// MRI: rb_fiber_scheduler_unblock
public static IRubyObject unblock(ThreadContext context, IRubyObject scheduler, IRubyObject blocker, IRubyObject fiber) {
return Helpers.invoke(context, scheduler, "unblock", blocker, fiber);
}
// MRI: rb_fiber_scheduler_io_wait
public static IRubyObject ioWait(ThreadContext context, IRubyObject scheduler, IRubyObject io, IRubyObject events, IRubyObject timeout) {
return Helpers.invoke(context, scheduler, "io_wait", io, events, timeout);
}
// MRI: rb_fiber_scheduler_io_wait_readable
public static IRubyObject ioWaitReadable(ThreadContext context, IRubyObject scheduler, IRubyObject io) {
return ioWait(context, scheduler, io, asFixnum(context, OpenFile.READABLE), context.nil);
}
// MRI: rb_fiber_scheduler_io_wait_writable
public static IRubyObject ioWaitWritable(ThreadContext context, IRubyObject scheduler, IRubyObject io) {
return ioWait(context, scheduler, io, asFixnum(context, OpenFile.WRITABLE), context.nil);
}
// MRI: rb_fiber_scheduler_io_select
public static IRubyObject ioSelect(ThreadContext context, IRubyObject scheduler, IRubyObject readables, IRubyObject writables, IRubyObject exceptables, IRubyObject timeout) {
return ioSelectv(context, scheduler, readables, writables, exceptables, timeout);
}
// MRI: rb_fiber_scheduler_io_selectv
public static IRubyObject ioSelectv(ThreadContext context, IRubyObject scheduler, IRubyObject... args) {
return Helpers.invokeChecked(context, scheduler, "io_select", args);
}
// MRI: rb_fiber_scheduler_io_read
public static IRubyObject ioRead(ThreadContext context, IRubyObject scheduler, IRubyObject io, IRubyObject buffer, int length, int offset) {
Ruby runtime = context.runtime;
return Helpers.invokeChecked(context, scheduler, "io_read", io, buffer, asFixnum(context, length), asFixnum(context, offset));
}
public static IRubyObject ioRead(ThreadContext context, IRubyObject scheduler, IRubyObject io, IRubyObject buffer, RubyInteger length, RubyInteger offset) {
return Helpers.invokeChecked(context, scheduler, "io_read", io, buffer, length, offset);
}
// MRI: rb_fiber_scheduler_io_pread
public static IRubyObject ioPRead(ThreadContext context, IRubyObject scheduler, IRubyObject io, IRubyObject buffer, int from, int length, int offset) {
return Helpers.invokeChecked(context, scheduler, "io_pread", io, buffer, asFixnum(context, from), asFixnum(context, length), asFixnum(context, offset));
}
public static IRubyObject ioPRead(ThreadContext context, IRubyObject scheduler, IRubyObject io, IRubyObject buffer, RubyInteger from, RubyInteger length, RubyInteger offset) {
return Helpers.invokeChecked(context, scheduler, "io_pread", io, buffer, from, length, offset);
}
// MRI: rb_fiber_scheduler_io_write
public static IRubyObject ioWrite(ThreadContext context, IRubyObject scheduler, IRubyObject io, IRubyObject buffer, int length, int offset) {
return Helpers.invokeChecked(context, scheduler, "io_write", io, buffer, asFixnum(context, length), asFixnum(context, offset));
}
public static IRubyObject ioWrite(ThreadContext context, IRubyObject scheduler, IRubyObject io, IRubyObject buffer, RubyInteger length, RubyInteger offset) {
return Helpers.invokeChecked(context, scheduler, "io_write", io, buffer, length, offset);
}
// MRI: rb_fiber_scheduler_io_pwrite
public static IRubyObject ioPWrite(ThreadContext context, IRubyObject scheduler, IRubyObject io, IRubyObject buffer, int from, int length, int offset) {
return Helpers.invokeChecked(context, scheduler, "io_pwrite", io, buffer, asFixnum(context, from), asFixnum(context, length), asFixnum(context, offset));
}
public static IRubyObject ioPWrite(ThreadContext context, IRubyObject scheduler, IRubyObject io, IRubyObject buffer, RubyInteger from, RubyInteger length, RubyInteger offset) {
return Helpers.invokeChecked(context, scheduler, "io_pwrite", io, buffer, from, length, offset);
}
// MRI: rb_fiber_scheduler_io_read_memory
public static IRubyObject ioReadMemory(ThreadContext context, IRubyObject scheduler, IRubyObject io, ByteBuffer base, int size, int length) {
RubyIOBuffer buffer = RubyIOBuffer.newBuffer(context, base, size, RubyIOBuffer.LOCKED);
IRubyObject result = ioRead(context, scheduler, io, buffer, length, 0);
buffer.unlock(context);
buffer.free(context);
return result;
}
// MRI: rb_fiber_scheduler_io_pread_memory
public static IRubyObject ioPReadMemory(ThreadContext context, IRubyObject scheduler, IRubyObject io, ByteBuffer base, int from, int size, int length) {
RubyIOBuffer buffer = RubyIOBuffer.newBuffer(context, base, size, RubyIOBuffer.LOCKED);
IRubyObject result = ioPRead(context, scheduler, io, buffer, from, length, 0);
buffer.unlock(context);
buffer.free(context);
return result;
}
// MRI: rb_fiber_scheduler_io_write_memory
public static IRubyObject ioWriteMemory(ThreadContext context, IRubyObject scheduler, IRubyObject io, ByteBuffer base, int size, int length) {
RubyIOBuffer buffer = RubyIOBuffer.newBuffer(context, base, size, RubyIOBuffer.LOCKED | RubyIOBuffer.READONLY);
IRubyObject result = ioWrite(context, scheduler, io, buffer, length, 0);
buffer.unlock(context);
buffer.free(context);
return result;
}
// MRI: p
public static IRubyObject ioPWriteMemory(ThreadContext context, IRubyObject scheduler, IRubyObject io, ByteBuffer base, int from, int size, int length) {
RubyIOBuffer buffer = RubyIOBuffer.newBuffer(context, base, size, RubyIOBuffer.LOCKED | RubyIOBuffer.READONLY);
IRubyObject result = ioPWrite(context, scheduler, io, buffer, from, length, 0);
buffer.unlock(context);
buffer.free(context);
return result;
}
// MRI: rb_fiber_scheduler_io_close
public static IRubyObject ioClose(ThreadContext context, IRubyObject scheduler, IRubyObject io) {
return Helpers.invokeChecked(context, scheduler, "io_close", io);
}
// MRI: rb_fiber_scheduler_address_resolve
public static IRubyObject addressResolve(ThreadContext context, IRubyObject scheduler, IRubyObject hostname) {
return Helpers.invokeChecked(context, scheduler, "address_resolve", hostname);
}
// MRI: verify_scheduler
static void verifyInterface(ThreadContext context, IRubyObject scheduler) {
if (!scheduler.respondsTo("block")) {
throw argumentError(context, "Scheduler must implement #block");
}
if (!scheduler.respondsTo("unblock")) {
throw argumentError(context, "Scheduler must implement #unblock");
}
if (!scheduler.respondsTo("kernel_sleep")) {
throw argumentError(context, "Scheduler must implement #kernel_sleep");
}
if (!scheduler.respondsTo("io_wait")) {
throw argumentError(context, "Scheduler must implement #io_wait");
}
}
// MRI: rb_fiber_scheduler_close
public static IRubyObject close(ThreadContext context, IRubyObject scheduler) {
// VM_ASSERT(ruby_thread_has_gvl_p());
IRubyObject result;
result = Helpers.invokeChecked(context, scheduler, "scheduler_close");
if (result != null) return result;
result = Helpers.invokeChecked(context, scheduler, "close");
if (result != null) return result;
return context.nil;
}
// MRI: rb_fiber_scheduler_io_result_apply
public static int resultApply(ThreadContext context, IRubyObject result) {
int resultInt;
if (result instanceof RubyFixnum fixnum && (resultInt = fixnum.asInt(context)) < 0) {
context.runtime.getPosix().errno(-resultInt);
return -1;
} else {
return toInt(context, result);
}
}
@Deprecated(since = "10.0.0.0")
public static IRubyObject result(Ruby runtime, int result, Errno error) {
return result(runtime.getCurrentContext(), result, error);
}
public static IRubyObject result(ThreadContext context, int result, Errno error) {
return asFixnum(context, result == -1 ? error.value(): result);
}
}