uringmachine 0.6.1 → 0.8
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/.github/workflows/test.yml +1 -1
- data/CHANGELOG.md +8 -0
- data/TODO.md +8 -1
- data/ext/um/extconf.rb +0 -57
- data/ext/um/um.c +16 -0
- data/ext/um/um.h +2 -2
- data/ext/um/um_class.c +7 -2
- data/lib/uringmachine/actor.rb +19 -10
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +64 -9
- data/test/test_actor.rb +8 -6
- data/test/test_fiber.rb +171 -0
- data/test/test_um.rb +73 -1
- data/uringmachine.gemspec +1 -1
- metadata +5 -10
- data/ext/um/um_ssl.c +0 -850
- data/ext/um/um_ssl.h +0 -22
- data/ext/um/um_ssl_class.c +0 -138
- data/lib/uringmachine/ssl/context_builder.rb +0 -96
- data/lib/uringmachine/ssl.rb +0 -394
- data/test/test_ssl.rb +0 -155
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c901aae24c3fad58a2453333885d10c577448c910c069753188cf8a89b6a1f2e
|
4
|
+
data.tar.gz: '0804b7103ccf9ae6c244ef5a9677987af2944e508b63d98aeee5f19dee0f1f2e'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3a6934132fad56b013a8754c375b33acd2cefc28577879b7e05bbf0ded8e9b9cd8e50070ec398d67c00c07ebb15468347e96d27d6ba2ccdbfbc19b5a206aff6c
|
7
|
+
data.tar.gz: 9c54ade5eada0ce6238f6138f8be9c5857436668851154ead8a55b8d221d2f4f3d2318616d1fdc733e99562748c17b26eca7e171cf43ddeb34a80320df2e2b43
|
data/.github/workflows/test.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/TODO.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# ops
|
2
|
+
|
1
3
|
- [ ] multishot timeout
|
2
4
|
- [v] machine.periodically(interval) { ... }
|
3
5
|
- [ ] machine.prep_timeout_multishot(interval)
|
@@ -14,5 +16,10 @@
|
|
14
16
|
- fadvise
|
15
17
|
- madvise
|
16
18
|
- getxattr / setxattr
|
17
|
-
- shutdown
|
18
19
|
- send_bundle / recv_bundle (kernel >= 6.10)
|
20
|
+
|
21
|
+
# actors
|
22
|
+
|
23
|
+
When doing a `call`, we need to provide a mailbox for the response. can this be
|
24
|
+
automatic?
|
25
|
+
|
data/ext/um/extconf.rb
CHANGED
@@ -6,61 +6,6 @@ require 'rbconfig'
|
|
6
6
|
|
7
7
|
dir_config 'um_ext'
|
8
8
|
|
9
|
-
def config_ssl
|
10
|
-
# don't use pkg_config('openssl') if '--with-openssl-dir' is used
|
11
|
-
has_openssl_dir = dir_config('openssl').any? ||
|
12
|
-
RbConfig::CONFIG['configure_args']&.include?('openssl')
|
13
|
-
|
14
|
-
found_pkg_config = !has_openssl_dir && pkg_config('openssl')
|
15
|
-
|
16
|
-
found_ssl = if !$mingw && found_pkg_config
|
17
|
-
puts '──── Using OpenSSL pkgconfig (openssl.pc) ────'
|
18
|
-
true
|
19
|
-
elsif have_library('libcrypto', 'BIO_read') && have_library('libssl', 'SSL_CTX_new')
|
20
|
-
true
|
21
|
-
elsif %w'crypto libeay32'.find {|crypto| have_library(crypto, 'BIO_read')} &&
|
22
|
-
%w'ssl ssleay32'.find {|ssl| have_library(ssl, 'SSL_CTX_new')}
|
23
|
-
true
|
24
|
-
else
|
25
|
-
puts '** Puma will be compiled without SSL support'
|
26
|
-
false
|
27
|
-
end
|
28
|
-
|
29
|
-
if found_ssl
|
30
|
-
have_header "openssl/bio.h"
|
31
|
-
|
32
|
-
ssl_h = "openssl/ssl.h".freeze
|
33
|
-
|
34
|
-
puts "\n──── Below are yes for 1.0.2 & later ────"
|
35
|
-
have_func "DTLS_method" , ssl_h
|
36
|
-
have_func "SSL_CTX_set_session_cache_mode(NULL, 0)", ssl_h
|
37
|
-
|
38
|
-
puts "\n──── Below are yes for 1.1.0 & later ────"
|
39
|
-
have_func "TLS_server_method" , ssl_h
|
40
|
-
have_func "SSL_CTX_set_min_proto_version(NULL, 0)" , ssl_h
|
41
|
-
|
42
|
-
puts "\n──── Below is yes for 1.1.0 and later, but isn't documented until 3.0.0 ────"
|
43
|
-
# https://github.com/openssl/openssl/blob/OpenSSL_1_1_0/include/openssl/ssl.h#L1159
|
44
|
-
have_func "SSL_CTX_set_dh_auto(NULL, 0)" , ssl_h
|
45
|
-
|
46
|
-
puts "\n──── Below is yes for 1.1.1 & later ────"
|
47
|
-
have_func "SSL_CTX_set_ciphersuites(NULL, \"\")" , ssl_h
|
48
|
-
|
49
|
-
puts "\n──── Below is yes for 3.0.0 & later ────"
|
50
|
-
have_func "SSL_get1_peer_certificate" , ssl_h
|
51
|
-
|
52
|
-
puts ''
|
53
|
-
|
54
|
-
# Random.bytes available in Ruby 2.5 and later, Random::DEFAULT deprecated in 3.0
|
55
|
-
if Random.respond_to?(:bytes)
|
56
|
-
$defs.push "-DHAVE_RANDOM_BYTES"
|
57
|
-
puts "checking for Random.bytes... yes"
|
58
|
-
else
|
59
|
-
puts "checking for Random.bytes... no"
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
9
|
KERNEL_INFO_RE = /Linux (\d)\.(\d+)(?:\.)?((?:\d+\.?)*)(?:\-)?([\w\-]+)?/
|
65
10
|
def get_config
|
66
11
|
if RUBY_PLATFORM !~ /linux/
|
@@ -90,8 +35,6 @@ def get_config
|
|
90
35
|
}
|
91
36
|
end
|
92
37
|
|
93
|
-
# config_ssl
|
94
|
-
|
95
38
|
config = get_config
|
96
39
|
puts "Building UringMachine (\n#{config.map { |(k, v)| " #{k}: #{v}\n"}.join})"
|
97
40
|
|
data/ext/um/um.c
CHANGED
@@ -549,6 +549,22 @@ VALUE um_setsockopt(struct um *machine, int fd, int level, int opt, int value) {
|
|
549
549
|
return raise_if_exception(ret);
|
550
550
|
}
|
551
551
|
|
552
|
+
VALUE um_shutdown(struct um *machine, int fd, int how) {
|
553
|
+
VALUE ret = Qnil;
|
554
|
+
|
555
|
+
struct um_op op;
|
556
|
+
um_prep_op(machine, &op, OP_SHUTDOWN);
|
557
|
+
struct io_uring_sqe *sqe = um_get_sqe(machine, &op);
|
558
|
+
io_uring_prep_shutdown(sqe, fd, how);
|
559
|
+
|
560
|
+
ret = um_fiber_switch(machine);
|
561
|
+
if (um_check_completion(machine, &op))
|
562
|
+
ret = INT2NUM(op.result.res);
|
563
|
+
|
564
|
+
RB_GC_GUARD(ret);
|
565
|
+
return raise_if_exception(ret);
|
566
|
+
}
|
567
|
+
|
552
568
|
VALUE um_open(struct um *machine, VALUE pathname, int flags, int mode) {
|
553
569
|
struct um_op op;
|
554
570
|
um_prep_op(machine, &op, OP_BIND);
|
data/ext/um/um.h
CHANGED
@@ -37,6 +37,7 @@ enum op_kind {
|
|
37
37
|
OP_LISTEN,
|
38
38
|
OP_GETSOCKOPT,
|
39
39
|
OP_SETSOCKOPT,
|
40
|
+
OP_SHUTDOWN,
|
40
41
|
|
41
42
|
OP_FUTEX_WAIT,
|
42
43
|
OP_FUTEX_WAKE,
|
@@ -220,6 +221,7 @@ VALUE um_bind(struct um *machine, int fd, struct sockaddr *addr, socklen_t addrl
|
|
220
221
|
VALUE um_listen(struct um *machine, int fd, int backlog);
|
221
222
|
VALUE um_getsockopt(struct um *machine, int fd, int level, int opt);
|
222
223
|
VALUE um_setsockopt(struct um *machine, int fd, int level, int opt, int value);
|
224
|
+
VALUE um_shutdown(struct um *machine, int fd, int how);
|
223
225
|
|
224
226
|
void um_async_op_set(VALUE self, struct um *machine, struct um_op *op);
|
225
227
|
VALUE um_async_op_await(struct um_async_op *async_op);
|
@@ -244,6 +246,4 @@ VALUE um_queue_shift(struct um *machine, struct um_queue *queue);
|
|
244
246
|
|
245
247
|
void um_define_net_constants(VALUE mod);
|
246
248
|
|
247
|
-
// void Init_micro_ssl(VALUE mod);
|
248
|
-
|
249
249
|
#endif // UM_H
|
data/ext/um/um_class.c
CHANGED
@@ -150,6 +150,12 @@ VALUE UM_socket(VALUE self, VALUE domain, VALUE type, VALUE protocol, VALUE flag
|
|
150
150
|
return um_socket(machine, NUM2INT(domain), NUM2INT(type), NUM2INT(protocol), NUM2UINT(flags));
|
151
151
|
}
|
152
152
|
|
153
|
+
VALUE UM_shutdown(VALUE self, VALUE fd, VALUE how) {
|
154
|
+
struct um *machine = um_get_machine(self);
|
155
|
+
return um_shutdown(machine, NUM2INT(fd), NUM2INT(how));
|
156
|
+
|
157
|
+
}
|
158
|
+
|
153
159
|
VALUE UM_connect(VALUE self, VALUE fd, VALUE host, VALUE port) {
|
154
160
|
struct um *machine = um_get_machine(self);
|
155
161
|
|
@@ -350,6 +356,7 @@ void Init_UM(void) {
|
|
350
356
|
rb_define_method(cUM, "send", UM_send, 4);
|
351
357
|
rb_define_method(cUM, "setsockopt", UM_setsockopt, 4);
|
352
358
|
rb_define_method(cUM, "socket", UM_socket, 4);
|
359
|
+
rb_define_method(cUM, "shutdown", UM_shutdown, 2);
|
353
360
|
|
354
361
|
rb_define_method(cUM, "prep_timeout", UM_prep_timeout, 1);
|
355
362
|
|
@@ -361,7 +368,5 @@ void Init_UM(void) {
|
|
361
368
|
rb_define_method(cUM, "unshift", UM_queue_unshift, 2);
|
362
369
|
#endif
|
363
370
|
|
364
|
-
// Init_micro_ssl(cUM);
|
365
|
-
|
366
371
|
um_define_net_constants(cUM);
|
367
372
|
}
|
data/lib/uringmachine/actor.rb
CHANGED
@@ -10,6 +10,19 @@ class UringMachine
|
|
10
10
|
actor
|
11
11
|
end
|
12
12
|
|
13
|
+
def spin_thread_actor(mod, *a, **k)
|
14
|
+
machine = UM.new
|
15
|
+
target = Object.new.extend(mod)
|
16
|
+
mailbox = UM::Queue.new
|
17
|
+
actor = Actor.new
|
18
|
+
thread = Thread.new do
|
19
|
+
actor.run(machine, target, mailbox)
|
20
|
+
end
|
21
|
+
target.setup(*a, **k)
|
22
|
+
snooze
|
23
|
+
actor
|
24
|
+
end
|
25
|
+
|
13
26
|
class Actor < Fiber
|
14
27
|
def run(machine, target, mailbox)
|
15
28
|
@machine = machine
|
@@ -23,30 +36,26 @@ class UringMachine
|
|
23
36
|
end
|
24
37
|
|
25
38
|
def cast(sym, *a, **k)
|
26
|
-
|
39
|
+
@machine.push @mailbox, [:cast, nil, sym, a, k]
|
27
40
|
self
|
28
41
|
end
|
29
42
|
|
30
|
-
def call(sym, *a, **k)
|
31
|
-
|
32
|
-
@machine.
|
43
|
+
def call(response_mailbox, sym, *a, **k)
|
44
|
+
@machine.push @mailbox, [:call, response_mailbox, sym, a, k]
|
45
|
+
@machine.shift response_mailbox
|
33
46
|
end
|
34
47
|
|
35
48
|
private
|
36
49
|
|
37
50
|
def process_message(msg)
|
38
|
-
type,
|
51
|
+
type, response_mailbox, sym, args, kwargs = msg
|
39
52
|
case type
|
40
53
|
when :cast
|
41
54
|
@target.send(sym, *args, **kwargs)
|
42
55
|
when :call
|
43
56
|
res = @target.send(sym, *args, **kwargs)
|
44
|
-
@machine.
|
57
|
+
@machine.push(response_mailbox, res)
|
45
58
|
end
|
46
59
|
end
|
47
|
-
|
48
|
-
def <<(msg)
|
49
|
-
@machine.push(@mailbox, msg)
|
50
|
-
end
|
51
60
|
end
|
52
61
|
end
|
data/lib/uringmachine/version.rb
CHANGED
data/lib/uringmachine.rb
CHANGED
@@ -12,30 +12,85 @@ class UringMachine
|
|
12
12
|
@@fiber_map
|
13
13
|
end
|
14
14
|
|
15
|
+
class Terminate < Exception
|
16
|
+
end
|
17
|
+
|
15
18
|
def spin(value = nil, fiber_class = Fiber, &block)
|
16
19
|
f = fiber_class.new do |resume_value|
|
17
|
-
block.(resume_value)
|
20
|
+
f.set_result block.(resume_value)
|
18
21
|
rescue Exception => e
|
19
|
-
|
20
|
-
STDERR.puts e.backtrace.join("\n")
|
21
|
-
exit
|
22
|
+
f.set_result e
|
22
23
|
ensure
|
24
|
+
f.mark_as_done
|
25
|
+
# cleanup
|
23
26
|
@@fiber_map.delete(f)
|
24
|
-
|
27
|
+
self.notify_done_listeners(f)
|
28
|
+
# transfer control to other fibers
|
25
29
|
self.yield
|
26
|
-
p :bad_bad_bad
|
27
30
|
end
|
28
|
-
schedule(f, value)
|
31
|
+
self.schedule(f, value)
|
29
32
|
@@fiber_map[f] = true
|
30
33
|
f
|
31
34
|
end
|
32
35
|
|
36
|
+
def join(*fibers)
|
37
|
+
results = fibers.inject({}) { |h, f| h[f] = nil; h }
|
38
|
+
queue = nil
|
39
|
+
pending = nil
|
40
|
+
fibers.each do |f|
|
41
|
+
if f.done?
|
42
|
+
results[f] = f.result
|
43
|
+
else
|
44
|
+
(pending ||= []) << f
|
45
|
+
queue ||= UM::Queue.new
|
46
|
+
f.add_done_listener(queue)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
return results.values if !pending
|
50
|
+
|
51
|
+
while !pending.empty?
|
52
|
+
f = self.shift(queue)
|
53
|
+
pending.delete(f)
|
54
|
+
results[f] = f.result
|
55
|
+
end
|
56
|
+
results.values
|
57
|
+
end
|
58
|
+
|
33
59
|
def resolve(hostname, type = :A)
|
34
60
|
@resolver ||= DNSResolver.new(self)
|
35
61
|
@resolver.resolve(hostname, type)
|
36
62
|
end
|
37
63
|
|
38
|
-
|
39
|
-
|
64
|
+
private
|
65
|
+
|
66
|
+
def notify_done_listeners(fiber)
|
67
|
+
listeners = fiber.done_listeners
|
68
|
+
return if !listeners
|
69
|
+
|
70
|
+
listeners.each { self.push(it, fiber) }
|
71
|
+
end
|
72
|
+
|
73
|
+
module FiberExtensions
|
74
|
+
attr_reader :result, :done, :done_listeners
|
75
|
+
|
76
|
+
def mark_as_done
|
77
|
+
@done = true
|
78
|
+
end
|
79
|
+
|
80
|
+
def set_result(value)
|
81
|
+
@result = value
|
82
|
+
end
|
83
|
+
|
84
|
+
def done?
|
85
|
+
@done
|
86
|
+
end
|
87
|
+
|
88
|
+
def add_done_listener(queue)
|
89
|
+
(@done_listeners ||= []) << queue
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class ::Fiber
|
94
|
+
include UringMachine::FiberExtensions
|
40
95
|
end
|
41
96
|
end
|
data/test/test_actor.rb
CHANGED
@@ -7,7 +7,7 @@ require 'uringmachine/actor'
|
|
7
7
|
class ActorTest < UMBaseTest
|
8
8
|
module Counter
|
9
9
|
def setup
|
10
|
-
@count = 0
|
10
|
+
@count = 0
|
11
11
|
end
|
12
12
|
|
13
13
|
def incr
|
@@ -24,16 +24,17 @@ class ActorTest < UMBaseTest
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def test_basic_actor_functionality
|
27
|
+
mailbox = UM::Queue.new
|
27
28
|
actor = @machine.spin_actor(Counter)
|
28
29
|
|
29
30
|
assert_kind_of Fiber, actor
|
30
31
|
|
31
|
-
assert_equal 0, actor.call(:get)
|
32
|
-
assert_equal 1, actor.call(:incr)
|
32
|
+
assert_equal 0, actor.call(mailbox, :get)
|
33
|
+
assert_equal 1, actor.call(mailbox, :incr)
|
33
34
|
assert_equal actor, actor.cast(:incr)
|
34
|
-
assert_equal 2, actor.call(:get)
|
35
|
+
assert_equal 2, actor.call(mailbox, :get)
|
35
36
|
assert_equal actor, actor.cast(:reset)
|
36
|
-
assert_equal 0, actor.call(:get)
|
37
|
+
assert_equal 0, actor.call(mailbox, :get)
|
37
38
|
end
|
38
39
|
|
39
40
|
module Counter2
|
@@ -57,7 +58,8 @@ class ActorTest < UMBaseTest
|
|
57
58
|
|
58
59
|
def test_actor_with_args
|
59
60
|
actor = @machine.spin_actor(Counter2, 43)
|
61
|
+
mailbox = UM::Queue.new
|
60
62
|
|
61
|
-
assert_equal 43, actor.call(:get)
|
63
|
+
assert_equal 43, actor.call(mailbox, :get)
|
62
64
|
end
|
63
65
|
end
|
data/test/test_fiber.rb
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'helper'
|
4
|
+
require 'socket'
|
5
|
+
|
6
|
+
class FiberSpinTest < UMBaseTest
|
7
|
+
def test_spin
|
8
|
+
x = nil
|
9
|
+
f = machine.spin do
|
10
|
+
x = :foo
|
11
|
+
end
|
12
|
+
|
13
|
+
assert_kind_of Fiber, f
|
14
|
+
assert_nil x
|
15
|
+
|
16
|
+
machine.snooze
|
17
|
+
|
18
|
+
assert_equal :foo, x
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_spin_with_initial_value
|
22
|
+
x = nil
|
23
|
+
f = machine.spin(42) do |v|
|
24
|
+
x = v
|
25
|
+
end
|
26
|
+
|
27
|
+
assert_kind_of Fiber, f
|
28
|
+
assert_nil x
|
29
|
+
|
30
|
+
machine.snooze
|
31
|
+
assert_equal 42, x
|
32
|
+
end
|
33
|
+
|
34
|
+
class MyFiber < Fiber
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_spin_with_custom_class
|
38
|
+
f = machine.spin(nil, MyFiber) do
|
39
|
+
end
|
40
|
+
|
41
|
+
assert_kind_of MyFiber, f
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class FiberTerminateTest < UMBaseTest
|
46
|
+
def test_terminate_fiber
|
47
|
+
x = nil
|
48
|
+
f = machine.spin do
|
49
|
+
x = 1
|
50
|
+
machine.sleep 0.01
|
51
|
+
ensure
|
52
|
+
x = 0
|
53
|
+
end
|
54
|
+
|
55
|
+
assert_nil x
|
56
|
+
machine.snooze
|
57
|
+
assert_equal 1, x
|
58
|
+
|
59
|
+
machine.schedule(f, UM::Terminate.new)
|
60
|
+
2.times { machine.snooze }
|
61
|
+
|
62
|
+
assert_equal 0, x
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class JoinTest < UMBaseTest
|
67
|
+
def test_join
|
68
|
+
q = UM::Queue.new
|
69
|
+
x = nil
|
70
|
+
|
71
|
+
f = machine.spin do
|
72
|
+
x = 1
|
73
|
+
machine.push q, machine.shift(q) + 1
|
74
|
+
42
|
75
|
+
ensure
|
76
|
+
x = 0
|
77
|
+
end
|
78
|
+
|
79
|
+
assert_nil x
|
80
|
+
machine.snooze
|
81
|
+
assert_equal 1, x
|
82
|
+
|
83
|
+
machine.spin do
|
84
|
+
x = 2
|
85
|
+
machine.push q, 2
|
86
|
+
end
|
87
|
+
|
88
|
+
res = machine.join(f)
|
89
|
+
assert_equal 0, x
|
90
|
+
assert_equal 3, machine.shift(q)
|
91
|
+
assert_equal [42], res
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_join_multiple
|
95
|
+
f1 = machine.spin do
|
96
|
+
:foo
|
97
|
+
end
|
98
|
+
|
99
|
+
f2 = machine.spin do
|
100
|
+
machine.sleep(0.001)
|
101
|
+
:bar
|
102
|
+
end
|
103
|
+
|
104
|
+
f3 = machine.spin do
|
105
|
+
:baz
|
106
|
+
end
|
107
|
+
|
108
|
+
res = machine.join(f1, f2, f3)
|
109
|
+
assert_equal [:foo, :bar, :baz], res
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_join_cross_thread
|
113
|
+
q = UM::Queue.new
|
114
|
+
|
115
|
+
t2 = Thread.new do
|
116
|
+
m2 = UM.new
|
117
|
+
f = m2.spin do
|
118
|
+
m2.push(q, f)
|
119
|
+
m2.snooze
|
120
|
+
:foo
|
121
|
+
end
|
122
|
+
m2.join(f)
|
123
|
+
end
|
124
|
+
|
125
|
+
f = machine.shift(q)
|
126
|
+
assert_kind_of Fiber, f
|
127
|
+
res = machine.join(f)
|
128
|
+
assert_equal [:foo], res
|
129
|
+
ensure
|
130
|
+
t2.join
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_join_with_exception
|
134
|
+
f = machine.spin do
|
135
|
+
raise "Foobar"
|
136
|
+
end
|
137
|
+
|
138
|
+
res = machine.join(f)
|
139
|
+
e = res.first
|
140
|
+
assert_kind_of RuntimeError, e
|
141
|
+
assert_equal 'Foobar', e.message
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
class ScopeTest < UMBaseTest
|
146
|
+
def test_scope
|
147
|
+
skip
|
148
|
+
|
149
|
+
x1 = nil
|
150
|
+
x2 = nil
|
151
|
+
|
152
|
+
machine.scope do
|
153
|
+
f1 = machine.spin do
|
154
|
+
x1 = 1
|
155
|
+
machine.sleep 0.01
|
156
|
+
ensure
|
157
|
+
x1 = 0
|
158
|
+
end
|
159
|
+
|
160
|
+
f2 = machine.spin do
|
161
|
+
x2 = 1
|
162
|
+
machine.sleep 0.01
|
163
|
+
ensure
|
164
|
+
x2 = 0
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
assert_equal 0, x1
|
169
|
+
assert_equal 0, x2
|
170
|
+
end
|
171
|
+
end
|
data/test/test_um.rb
CHANGED
@@ -514,7 +514,7 @@ class WriteTest < UMBaseTest
|
|
514
514
|
end
|
515
515
|
end
|
516
516
|
|
517
|
-
class
|
517
|
+
class CloseTest < UMBaseTest
|
518
518
|
def test_close
|
519
519
|
r, w = IO.pipe
|
520
520
|
machine.write(w.fileno, 'foo')
|
@@ -529,6 +529,54 @@ class Closetest < UMBaseTest
|
|
529
529
|
end
|
530
530
|
end
|
531
531
|
|
532
|
+
class ShutdownTest < UMBaseTest
|
533
|
+
def make_socket_pair
|
534
|
+
port = 10000 + rand(30000)
|
535
|
+
server_fd = @machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0)
|
536
|
+
@machine.setsockopt(server_fd, UM::SOL_SOCKET, UM::SO_REUSEADDR, true)
|
537
|
+
@machine.bind(server_fd, '127.0.0.1', port)
|
538
|
+
@machine.listen(server_fd, UM::SOMAXCONN)
|
539
|
+
|
540
|
+
client_conn_fd = @machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0)
|
541
|
+
@machine.connect(client_conn_fd, '127.0.0.1', port)
|
542
|
+
|
543
|
+
server_conn_fd = @machine.accept(server_fd)
|
544
|
+
|
545
|
+
@machine.close(server_fd)
|
546
|
+
[client_conn_fd, server_conn_fd]
|
547
|
+
end
|
548
|
+
|
549
|
+
def test_shutdown
|
550
|
+
c_fd, s_fd = make_socket_pair
|
551
|
+
res = @machine.send(c_fd, 'abc', 3, 0)
|
552
|
+
assert_equal 3, res
|
553
|
+
|
554
|
+
buf = +''
|
555
|
+
res = @machine.recv(s_fd, buf, 256, 0)
|
556
|
+
assert_equal 3, res
|
557
|
+
assert_equal 'abc', buf
|
558
|
+
|
559
|
+
res = @machine.shutdown(c_fd, UM::SHUT_WR)
|
560
|
+
assert_equal 0, res
|
561
|
+
|
562
|
+
assert_raises(Errno::EPIPE) { @machine.send(c_fd, 'abc', 3, 0) }
|
563
|
+
|
564
|
+
res = @machine.shutdown(s_fd, UM::SHUT_RD)
|
565
|
+
assert_equal 0, res
|
566
|
+
|
567
|
+
res = @machine.recv(s_fd, buf, 256, 0)
|
568
|
+
assert_equal 0, res
|
569
|
+
|
570
|
+
res = @machine.shutdown(c_fd, UM::SHUT_RDWR)
|
571
|
+
assert_equal 0, res
|
572
|
+
|
573
|
+
assert_raises(Errno::EINVAL) { @machine.shutdown(c_fd, -9999) }
|
574
|
+
ensure
|
575
|
+
@machine.close(c_fd)
|
576
|
+
@machine.close(s_fd)
|
577
|
+
end
|
578
|
+
end
|
579
|
+
|
532
580
|
class AcceptTest < UMBaseTest
|
533
581
|
def setup
|
534
582
|
super
|
@@ -1028,6 +1076,30 @@ class QueueTest < UMBaseTest
|
|
1028
1076
|
assert_equal :bar, machine.shift(q)
|
1029
1077
|
assert_equal :foo, machine.shift(q)
|
1030
1078
|
end
|
1079
|
+
|
1080
|
+
def test_cross_thread_push_shift
|
1081
|
+
q = UM::Queue.new
|
1082
|
+
|
1083
|
+
t1 = Thread.new {
|
1084
|
+
m = UM.new
|
1085
|
+
3.times { m.push(q, it); m.sleep(0.01) }
|
1086
|
+
}
|
1087
|
+
|
1088
|
+
items = []
|
1089
|
+
|
1090
|
+
t2 = Thread.new {
|
1091
|
+
m = UM.new
|
1092
|
+
3.times {
|
1093
|
+
i = m.pop(q)
|
1094
|
+
items << i
|
1095
|
+
m.sleep(0.01)
|
1096
|
+
}
|
1097
|
+
}
|
1098
|
+
|
1099
|
+
[t1, t2].each(&:join)
|
1100
|
+
|
1101
|
+
assert_equal [0, 1, 2], items
|
1102
|
+
end
|
1031
1103
|
end
|
1032
1104
|
|
1033
1105
|
class OpenTest < UMBaseTest
|
data/uringmachine.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.extra_rdoc_files = ["README.md"]
|
19
19
|
s.extensions = ["ext/um/extconf.rb"]
|
20
20
|
s.require_paths = ["lib"]
|
21
|
-
s.required_ruby_version = '>= 3.
|
21
|
+
s.required_ruby_version = '>= 3.4'
|
22
22
|
|
23
23
|
s.add_development_dependency 'rake-compiler', '1.2.9'
|
24
24
|
s.add_development_dependency 'minitest', '5.25.4'
|