polyphony 0.76 → 0.77
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -1
- data/Gemfile.lock +1 -1
- data/examples/core/trap1.rb +21 -0
- data/examples/core/trap2.rb +14 -0
- data/ext/polyphony/backend_io_uring.c +5 -1
- data/ext/polyphony/backend_libev.c +5 -0
- data/ext/test_eintr.c +50 -0
- data/lib/polyphony/extensions/fiber.rb +12 -6
- data/lib/polyphony/version.rb +1 -1
- data/test/helper.rb +2 -1
- data/test/stress.rb +1 -1
- data/test/test_fiber.rb +6 -4
- data/test/test_signal.rb +57 -0
- data/test/test_timer.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 10f049946dc02d9cdd984cc8658687d2319e0fd85f6f2cce74aa0a887bc714cb
|
4
|
+
data.tar.gz: 5118859d4640aebeddb9186c43d58617e9b455a63ea97c1dc8283432db954fd1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e107e21d6c42f9cd9e91521e288dfee37a6f0da4b7d8a8d311924bf88ccf732d2cc94de834dbbaa3c7a974e5bb84ce1d8d20efd68870c9f2dac9b73155d28558
|
7
|
+
data.tar.gz: 8e4f7005c9cbc46cd084bbe66a4e8f7145f6a4a3062ce027a70eee07c0e648f79289515591ef4b48010580b7125c403ab09e45417781346ebf6da4b2d528ec45
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
pid = Process.pid
|
4
|
+
fork do
|
5
|
+
sleep 1
|
6
|
+
Process.kill('SIGINT', pid)
|
7
|
+
# sleep 10
|
8
|
+
# Process.kill(-9, pid)
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'bundler/setup'
|
12
|
+
require 'polyphony'
|
13
|
+
|
14
|
+
Thread.backend.trace_proc = proc { |*e| STDOUT.orig_write("#{e.inspect}\n") }
|
15
|
+
trap('SIGINT') { STDOUT.orig_write("* recv SIGINT\n") }
|
16
|
+
# trap('SIGCHLD') { STDOUT.orig_write("* recv SIGCHLD\n") }
|
17
|
+
STDOUT.orig_write("* pre gets\n")
|
18
|
+
# STDIN.wait_readable
|
19
|
+
s = gets
|
20
|
+
p s
|
21
|
+
STDOUT.orig_write("* post gets\n")
|
@@ -191,10 +191,14 @@ void io_uring_backend_poll(Backend_t *backend) {
|
|
191
191
|
io_uring_submit(&backend->ring);
|
192
192
|
}
|
193
193
|
|
194
|
+
wait_cqe:
|
194
195
|
backend->base.currently_polling = 1;
|
195
196
|
rb_thread_call_without_gvl(io_uring_backend_poll_without_gvl, (void *)&poll_ctx, RUBY_UBF_IO, 0);
|
196
197
|
backend->base.currently_polling = 0;
|
197
|
-
if (poll_ctx.result < 0)
|
198
|
+
if (poll_ctx.result < 0) {
|
199
|
+
if (poll_ctx.result == -EINTR && runqueue_empty_p(&backend->base.runqueue)) goto wait_cqe;
|
200
|
+
return;
|
201
|
+
}
|
198
202
|
|
199
203
|
io_uring_backend_handle_completion(poll_ctx.cqe, backend);
|
200
204
|
io_uring_cqe_seen(&backend->ring, poll_ctx.cqe);
|
@@ -169,9 +169,14 @@ inline VALUE Backend_poll(VALUE self, VALUE blocking) {
|
|
169
169
|
backend->base.poll_count++;
|
170
170
|
|
171
171
|
COND_TRACE(&backend->base, 2, SYM_fiber_event_poll_enter, rb_fiber_current());
|
172
|
+
|
173
|
+
ev_run:
|
172
174
|
backend->base.currently_polling = 1;
|
175
|
+
errno = 0;
|
173
176
|
ev_run(backend->ev_loop, blocking == Qtrue ? EVRUN_ONCE : EVRUN_NOWAIT);
|
174
177
|
backend->base.currently_polling = 0;
|
178
|
+
if (errno == EINTR && runqueue_empty_p(&backend->base.runqueue)) goto ev_run;
|
179
|
+
|
175
180
|
COND_TRACE(&backend->base, 2, SYM_fiber_event_poll_leave, rb_fiber_current());
|
176
181
|
|
177
182
|
return self;
|
data/ext/test_eintr.c
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include <unistd.h>
|
3
|
+
#include <signal.h>
|
4
|
+
#include <poll.h>
|
5
|
+
#include "./liburing/liburing.h"
|
6
|
+
|
7
|
+
void sig_handler(int sig) {
|
8
|
+
printf("handle signal %d!\n", sig);
|
9
|
+
}
|
10
|
+
|
11
|
+
int main(int argc, char *argv[])
|
12
|
+
{
|
13
|
+
int pid = getpid();
|
14
|
+
int child_pid = fork();
|
15
|
+
if (!child_pid) {
|
16
|
+
sleep(1);
|
17
|
+
kill(pid, SIGINT);
|
18
|
+
sleep(1);
|
19
|
+
kill(pid, SIGINT);
|
20
|
+
}
|
21
|
+
else {
|
22
|
+
struct sigaction sa;
|
23
|
+
|
24
|
+
sa.sa_handler = sig_handler;
|
25
|
+
sa.sa_flags = SA_SIGINFO | SA_ONSTACK;//0;
|
26
|
+
sigemptyset(&sa.sa_mask);
|
27
|
+
sigaction(SIGINT, &sa, NULL);
|
28
|
+
|
29
|
+
printf("pid: %d\n", pid);
|
30
|
+
|
31
|
+
struct io_uring ring;
|
32
|
+
int ret = io_uring_queue_init(16, &ring, 0);
|
33
|
+
printf("io_uring_queue_init: %d\n", ret);
|
34
|
+
|
35
|
+
struct io_uring_sqe *sqe = io_uring_get_sqe(&ring);
|
36
|
+
io_uring_prep_poll_add(sqe, STDIN_FILENO, POLLIN);
|
37
|
+
ret = io_uring_submit(&ring);
|
38
|
+
printf("io_uring_submit: %d\n", ret);
|
39
|
+
|
40
|
+
struct io_uring_cqe *cqe;
|
41
|
+
|
42
|
+
wait_cqe:
|
43
|
+
ret = io_uring_wait_cqe(&ring, &cqe);
|
44
|
+
printf("io_uring_wait_cqe: %d\n", ret);
|
45
|
+
if (ret == -EINTR) goto wait_cqe;
|
46
|
+
|
47
|
+
printf("done\n");
|
48
|
+
return 0;
|
49
|
+
}
|
50
|
+
}
|
@@ -248,21 +248,27 @@ module Polyphony
|
|
248
248
|
# also be scheduled with priority. This method is mainly used trapping
|
249
249
|
# signals (see also the patched `Kernel#trap`)
|
250
250
|
def schedule_priority_oob_fiber(&block)
|
251
|
-
|
251
|
+
oob_fiber = Fiber.new do
|
252
252
|
Fiber.current.setup_raw
|
253
253
|
result = block.call
|
254
254
|
rescue Exception => e
|
255
255
|
Thread.current.schedule_and_wakeup(Thread.main.main_fiber, e)
|
256
256
|
result = e
|
257
257
|
ensure
|
258
|
-
Thread.backend.trace(:fiber_terminate,
|
258
|
+
Thread.backend.trace(:fiber_terminate, Fiber.current, result)
|
259
259
|
suspend
|
260
260
|
end
|
261
|
-
|
261
|
+
prepare_oob_fiber(oob_fiber, block)
|
262
|
+
Thread.backend.trace(:fiber_create, oob_fiber)
|
263
|
+
oob_fiber.schedule_with_priority(nil)
|
264
|
+
end
|
265
|
+
|
266
|
+
def prepare_oob_fiber(fiber, block)
|
267
|
+
fiber.oob = true
|
268
|
+
fiber.tag = :oob
|
269
|
+
fiber.thread = Thread.current
|
262
270
|
location = block.source_location
|
263
|
-
|
264
|
-
Thread.backend.trace(:fiber_create, f)
|
265
|
-
Thread.current.schedule_and_wakeup(f, nil)
|
271
|
+
fiber.set_caller(["#{location.join(':')}"])
|
266
272
|
end
|
267
273
|
end
|
268
274
|
|
data/lib/polyphony/version.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -46,10 +46,11 @@ class MiniTest::Test
|
|
46
46
|
Thread.current.backend.finalize
|
47
47
|
Thread.current.backend = Polyphony::Backend.new
|
48
48
|
sleep 0.001
|
49
|
+
@__stamp = Time.now
|
49
50
|
end
|
50
51
|
|
51
52
|
def teardown
|
52
|
-
# trace "* teardown #{self.name}"
|
53
|
+
# trace "* teardown #{self.name} (#{Time.now - @__stamp}s)"
|
53
54
|
Fiber.current.shutdown_all_children
|
54
55
|
if Fiber.current.children.size > 0
|
55
56
|
puts "Children left after #{self.name}: #{Fiber.current.children.inspect}"
|
data/test/stress.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
count = ARGV[0] ? ARGV[0].to_i : 100
|
4
4
|
test_name = ARGV[1]
|
5
5
|
|
6
|
-
$test_cmd = +'ruby test/run.rb --name
|
6
|
+
$test_cmd = +'ruby test/run.rb --name test_cross_thread_send_receive'
|
7
7
|
if test_name
|
8
8
|
$test_cmd << " --name #{test_name}"
|
9
9
|
end
|
data/test/test_fiber.rb
CHANGED
@@ -923,18 +923,20 @@ class MailboxTest < MiniTest::Test
|
|
923
923
|
def test_cross_thread_send_receive
|
924
924
|
ping_receive_buffer = []
|
925
925
|
pong_receive_buffer = []
|
926
|
+
master = Fiber.current
|
926
927
|
|
927
928
|
pong = Thread.new do
|
928
|
-
|
929
|
-
|
929
|
+
master << :pong_ready
|
930
|
+
3.times do
|
930
931
|
peer, data = receive
|
931
932
|
pong_receive_buffer << data
|
932
933
|
peer << 'pong'
|
933
934
|
end
|
934
935
|
end
|
935
936
|
|
937
|
+
assert_equal :pong_ready, receive
|
938
|
+
|
936
939
|
ping = Thread.new do
|
937
|
-
sleep 0.05
|
938
940
|
3.times do
|
939
941
|
pong << [Fiber.current, 'ping']
|
940
942
|
data = receive
|
@@ -943,7 +945,7 @@ class MailboxTest < MiniTest::Test
|
|
943
945
|
end
|
944
946
|
|
945
947
|
ping.join
|
946
|
-
pong.
|
948
|
+
pong.join
|
947
949
|
ping = pong = nil
|
948
950
|
|
949
951
|
assert_equal %w{pong pong pong}, ping_receive_buffer
|
data/test/test_signal.rb
CHANGED
@@ -3,6 +3,63 @@
|
|
3
3
|
require_relative 'helper'
|
4
4
|
|
5
5
|
class SignalTrapTest < Minitest::Test
|
6
|
+
def test_signal_handler_trace
|
7
|
+
i1, o1 = IO.pipe
|
8
|
+
i2, o2 = IO.pipe
|
9
|
+
pid = Process.pid
|
10
|
+
child_pid = Polyphony.fork do
|
11
|
+
i1.gets
|
12
|
+
Process.kill('SIGINT', pid)
|
13
|
+
sleep 0.1
|
14
|
+
o2.puts "done"
|
15
|
+
o2.close
|
16
|
+
end
|
17
|
+
|
18
|
+
events = []
|
19
|
+
begin
|
20
|
+
Thread.backend.trace_proc = proc { |*e| events << [e[0], e[1].tag] }
|
21
|
+
trap ('SIGINT') { }
|
22
|
+
|
23
|
+
o1.orig_write("\n")
|
24
|
+
o1.close
|
25
|
+
|
26
|
+
msg = i2.gets
|
27
|
+
assert_equal "done\n", msg
|
28
|
+
ensure
|
29
|
+
Thread.backend.trace_proc = nil
|
30
|
+
trap ('SIGINT') { raise Interrupt }
|
31
|
+
end
|
32
|
+
|
33
|
+
Fiber.current.tag = :main
|
34
|
+
|
35
|
+
expected = [
|
36
|
+
[:fiber_switchpoint, :main],
|
37
|
+
[:fiber_event_poll_enter, :main],
|
38
|
+
[:fiber_create, :oob],
|
39
|
+
[:fiber_schedule, :oob],
|
40
|
+
[:fiber_event_poll_leave, :main],
|
41
|
+
[:fiber_run, :oob],
|
42
|
+
[:fiber_terminate, :oob],
|
43
|
+
[:fiber_switchpoint, :oob],
|
44
|
+
[:fiber_event_poll_enter, :oob],
|
45
|
+
[:fiber_schedule, :main],
|
46
|
+
[:fiber_event_poll_leave, :oob],
|
47
|
+
[:fiber_run, :main]
|
48
|
+
]
|
49
|
+
if Thread.backend.kind == :libev
|
50
|
+
expected += [
|
51
|
+
[:fiber_schedule, :main],
|
52
|
+
[:fiber_switchpoint, :main],
|
53
|
+
[:fiber_run, :main]
|
54
|
+
]
|
55
|
+
end
|
56
|
+
|
57
|
+
assert_equal expected, events
|
58
|
+
ensure
|
59
|
+
Process.kill('SIGTERM', child_pid) rescue nil
|
60
|
+
Process.wait(child_pid) rescue nil
|
61
|
+
end
|
62
|
+
|
6
63
|
def test_int_signal
|
7
64
|
Thread.new { sleep 0.001; Process.kill('INT', Process.pid) }
|
8
65
|
assert_raises(Interrupt) { sleep 5 }
|
data/test/test_timer.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: polyphony
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.77'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-02-
|
11
|
+
date: 2022-02-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -245,6 +245,8 @@ files:
|
|
245
245
|
- examples/core/thread_pool.rb
|
246
246
|
- examples/core/throttling.rb
|
247
247
|
- examples/core/timeout.rb
|
248
|
+
- examples/core/trap1.rb
|
249
|
+
- examples/core/trap2.rb
|
248
250
|
- examples/core/using-a-mutex.rb
|
249
251
|
- examples/core/worker-thread.rb
|
250
252
|
- examples/io/backticks.rb
|
@@ -346,6 +348,7 @@ files:
|
|
346
348
|
- ext/polyphony/runqueue_ring_buffer.h
|
347
349
|
- ext/polyphony/socket_extensions.c
|
348
350
|
- ext/polyphony/thread.c
|
351
|
+
- ext/test_eintr.c
|
349
352
|
- lib/polyphony.rb
|
350
353
|
- lib/polyphony/adapters/fs.rb
|
351
354
|
- lib/polyphony/adapters/irb.rb
|