uringmachine 0.4 → 0.5.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/.github/workflows/test.yml +2 -1
- data/CHANGELOG.md +16 -0
- data/README.md +44 -1
- data/TODO.md +12 -3
- data/examples/bm_snooze.rb +89 -0
- data/examples/bm_sqlite.rb +89 -0
- data/examples/bm_write.rb +56 -0
- data/examples/dns_client.rb +12 -0
- data/examples/http_server.rb +42 -43
- data/examples/pg.rb +85 -0
- data/examples/server_client.rb +64 -0
- data/examples/snooze.rb +44 -0
- data/examples/stream.rb +85 -0
- data/examples/write_dev_null.rb +16 -0
- data/ext/um/extconf.rb +81 -14
- data/ext/um/um.c +468 -414
- data/ext/um/um.h +149 -40
- data/ext/um/um_async_op.c +40 -0
- data/ext/um/um_async_op_class.c +136 -0
- data/ext/um/um_buffer.c +49 -0
- data/ext/um/um_class.c +176 -44
- data/ext/um/um_const.c +174 -9
- data/ext/um/um_ext.c +8 -0
- data/ext/um/um_mutex_class.c +47 -0
- data/ext/um/um_op.c +89 -111
- data/ext/um/um_queue_class.c +58 -0
- data/ext/um/um_ssl.c +850 -0
- data/ext/um/um_ssl.h +22 -0
- data/ext/um/um_ssl_class.c +138 -0
- data/ext/um/um_sync.c +273 -0
- data/ext/um/um_utils.c +1 -1
- data/lib/uringmachine/dns_resolver.rb +84 -0
- data/lib/uringmachine/ssl/context_builder.rb +96 -0
- data/lib/uringmachine/ssl.rb +394 -0
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +27 -3
- data/supressions/ruby.supp +71 -0
- data/test/helper.rb +6 -0
- data/test/test_async_op.rb +119 -0
- data/test/test_ssl.rb +155 -0
- data/test/test_um.rb +464 -47
- data/uringmachine.gemspec +3 -2
- data/vendor/liburing/.gitignore +5 -0
- data/vendor/liburing/CHANGELOG +1 -0
- data/vendor/liburing/configure +32 -0
- data/vendor/liburing/examples/Makefile +1 -0
- data/vendor/liburing/examples/reg-wait.c +159 -0
- data/vendor/liburing/liburing.spec +1 -1
- data/vendor/liburing/src/include/liburing/io_uring.h +48 -2
- data/vendor/liburing/src/include/liburing.h +28 -2
- data/vendor/liburing/src/int_flags.h +10 -3
- data/vendor/liburing/src/liburing-ffi.map +13 -2
- data/vendor/liburing/src/liburing.map +9 -0
- data/vendor/liburing/src/queue.c +25 -16
- data/vendor/liburing/src/register.c +73 -4
- data/vendor/liburing/src/setup.c +46 -18
- data/vendor/liburing/src/setup.h +6 -0
- data/vendor/liburing/test/Makefile +7 -0
- data/vendor/liburing/test/cmd-discard.c +427 -0
- data/vendor/liburing/test/fifo-nonblock-read.c +69 -0
- data/vendor/liburing/test/file-exit-unreg.c +48 -0
- data/vendor/liburing/test/io_uring_passthrough.c +2 -0
- data/vendor/liburing/test/io_uring_register.c +13 -2
- data/vendor/liburing/test/napi-test.c +1 -1
- data/vendor/liburing/test/no-mmap-inval.c +1 -1
- data/vendor/liburing/test/read-mshot-empty.c +2 -0
- data/vendor/liburing/test/read-mshot-stdin.c +121 -0
- data/vendor/liburing/test/read-mshot.c +6 -0
- data/vendor/liburing/test/recvsend_bundle.c +2 -2
- data/vendor/liburing/test/reg-fd-only.c +1 -1
- data/vendor/liburing/test/reg-wait.c +251 -0
- data/vendor/liburing/test/regbuf-clone.c +458 -0
- data/vendor/liburing/test/resize-rings.c +643 -0
- data/vendor/liburing/test/rsrc_tags.c +1 -1
- data/vendor/liburing/test/sqpoll-sleep.c +39 -8
- data/vendor/liburing/test/sqwait.c +136 -0
- data/vendor/liburing/test/sync-cancel.c +8 -1
- data/vendor/liburing/test/timeout.c +13 -8
- metadata +52 -8
- data/examples/http_server_multishot.rb +0 -57
- data/examples/http_server_simpler.rb +0 -34
data/examples/stream.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../lib/uringmachine'
|
4
|
+
|
5
|
+
@machine = UM.new
|
6
|
+
|
7
|
+
class UM::Stream
|
8
|
+
def initialize(machine, fd)
|
9
|
+
@machine, @fd, @bgid = machine, fd
|
10
|
+
@buffer = +''
|
11
|
+
@ofs_head = 0
|
12
|
+
@ofs_tail = 0
|
13
|
+
end
|
14
|
+
|
15
|
+
def feed
|
16
|
+
if (@ofs_head == @ofs_tail) && (@ofs_head >= 4096)
|
17
|
+
@buffer = +''
|
18
|
+
@ofs_head = @ofs_tail = 0
|
19
|
+
end
|
20
|
+
ret = @machine.read(@fd, @buffer, 65536, @ofs_tail)
|
21
|
+
if ret == 0
|
22
|
+
@eof = true
|
23
|
+
return false
|
24
|
+
end
|
25
|
+
|
26
|
+
@ofs_tail += ret
|
27
|
+
true
|
28
|
+
end
|
29
|
+
|
30
|
+
def read(len)
|
31
|
+
if @ofs_head + len > @ofs_tail
|
32
|
+
feed
|
33
|
+
end
|
34
|
+
|
35
|
+
str = @buffer[@ofs_head, len]
|
36
|
+
@ofs_head += str.bytesize
|
37
|
+
str
|
38
|
+
end
|
39
|
+
|
40
|
+
def gets(sep = $/, _limit = nil, _chomp: nil)
|
41
|
+
if sep.is_a?(Integer)
|
42
|
+
sep = $/
|
43
|
+
_limit = sep
|
44
|
+
end
|
45
|
+
sep_size = sep.bytesize
|
46
|
+
|
47
|
+
while true
|
48
|
+
idx = @buffer.index(sep, @ofs_head)
|
49
|
+
if idx
|
50
|
+
str = @buffer[@ofs_head, idx + sep_size]
|
51
|
+
@ofs_head += str.bytesize
|
52
|
+
return str
|
53
|
+
end
|
54
|
+
|
55
|
+
return nil if !feed
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
$machine = UringMachine.new
|
61
|
+
|
62
|
+
server_fd = @machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0)
|
63
|
+
$machine.setsockopt(server_fd, UM::SOL_SOCKET, UM::SO_REUSEADDR, true)
|
64
|
+
$machine.bind(server_fd, '127.0.0.1', 1234)
|
65
|
+
$machine.listen(server_fd, UM::SOMAXCONN)
|
66
|
+
puts 'Listening on port 1234'
|
67
|
+
|
68
|
+
def handle_connection(fd)
|
69
|
+
stream = UM::Stream.new($machine, fd)
|
70
|
+
|
71
|
+
while (l = stream.gets)
|
72
|
+
$machine.write(fd, "You said: #{l}")
|
73
|
+
end
|
74
|
+
rescue Exception => e
|
75
|
+
puts "Got error #{e.inspect}, closing connection"
|
76
|
+
$machine.close(fd) rescue nil
|
77
|
+
end
|
78
|
+
|
79
|
+
main = Fiber.current
|
80
|
+
trap('SIGINT') { $machine.spin { $machine.schedule(main, SystemExit.new) } }
|
81
|
+
|
82
|
+
$machine.accept_each(server_fd) do |fd|
|
83
|
+
puts "Connection accepted fd #{fd}"
|
84
|
+
$machine.spin(fd) { handle_connection(_1) }
|
85
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../lib/uringmachine'
|
4
|
+
|
5
|
+
ITERATIONS = 1000
|
6
|
+
DEV_NULL = File.open('/dev/null', 'w')
|
7
|
+
FD = DEV_NULL.fileno
|
8
|
+
BUF = ('*' * 8192).freeze
|
9
|
+
|
10
|
+
$machine = UringMachine.new
|
11
|
+
|
12
|
+
def run_um_write
|
13
|
+
$machine.write(FD, BUF)
|
14
|
+
end
|
15
|
+
|
16
|
+
1000.times { run_um_write }
|
data/ext/um/extconf.rb
CHANGED
@@ -6,10 +6,66 @@ 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
|
+
|
9
64
|
KERNEL_INFO_RE = /Linux (\d)\.(\d+)(?:\.)?((?:\d+\.?)*)(?:\-)?([\w\-]+)?/
|
10
65
|
def get_config
|
11
|
-
|
12
|
-
|
66
|
+
if RUBY_PLATFORM !~ /linux/
|
67
|
+
raise "UringMachine only works on Linux!"
|
68
|
+
end
|
13
69
|
|
14
70
|
kernel_info = `uname -sr`
|
15
71
|
m = kernel_info.match(KERNEL_INFO_RE)
|
@@ -20,16 +76,22 @@ def get_config
|
|
20
76
|
combined_version = version.to_i * 100 + major_revision.to_i
|
21
77
|
raise "UringMachine requires kernel version 6.4 or newer!" if combined_version < 604
|
22
78
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
79
|
+
{
|
80
|
+
kernel_version: combined_version,
|
81
|
+
submit_all_flag: combined_version >= 518,
|
82
|
+
coop_taskrun_flag: combined_version >= 519,
|
83
|
+
single_issuer_flag: combined_version >= 600,
|
84
|
+
prep_bind: combined_version >= 611,
|
85
|
+
prep_listen: combined_version >= 611,
|
86
|
+
prep_cmd_sock: combined_version >= 607,
|
87
|
+
prep_futex: combined_version >= 607,
|
88
|
+
prep_waitid: combined_version >= 607,
|
89
|
+
prep_read_multishot: combined_version >= 607
|
90
|
+
}
|
31
91
|
end
|
32
92
|
|
93
|
+
config_ssl
|
94
|
+
|
33
95
|
config = get_config
|
34
96
|
puts "Building UringMachine (\n#{config.map { |(k, v)| " #{k}: #{v}\n"}.join})"
|
35
97
|
|
@@ -51,10 +113,15 @@ if !find_library('uring', nil, File.join(liburing_path, 'src'))
|
|
51
113
|
raise "Couldn't find liburing.a"
|
52
114
|
end
|
53
115
|
|
54
|
-
$defs <<
|
55
|
-
$defs << '-
|
56
|
-
$defs << '-
|
57
|
-
$defs << '-
|
116
|
+
$defs << "-DUM_KERNEL_VERSION=#{config[:kernel_version]}"
|
117
|
+
$defs << '-DHAVE_IORING_SETUP_SUBMIT_ALL' if config[:submit_all_flag]
|
118
|
+
$defs << '-DHAVE_IORING_SETUP_COOP_TASKRUN' if config[:coop_taskrun_flag]
|
119
|
+
$defs << '-DHAVE_IO_URING_PREP_BIND' if config[:prep_bind]
|
120
|
+
$defs << '-DHAVE_IO_URING_PREP_LISTEN' if config[:prep_listen]
|
121
|
+
$defs << '-DHAVE_IO_URING_PREP_CMD_SOCK' if config[:prep_cmd_sock]
|
122
|
+
$defs << '-DHAVE_IO_URING_PREP_FUTEX' if config[:prep_futex]
|
123
|
+
$defs << '-DHAVE_IO_URING_PREP_WAITID' if config[:prep_waitid]
|
124
|
+
$defs << '-DHAVE_IO_URING_PREP_READ_MULTISHOT' if config[:prep_read_multishot]
|
58
125
|
$CFLAGS << ' -Wno-pointer-arith'
|
59
126
|
|
60
127
|
CONFIG['optflags'] << ' -fno-strict-aliasing'
|