uringmachine 0.8 → 0.8.1
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 +4 -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 +17 -39
- 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: 7fdbc29b1e4c910d05eef327345a52faafd92566d7bdddaad81396bcf1f4767d
|
4
|
+
data.tar.gz: 4729a2ca7640fd58d0d83cc008db6e3431edfcdf04e396bce9981465a8e4e0a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56c03563909bd5acd8466a0ef255cd2a791c9907e7fa9ab0a88d9be22f4db895cfb85f0ed5fc0883d0e583c216e238e954a74623f6d231f38c51de2f65316af8
|
7
|
+
data.tar.gz: 1471eea52c8edb8bab45e4fa058191c13e1c88a39bd728c1be5f72998058724ab7fb8a699d279fe5ace36fec6dc5eaca5361a4265b909d078cf5549dd3a19af2
|
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,16 +141,19 @@ 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
159
|
if (unlikely(ctx.result < 0 && ctx.result != -EINTR))
|
@@ -187,18 +191,19 @@ inline VALUE um_fiber_switch(struct um *machine) {
|
|
187
191
|
if (machine->pending_count > 0) {
|
188
192
|
// if yes, process completions, get runqueue head, put original op
|
189
193
|
// back on runqueue.
|
190
|
-
|
194
|
+
// um_process_ready_cqes(machine);
|
195
|
+
um_wait_for_and_process_ready_cqes(machine, 0);
|
191
196
|
struct um_op *op2 = um_runqueue_shift(machine);
|
192
197
|
if (likely(op2 && op2 != op)) {
|
193
198
|
um_runqueue_push(machine, op);
|
194
|
-
op = op2;
|
199
|
+
op = op2;
|
195
200
|
}
|
196
201
|
}
|
197
202
|
}
|
198
203
|
return process_runqueue_op(machine, op);
|
199
204
|
}
|
200
205
|
|
201
|
-
um_wait_for_and_process_ready_cqes(machine);
|
206
|
+
um_wait_for_and_process_ready_cqes(machine, 1);
|
202
207
|
}
|
203
208
|
}
|
204
209
|
|
@@ -320,45 +325,18 @@ VALUE um_sleep(struct um *machine, double duration) {
|
|
320
325
|
return raise_if_exception(ret);
|
321
326
|
}
|
322
327
|
|
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
328
|
inline VALUE um_read(struct um *machine, int fd, VALUE buffer, int maxlen, int buffer_offset) {
|
351
329
|
struct um_op op;
|
352
330
|
um_prep_op(machine, &op, OP_READ);
|
353
331
|
struct io_uring_sqe *sqe = um_get_sqe(machine, &op);
|
354
332
|
void *ptr = um_prepare_read_buffer(buffer, maxlen, buffer_offset);
|
355
333
|
io_uring_prep_read(sqe, fd, ptr, maxlen, -1);
|
356
|
-
|
334
|
+
|
357
335
|
VALUE ret = um_fiber_switch(machine);
|
358
336
|
if (um_check_completion(machine, &op)) {
|
359
337
|
um_update_read_buffer(machine, buffer, buffer_offset, op.result.res, op.result.flags);
|
360
338
|
ret = INT2NUM(op.result.res);
|
361
|
-
|
339
|
+
|
362
340
|
}
|
363
341
|
|
364
342
|
RB_GC_GUARD(buffer);
|
@@ -652,7 +630,7 @@ VALUE multishot_ensure(VALUE arg) {
|
|
652
630
|
VALUE um_accept_each(struct um *machine, int fd) {
|
653
631
|
struct um_op op;
|
654
632
|
um_prep_op(machine, &op, OP_ACCEPT_MULTISHOT);
|
655
|
-
|
633
|
+
|
656
634
|
struct op_ctx ctx = { .machine = machine, .op = &op, .fd = fd, .read_buf = NULL };
|
657
635
|
return rb_ensure(accept_each_begin, (VALUE)&ctx, multishot_ensure, (VALUE)&ctx);
|
658
636
|
}
|
@@ -803,7 +781,7 @@ VALUE um_periodically(struct um *machine, double interval) {
|
|
803
781
|
struct um_op op;
|
804
782
|
um_prep_op(machine, &op, OP_SLEEP_MULTISHOT);
|
805
783
|
op.ts = um_double_to_timespec(interval);
|
806
|
-
|
784
|
+
|
807
785
|
struct op_ctx ctx = { .machine = machine, .op = &op, .ts = op.ts, .read_buf = NULL };
|
808
786
|
return rb_ensure(periodically_begin, (VALUE)&ctx, multishot_ensure, (VALUE)&ctx);
|
809
787
|
}
|
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
|