uringmachine 0.8 → 0.8.2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/examples/bm_http_parse.rb +3 -3
- data/examples/bm_queue.rb +2 -2
- data/examples/bm_write.rb +3 -3
- data/examples/pg.rb +1 -1
- data/examples/server_client.rb +2 -2
- data/examples/snooze.rb +1 -1
- data/examples/stream.rb +1 -1
- data/ext/um/um.c +31 -41
- data/ext/um/um.h +1 -1
- data/ext/um/um_const.c +3 -3
- data/ext/um/um_op.c +1 -1
- data/ext/um/um_sync.c +5 -5
- data/lib/uringmachine/actor.rb +1 -1
- data/lib/uringmachine/version.rb +1 -1
- data/test/helper.rb +1 -1
- data/test/test_actor.rb +2 -2
- data/test/test_async_op.rb +5 -5
- data/test/test_fiber.rb +6 -3
- data/test/test_um.rb +58 -15
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24d5dacdb24cc1da4928d753803bd8012502147aaae23c4c7d9e53945550233c
|
4
|
+
data.tar.gz: 783c8359ae60e149944bd7f79ac588c9b85241f5cec66de11eeae60b92e99753
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 84c77a3826b01acd67bfca663d93e8a8e2a093b7415861040087d7bdcac97f34f3ed829c67529e6dd52abdc0ac88ac8395a0a39315f98fb2966f617c9b8f8dcb
|
7
|
+
data.tar.gz: 238b77b0a4d669b3421d8ce26e888dad76d0885b19405017c1ce2c118f5fb0ac022c4ffed7288ae6389dda6f54810e511e77209bcc8f2e8872aee9a4573fa704
|
data/CHANGELOG.md
CHANGED
data/examples/bm_http_parse.rb
CHANGED
@@ -43,7 +43,7 @@ def parse_http_parser
|
|
43
43
|
headers['protocol'] = parser.http_version
|
44
44
|
$machine.schedule(current_fiber, headers)
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
$machine.write(w.fileno, HTTP_MSG)
|
48
48
|
$machine.yield
|
49
49
|
ensure
|
@@ -89,7 +89,7 @@ def parse_headers(fd)
|
|
89
89
|
while true
|
90
90
|
line = get_line(fd, sio, buffer)
|
91
91
|
break if line.empty?
|
92
|
-
|
92
|
+
|
93
93
|
m = line.match(RE_HEADER_LINE)
|
94
94
|
raise "Invalid header" if !m
|
95
95
|
|
@@ -111,7 +111,7 @@ def parse_http_stringio
|
|
111
111
|
puts e.backtrace.join("\n")
|
112
112
|
exit!
|
113
113
|
end
|
114
|
-
|
114
|
+
|
115
115
|
$machine.write(w.fileno, HTTP_MSG)
|
116
116
|
$machine.yield
|
117
117
|
ensure
|
data/examples/bm_queue.rb
CHANGED
@@ -18,14 +18,14 @@ NUM_CONSUMERS = 10
|
|
18
18
|
def run_threads
|
19
19
|
queue = Queue.new
|
20
20
|
done = Queue.new
|
21
|
-
|
21
|
+
|
22
22
|
NUM_PRODUCERS.times do
|
23
23
|
Thread.new do
|
24
24
|
COUNT.times { queue << rand(1000) }
|
25
25
|
done << true
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
total = 0
|
30
30
|
NUM_CONSUMERS.times do
|
31
31
|
Thread.new do
|
data/examples/bm_write.rb
CHANGED
@@ -18,7 +18,7 @@ FN = '/tmp/bm_write'
|
|
18
18
|
def run_io_write(num_threads)
|
19
19
|
FileUtils.rm(FN) rescue nil
|
20
20
|
fio = File.open(FN, 'w')
|
21
|
-
|
21
|
+
|
22
22
|
threads = num_threads.times.map do |i|
|
23
23
|
Thread.new do
|
24
24
|
ITERATIONS.times { fio.write(BUF) }
|
@@ -33,13 +33,13 @@ def run_um_write(num_fibers)
|
|
33
33
|
FileUtils.rm(FN) rescue nil
|
34
34
|
fio = File.open(FN, 'w')
|
35
35
|
fd = fio.fileno
|
36
|
-
|
36
|
+
|
37
37
|
machine = UringMachine.new
|
38
38
|
done = UringMachine::Queue.new
|
39
39
|
num_fibers.times do
|
40
40
|
machine.spin do
|
41
41
|
ITERATIONS.times { machine.write(fd, BUF) }
|
42
|
-
machine.push(done, true)
|
42
|
+
machine.push(done, true)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
num_fibers.times { machine.pop(done) }
|
data/examples/pg.rb
CHANGED
data/examples/server_client.rb
CHANGED
@@ -31,7 +31,7 @@ def run_client
|
|
31
31
|
@machine.send(fd, msg, msg.bytesize, 0)
|
32
32
|
res = @machine.recv(fd, buf, 8192, 0)
|
33
33
|
@counter += 2
|
34
|
-
|
34
|
+
|
35
35
|
break if res == 0
|
36
36
|
raise "Got #{res} bytes instead of #{msg.bytesize}" if res != msg.bytesize
|
37
37
|
end
|
@@ -59,6 +59,6 @@ end
|
|
59
59
|
|
60
60
|
t0 = Time.now
|
61
61
|
@machine.sleep 3
|
62
|
-
t1 = Time.now
|
62
|
+
t1 = Time.now
|
63
63
|
elapsed = t1 - t0
|
64
64
|
puts "Did #{@counter} ops in #{elapsed} seconds (#{(@counter / elapsed)} ops/s)"
|
data/examples/snooze.rb
CHANGED
data/examples/stream.rb
CHANGED
data/ext/um/um.c
CHANGED
@@ -89,7 +89,7 @@ static inline void um_process_cqe(struct um *machine, struct io_uring_cqe *cqe)
|
|
89
89
|
}
|
90
90
|
|
91
91
|
if (op->flags & OP_F_ASYNC) return;
|
92
|
-
|
92
|
+
|
93
93
|
um_runqueue_push(machine, op);
|
94
94
|
}
|
95
95
|
|
@@ -127,6 +127,7 @@ done:
|
|
127
127
|
struct wait_for_cqe_ctx {
|
128
128
|
struct um *machine;
|
129
129
|
struct io_uring_cqe *cqe;
|
130
|
+
int wait_nr;
|
130
131
|
int result;
|
131
132
|
};
|
132
133
|
|
@@ -140,20 +141,35 @@ void *um_wait_for_cqe_without_gvl(void *ptr) {
|
|
140
141
|
// NULL.
|
141
142
|
//
|
142
143
|
// https://github.com/axboe/liburing/issues/1280
|
143
|
-
int res = io_uring_submit_and_wait_timeout(&ctx->machine->ring, &ctx->cqe,
|
144
|
+
int res = io_uring_submit_and_wait_timeout(&ctx->machine->ring, &ctx->cqe, ctx->wait_nr, NULL, NULL);
|
144
145
|
ctx->result = (res > 0 && !ctx->cqe) ? -EINTR : res;
|
145
146
|
}
|
146
147
|
else
|
147
|
-
ctx->result =
|
148
|
+
ctx->result = io_uring_wait_cqes(&ctx->machine->ring, &ctx->cqe, ctx->wait_nr, NULL, NULL);
|
148
149
|
return NULL;
|
149
150
|
}
|
150
151
|
|
151
|
-
|
152
|
-
|
152
|
+
// Waits for the given minimum number of completion entries. The wait_nr is
|
153
|
+
// either 1 - where we wait for at least one CQE to be ready, or 0, where we
|
154
|
+
// don't wait, and just process any CQEs that already ready.
|
155
|
+
static inline void um_wait_for_and_process_ready_cqes(struct um *machine, int wait_nr) {
|
156
|
+
struct wait_for_cqe_ctx ctx = { .machine = machine, .cqe = NULL, .wait_nr = wait_nr };
|
153
157
|
rb_thread_call_without_gvl(um_wait_for_cqe_without_gvl, (void *)&ctx, RUBY_UBF_IO, 0);
|
154
158
|
|
155
|
-
if (unlikely(ctx.result < 0
|
156
|
-
|
159
|
+
if (unlikely(ctx.result < 0)) {
|
160
|
+
// the internal calls to (maybe submit) and wait for cqes may fail with:
|
161
|
+
// -EINTR (interrupted by signal)
|
162
|
+
// -EAGAIN (apparently can be returned when wait_nr = 0)
|
163
|
+
// both should not raise an exception.
|
164
|
+
switch (ctx.result) {
|
165
|
+
case -EINTR:
|
166
|
+
case -EAGAIN:
|
167
|
+
// do nothing
|
168
|
+
break;
|
169
|
+
default:
|
170
|
+
rb_syserr_fail(-ctx.result, strerror(-ctx.result));
|
171
|
+
}
|
172
|
+
}
|
157
173
|
|
158
174
|
if (ctx.cqe) {
|
159
175
|
um_process_cqe(machine, ctx.cqe);
|
@@ -187,18 +203,19 @@ inline VALUE um_fiber_switch(struct um *machine) {
|
|
187
203
|
if (machine->pending_count > 0) {
|
188
204
|
// if yes, process completions, get runqueue head, put original op
|
189
205
|
// back on runqueue.
|
190
|
-
|
206
|
+
// um_process_ready_cqes(machine);
|
207
|
+
um_wait_for_and_process_ready_cqes(machine, 0);
|
191
208
|
struct um_op *op2 = um_runqueue_shift(machine);
|
192
209
|
if (likely(op2 && op2 != op)) {
|
193
210
|
um_runqueue_push(machine, op);
|
194
|
-
op = op2;
|
211
|
+
op = op2;
|
195
212
|
}
|
196
213
|
}
|
197
214
|
}
|
198
215
|
return process_runqueue_op(machine, op);
|
199
216
|
}
|
200
217
|
|
201
|
-
um_wait_for_and_process_ready_cqes(machine);
|
218
|
+
um_wait_for_and_process_ready_cqes(machine, 1);
|
202
219
|
}
|
203
220
|
}
|
204
221
|
|
@@ -320,45 +337,18 @@ VALUE um_sleep(struct um *machine, double duration) {
|
|
320
337
|
return raise_if_exception(ret);
|
321
338
|
}
|
322
339
|
|
323
|
-
// VALUE um_periodically(struct um *machine, double interval) {
|
324
|
-
// struct um_op op;
|
325
|
-
// VALUE ret = Qnil;
|
326
|
-
// um_prep_op(machine, &op, OP_SLEEP_MULTISHOT);
|
327
|
-
// op.ts = um_double_to_timespec(interval);
|
328
|
-
// op.flags |= OP_F_MULTISHOT;
|
329
|
-
// struct io_uring_sqe *sqe = um_get_sqe(machine, &op);
|
330
|
-
// io_uring_prep_timeout(sqe, &op.ts, 0, IORING_TIMEOUT_MULTISHOT);
|
331
|
-
|
332
|
-
// while (true) {
|
333
|
-
// ret = um_fiber_switch(machine);
|
334
|
-
|
335
|
-
// if (!um_op_completed_p(&op)) {
|
336
|
-
// um_cancel_and_wait(machine, &op);
|
337
|
-
// break;
|
338
|
-
// }
|
339
|
-
// else {
|
340
|
-
// if (op.result.res != -ETIME) um_raise_on_error_result(op.result.res);
|
341
|
-
// ret = DBL2NUM(interval);
|
342
|
-
// }
|
343
|
-
// }
|
344
|
-
|
345
|
-
// RB_GC_GUARD(ret);
|
346
|
-
// return raise_if_exception(ret);
|
347
|
-
|
348
|
-
// }
|
349
|
-
|
350
340
|
inline VALUE um_read(struct um *machine, int fd, VALUE buffer, int maxlen, int buffer_offset) {
|
351
341
|
struct um_op op;
|
352
342
|
um_prep_op(machine, &op, OP_READ);
|
353
343
|
struct io_uring_sqe *sqe = um_get_sqe(machine, &op);
|
354
344
|
void *ptr = um_prepare_read_buffer(buffer, maxlen, buffer_offset);
|
355
345
|
io_uring_prep_read(sqe, fd, ptr, maxlen, -1);
|
356
|
-
|
346
|
+
|
357
347
|
VALUE ret = um_fiber_switch(machine);
|
358
348
|
if (um_check_completion(machine, &op)) {
|
359
349
|
um_update_read_buffer(machine, buffer, buffer_offset, op.result.res, op.result.flags);
|
360
350
|
ret = INT2NUM(op.result.res);
|
361
|
-
|
351
|
+
|
362
352
|
}
|
363
353
|
|
364
354
|
RB_GC_GUARD(buffer);
|
@@ -652,7 +642,7 @@ VALUE multishot_ensure(VALUE arg) {
|
|
652
642
|
VALUE um_accept_each(struct um *machine, int fd) {
|
653
643
|
struct um_op op;
|
654
644
|
um_prep_op(machine, &op, OP_ACCEPT_MULTISHOT);
|
655
|
-
|
645
|
+
|
656
646
|
struct op_ctx ctx = { .machine = machine, .op = &op, .fd = fd, .read_buf = NULL };
|
657
647
|
return rb_ensure(accept_each_begin, (VALUE)&ctx, multishot_ensure, (VALUE)&ctx);
|
658
648
|
}
|
@@ -803,7 +793,7 @@ VALUE um_periodically(struct um *machine, double interval) {
|
|
803
793
|
struct um_op op;
|
804
794
|
um_prep_op(machine, &op, OP_SLEEP_MULTISHOT);
|
805
795
|
op.ts = um_double_to_timespec(interval);
|
806
|
-
|
796
|
+
|
807
797
|
struct op_ctx ctx = { .machine = machine, .op = &op, .ts = op.ts, .read_buf = NULL };
|
808
798
|
return rb_ensure(periodically_begin, (VALUE)&ctx, multishot_ensure, (VALUE)&ctx);
|
809
799
|
}
|
data/ext/um/um.h
CHANGED
data/ext/um/um_const.c
CHANGED
@@ -159,7 +159,7 @@ void um_define_net_constants(VALUE mod) {
|
|
159
159
|
DEF_CONST_INT(mod, TCP_THIN_LINEAR_TIMEOUTS);
|
160
160
|
DEF_CONST_INT(mod, TCP_TIMESTAMP);
|
161
161
|
DEF_CONST_INT(mod, TCP_USER_TIMEOUT);
|
162
|
-
|
162
|
+
|
163
163
|
DEF_CONST_INT(mod, UDP_CORK);
|
164
164
|
|
165
165
|
DEF_CONST_INT(mod, AI_PASSIVE);
|
@@ -169,7 +169,7 @@ void um_define_net_constants(VALUE mod) {
|
|
169
169
|
DEF_CONST_INT(mod, AI_ALL);
|
170
170
|
DEF_CONST_INT(mod, AI_ADDRCONFIG);
|
171
171
|
DEF_CONST_INT(mod, AI_V4MAPPED);
|
172
|
-
|
172
|
+
|
173
173
|
DEF_CONST_INT(mod, NI_MAXHOST);
|
174
174
|
DEF_CONST_INT(mod, NI_MAXSERV);
|
175
175
|
DEF_CONST_INT(mod, NI_NOFQDN);
|
@@ -177,7 +177,7 @@ void um_define_net_constants(VALUE mod) {
|
|
177
177
|
DEF_CONST_INT(mod, NI_NAMEREQD);
|
178
178
|
DEF_CONST_INT(mod, NI_NUMERICSERV);
|
179
179
|
DEF_CONST_INT(mod, NI_DGRAM);
|
180
|
-
|
180
|
+
|
181
181
|
DEF_CONST_INT(mod, SHUT_RD);
|
182
182
|
DEF_CONST_INT(mod, SHUT_WR);
|
183
183
|
DEF_CONST_INT(mod, SHUT_RDWR);
|
data/ext/um/um_op.c
CHANGED
@@ -66,7 +66,7 @@ inline void um_op_list_compact(struct um *machine, struct um_op *head) {
|
|
66
66
|
}
|
67
67
|
}
|
68
68
|
|
69
|
-
inline struct um_op_result *multishot_result_alloc(struct um *machine) {
|
69
|
+
inline struct um_op_result *multishot_result_alloc(struct um *machine) {
|
70
70
|
if (machine->result_freelist) {
|
71
71
|
struct um_op_result *result = machine->result_freelist;
|
72
72
|
machine->result_freelist = result->next;
|
data/ext/um/um_sync.c
CHANGED
@@ -12,7 +12,7 @@ void um_futex_wait(struct um *machine, uint32_t *futex, uint32_t expect) {
|
|
12
12
|
sqe, (uint32_t *)futex, expect, FUTEX_BITSET_MATCH_ANY,
|
13
13
|
FUTEX2_SIZE_U32, 0
|
14
14
|
);
|
15
|
-
|
15
|
+
|
16
16
|
VALUE ret = um_fiber_switch(machine);
|
17
17
|
if (!um_op_completed_p(&op))
|
18
18
|
um_cancel_and_wait(machine, &op);
|
@@ -157,7 +157,7 @@ static inline void queue_add_head(struct um_queue *queue, VALUE value) {
|
|
157
157
|
struct um_queue_entry *entry = um_queue_entry_checkout(queue);
|
158
158
|
|
159
159
|
entry->next = queue->head;
|
160
|
-
if (queue->head) {
|
160
|
+
if (queue->head) {
|
161
161
|
queue->head->prev = entry;
|
162
162
|
queue->head = entry;
|
163
163
|
}
|
@@ -171,7 +171,7 @@ static inline void queue_add_tail(struct um_queue *queue, VALUE value) {
|
|
171
171
|
struct um_queue_entry *entry = um_queue_entry_checkout(queue);
|
172
172
|
|
173
173
|
entry->prev = queue->tail;
|
174
|
-
if (queue->tail) {
|
174
|
+
if (queue->tail) {
|
175
175
|
queue->tail->next = entry;
|
176
176
|
queue->tail = entry;
|
177
177
|
}
|
@@ -205,7 +205,7 @@ VALUE queue_remove_tail(struct um_queue *queue) {
|
|
205
205
|
static inline VALUE um_queue_add(struct um *machine, struct um_queue *queue, VALUE value, int add_head) {
|
206
206
|
if (add_head) queue_add_head(queue, value);
|
207
207
|
else queue_add_tail(queue, value);
|
208
|
-
|
208
|
+
|
209
209
|
queue->count++;
|
210
210
|
|
211
211
|
queue->state = QUEUE_READY;
|
@@ -232,7 +232,7 @@ struct queue_wait_ctx {
|
|
232
232
|
|
233
233
|
VALUE um_queue_remove_begin(VALUE arg) {
|
234
234
|
struct queue_wait_ctx *ctx = (struct queue_wait_ctx *)arg;
|
235
|
-
|
235
|
+
|
236
236
|
ctx->queue->num_waiters++;
|
237
237
|
while (ctx->queue->state == QUEUE_EMPTY) {
|
238
238
|
um_futex_wait(ctx->machine, &ctx->queue->state, QUEUE_EMPTY);
|
data/lib/uringmachine/actor.rb
CHANGED
data/lib/uringmachine/version.rb
CHANGED
data/test/helper.rb
CHANGED
data/test/test_actor.rb
CHANGED
@@ -26,7 +26,7 @@ class ActorTest < UMBaseTest
|
|
26
26
|
def test_basic_actor_functionality
|
27
27
|
mailbox = UM::Queue.new
|
28
28
|
actor = @machine.spin_actor(Counter)
|
29
|
-
|
29
|
+
|
30
30
|
assert_kind_of Fiber, actor
|
31
31
|
|
32
32
|
assert_equal 0, actor.call(mailbox, :get)
|
@@ -59,7 +59,7 @@ class ActorTest < UMBaseTest
|
|
59
59
|
def test_actor_with_args
|
60
60
|
actor = @machine.spin_actor(Counter2, 43)
|
61
61
|
mailbox = UM::Queue.new
|
62
|
-
|
62
|
+
|
63
63
|
assert_equal 43, actor.call(mailbox, :get)
|
64
64
|
end
|
65
65
|
end
|
data/test/test_async_op.rb
CHANGED
@@ -37,9 +37,9 @@ class AsyncOpTest < UMBaseTest
|
|
37
37
|
assert_equal 1, machine.pending_count
|
38
38
|
@op.cancel
|
39
39
|
assert_equal false, @op.done?
|
40
|
-
|
40
|
+
|
41
41
|
machine.sleep(0.01)
|
42
|
-
|
42
|
+
|
43
43
|
assert_equal 0, machine.pending_count
|
44
44
|
assert_equal true, @op.done?
|
45
45
|
assert_equal (-ECANCELED), @op.result
|
@@ -52,7 +52,7 @@ class AsyncOpTest < UMBaseTest
|
|
52
52
|
end
|
53
53
|
|
54
54
|
res = @op.await
|
55
|
-
|
55
|
+
|
56
56
|
assert_equal 0, machine.pending_count
|
57
57
|
assert_equal true, @op.done?
|
58
58
|
assert_equal (-ECANCELED), res
|
@@ -63,7 +63,7 @@ class AsyncOpTest < UMBaseTest
|
|
63
63
|
|
64
64
|
def test_async_op_await_with_timeout
|
65
65
|
e = nil
|
66
|
-
|
66
|
+
|
67
67
|
begin
|
68
68
|
machine.timeout(0.01, TOError) do
|
69
69
|
@op.await
|
@@ -80,7 +80,7 @@ class AsyncOpTest < UMBaseTest
|
|
80
80
|
|
81
81
|
def test_async_op_await_with_timeout2
|
82
82
|
e = nil
|
83
|
-
|
83
|
+
|
84
84
|
begin
|
85
85
|
machine.timeout(0.1, TOError) do
|
86
86
|
@op.await
|
data/test/test_fiber.rb
CHANGED
@@ -55,7 +55,7 @@ class FiberTerminateTest < UMBaseTest
|
|
55
55
|
assert_nil x
|
56
56
|
machine.snooze
|
57
57
|
assert_equal 1, x
|
58
|
-
|
58
|
+
|
59
59
|
machine.schedule(f, UM::Terminate.new)
|
60
60
|
2.times { machine.snooze }
|
61
61
|
|
@@ -149,6 +149,7 @@ class ScopeTest < UMBaseTest
|
|
149
149
|
x1 = nil
|
150
150
|
x2 = nil
|
151
151
|
|
152
|
+
t0 = monotonic_clock
|
152
153
|
machine.scope do
|
153
154
|
f1 = machine.spin do
|
154
155
|
x1 = 1
|
@@ -159,13 +160,15 @@ class ScopeTest < UMBaseTest
|
|
159
160
|
|
160
161
|
f2 = machine.spin do
|
161
162
|
x2 = 1
|
162
|
-
machine.sleep 0.
|
163
|
+
machine.sleep 0.03
|
163
164
|
ensure
|
164
165
|
x2 = 0
|
165
166
|
end
|
166
167
|
end
|
168
|
+
elapsed = monotonic_clock - t0
|
169
|
+
assert_in_range 0.03..0.05, elapsed
|
167
170
|
|
168
171
|
assert_equal 0, x1
|
169
172
|
assert_equal 0, x2
|
170
173
|
end
|
171
|
-
end
|
174
|
+
end
|
data/test/test_um.rb
CHANGED
@@ -11,7 +11,7 @@ class UringMachineTest < Minitest::Test
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
class
|
14
|
+
class SpinTest < UMBaseTest
|
15
15
|
def test_spin
|
16
16
|
x = nil
|
17
17
|
f = machine.spin do
|
@@ -27,6 +27,24 @@ class FiberTest < UMBaseTest
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
+
class SnoozeTest < UMBaseTest
|
31
|
+
def test_snooze_while_sleeping_fiber
|
32
|
+
f = machine.spin do
|
33
|
+
machine.sleep(0.1)
|
34
|
+
end
|
35
|
+
|
36
|
+
t0 = monotonic_clock
|
37
|
+
machine.snooze
|
38
|
+
t1 = monotonic_clock
|
39
|
+
assert_in_range 0..0.001, t1 - t0
|
40
|
+
|
41
|
+
t0 = monotonic_clock
|
42
|
+
machine.snooze
|
43
|
+
t1 = monotonic_clock
|
44
|
+
assert_in_range 0..0.001, t1 - t0
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
30
48
|
class ScheduleTest < UMBaseTest
|
31
49
|
def test_schedule_and_yield
|
32
50
|
buf = []
|
@@ -60,7 +78,7 @@ class ScheduleTest < UMBaseTest
|
|
60
78
|
buf << e
|
61
79
|
machine.yield
|
62
80
|
end
|
63
|
-
|
81
|
+
|
64
82
|
machine.schedule(f, nil)
|
65
83
|
# start the f fiber
|
66
84
|
machine.snooze
|
@@ -80,7 +98,7 @@ class ScheduleTest < UMBaseTest
|
|
80
98
|
machine.schedule(main, e)
|
81
99
|
machine.yield
|
82
100
|
end
|
83
|
-
|
101
|
+
|
84
102
|
machine.schedule(f, nil)
|
85
103
|
t0 = monotonic_clock
|
86
104
|
|
@@ -234,7 +252,7 @@ class PeriodicallyTest < UMBaseTest
|
|
234
252
|
t1 = monotonic_clock
|
235
253
|
assert_in_range 0.05..0.09, t1 - t0
|
236
254
|
assert_equal 5, count
|
237
|
-
assert_equal 1, cancel
|
255
|
+
assert_equal 1, cancel
|
238
256
|
end
|
239
257
|
|
240
258
|
def test_periodically_with_timeout
|
@@ -258,7 +276,7 @@ class PeriodicallyTest < UMBaseTest
|
|
258
276
|
t1 = monotonic_clock
|
259
277
|
assert_in_range 0.05..0.08, t1 - t0
|
260
278
|
assert_in_range 4..6, count
|
261
|
-
assert_equal 1, cancel
|
279
|
+
assert_equal 1, cancel
|
262
280
|
|
263
281
|
end
|
264
282
|
end
|
@@ -331,7 +349,7 @@ class ReadTest < UMBaseTest
|
|
331
349
|
|
332
350
|
buffer = +'foo'
|
333
351
|
sio = StringIO.new(buffer)
|
334
|
-
|
352
|
+
|
335
353
|
r, w = IO.pipe
|
336
354
|
w << 'bar'
|
337
355
|
|
@@ -366,7 +384,7 @@ class ReadEachTest < UMBaseTest
|
|
366
384
|
w.close
|
367
385
|
machine.yield
|
368
386
|
end
|
369
|
-
|
387
|
+
|
370
388
|
machine.schedule(f, nil)
|
371
389
|
|
372
390
|
machine.read_each(r.fileno, bgid) do |buf|
|
@@ -464,7 +482,7 @@ class ReadEachTest < UMBaseTest
|
|
464
482
|
sleep 0.1
|
465
483
|
w.close
|
466
484
|
end
|
467
|
-
|
485
|
+
|
468
486
|
bufs = []
|
469
487
|
machine.read_each(r.fileno, bgid) do |b|
|
470
488
|
bufs << b
|
@@ -591,7 +609,7 @@ class AcceptTest < UMBaseTest
|
|
591
609
|
|
592
610
|
def test_accept
|
593
611
|
conn = TCPSocket.new('127.0.0.1', @port)
|
594
|
-
|
612
|
+
|
595
613
|
assert_equal 0, machine.pending_count
|
596
614
|
fd = machine.accept(@server.fileno)
|
597
615
|
assert_equal 0, machine.pending_count
|
@@ -635,6 +653,32 @@ class AcceptEachTest < UMBaseTest
|
|
635
653
|
ensure
|
636
654
|
t&.kill
|
637
655
|
end
|
656
|
+
|
657
|
+
def test_accept_each_interrupted
|
658
|
+
conns = []
|
659
|
+
count = 0
|
660
|
+
terminated = nil
|
661
|
+
f = @machine.spin do
|
662
|
+
machine.accept_each(@server.fileno) do |fd|
|
663
|
+
count += 1
|
664
|
+
break if count == 3
|
665
|
+
end
|
666
|
+
rescue UM::Terminate
|
667
|
+
terminated = true
|
668
|
+
end
|
669
|
+
|
670
|
+
s = TCPSocket.new('127.0.0.1', @port)
|
671
|
+
@machine.sleep(0.01)
|
672
|
+
|
673
|
+
assert_equal 1, count
|
674
|
+
refute terminated
|
675
|
+
|
676
|
+
@machine.schedule(f, UM::Terminate.new)
|
677
|
+
@machine.sleep(0.01)
|
678
|
+
|
679
|
+
assert f.done?
|
680
|
+
assert terminated
|
681
|
+
end
|
638
682
|
end
|
639
683
|
|
640
684
|
class SocketTest < UMBaseTest
|
@@ -1041,10 +1085,9 @@ class QueueTest < UMBaseTest
|
|
1041
1085
|
machine.schedule(f2, nil)
|
1042
1086
|
|
1043
1087
|
machine.snooze
|
1044
|
-
|
1045
1088
|
assert_equal [[1, :foo]], buf
|
1046
|
-
machine.push(q, :bar)
|
1047
1089
|
|
1090
|
+
machine.push(q, :bar)
|
1048
1091
|
machine.snooze
|
1049
1092
|
assert_equal [[1, :foo], [2, :bar]], buf
|
1050
1093
|
end
|
@@ -1082,7 +1125,7 @@ class QueueTest < UMBaseTest
|
|
1082
1125
|
|
1083
1126
|
t1 = Thread.new {
|
1084
1127
|
m = UM.new
|
1085
|
-
3.times { m.push(q, it)
|
1128
|
+
3.times { m.push(q, it) }
|
1086
1129
|
}
|
1087
1130
|
|
1088
1131
|
items = []
|
@@ -1090,7 +1133,7 @@ class QueueTest < UMBaseTest
|
|
1090
1133
|
t2 = Thread.new {
|
1091
1134
|
m = UM.new
|
1092
1135
|
3.times {
|
1093
|
-
i = m.
|
1136
|
+
i = m.shift(q)
|
1094
1137
|
items << i
|
1095
1138
|
m.sleep(0.01)
|
1096
1139
|
}
|
@@ -1143,7 +1186,7 @@ class PipeTest < UMBaseTest
|
|
1143
1186
|
rfd, wfd = UM.pipe
|
1144
1187
|
ret = machine.write(wfd, 'foo')
|
1145
1188
|
assert_equal 3, ret
|
1146
|
-
|
1189
|
+
|
1147
1190
|
ret = machine.close(wfd)
|
1148
1191
|
assert_equal wfd, ret
|
1149
1192
|
|
@@ -1185,6 +1228,6 @@ class WaitTest < UMBaseTest
|
|
1185
1228
|
def test_waitpid_bad_pid
|
1186
1229
|
skip if UM.kernel_version < 607
|
1187
1230
|
|
1188
|
-
assert_raises(Errno::ECHILD) { machine.waitpid(1, UM::WEXITED) }
|
1231
|
+
assert_raises(Errno::ECHILD) { machine.waitpid(1, UM::WEXITED) }
|
1189
1232
|
end
|
1190
1233
|
end
|