uringmachine 0.5 → 0.6
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 +6 -0
- data/TODO.md +4 -0
- data/examples/bm_http_parse.rb +149 -0
- data/examples/bm_queue.rb +111 -0
- data/examples/bm_sqlite.rb +89 -0
- data/examples/http_server.rb +1 -1
- data/examples/pg.rb +85 -0
- data/examples/stream.rb +85 -0
- data/ext/um/extconf.rb +57 -0
- data/ext/um/um.c +75 -4
- data/ext/um/um.h +29 -7
- data/ext/um/um_async_op.c +40 -0
- data/ext/um/um_async_op_class.c +136 -0
- data/ext/um/um_class.c +45 -31
- data/ext/um/um_const.c +145 -9
- data/ext/um/um_ext.c +4 -0
- data/ext/um/um_op.c +5 -2
- 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/lib/uringmachine/actor.rb +52 -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 +10 -2
- data/test/helper.rb +6 -0
- data/test/test_actor.rb +63 -0
- data/test/test_async_op.rb +119 -0
- data/test/test_ssl.rb +155 -0
- data/test/test_um.rb +71 -2
- data/uringmachine.gemspec +4 -3
- metadata +39 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc849d9467e24fa296a104e5b1caf71907495a3ed9cc68370bc6eb134a474cbf
|
4
|
+
data.tar.gz: 4fcdf5cd6055321f37375094aa11b56696c894d6a2c47ed9f756fb9a40d79753
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d83d7419000bd434bac101d72c6850274a71dd0324bd1732043cbdb08ef659b683e1010dc31093fe7a77e37368698db56592685bf7fe8a2f76ee4cd70cee52f
|
7
|
+
data.tar.gz: dcb79682bbdc20b99bd312aad22145642c4479009250f01f2e0c83f506026218d973b5c6e8b0aecff4e993acbe3998822bccbdf1de7c77a025b7560b5860ca77
|
data/.github/workflows/test.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/TODO.md
CHANGED
@@ -0,0 +1,149 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/inline'
|
4
|
+
|
5
|
+
gemfile do
|
6
|
+
source 'https://rubygems.org'
|
7
|
+
gem 'uringmachine', path: '..'
|
8
|
+
gem 'benchmark-ips'
|
9
|
+
gem 'http_parser.rb'
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'benchmark/ips'
|
13
|
+
require 'uringmachine'
|
14
|
+
require 'http/parser'
|
15
|
+
|
16
|
+
$machine = UM.new
|
17
|
+
|
18
|
+
HTTP_MSG = "GET /foo/bar HTTP/1.1\r\nServer: foobar.com\r\nFoo: bar\r\n\r\n"
|
19
|
+
|
20
|
+
$count = 0
|
21
|
+
|
22
|
+
def parse_http_parser
|
23
|
+
current_fiber = Fiber.current
|
24
|
+
$count += 1
|
25
|
+
r, w = IO.pipe
|
26
|
+
parser = Http::Parser.new
|
27
|
+
$machine.spin do
|
28
|
+
buffer = +''
|
29
|
+
loop do
|
30
|
+
res = $machine.read(r.fileno, buffer, 512)
|
31
|
+
break if res == 0
|
32
|
+
parser << buffer
|
33
|
+
end
|
34
|
+
rescue Exception => e
|
35
|
+
$machine.schedule(current_fiber, e)
|
36
|
+
# puts e.backtrace.join("\n")
|
37
|
+
# exit!
|
38
|
+
end
|
39
|
+
parser.on_message_complete = -> do
|
40
|
+
headers = parser.headers
|
41
|
+
headers['method'] = parser.http_method.downcase
|
42
|
+
headers['path'] = parser.request_url
|
43
|
+
headers['protocol'] = parser.http_version
|
44
|
+
$machine.schedule(current_fiber, headers)
|
45
|
+
end
|
46
|
+
|
47
|
+
$machine.write(w.fileno, HTTP_MSG)
|
48
|
+
$machine.yield
|
49
|
+
ensure
|
50
|
+
$machine.close(r.fileno)
|
51
|
+
$machine.close(w.fileno)
|
52
|
+
end
|
53
|
+
|
54
|
+
require 'stringio'
|
55
|
+
|
56
|
+
RE_REQUEST_LINE = /^([a-z]+)\s+([^\s]+)\s+(http\/[0-9\.]{1,3})/i
|
57
|
+
RE_HEADER_LINE = /^([a-z0-9\-]+)\:\s+(.+)/i
|
58
|
+
|
59
|
+
def get_line(fd, sio, buffer)
|
60
|
+
while true
|
61
|
+
line = sio.gets(chomp: true)
|
62
|
+
return line if line
|
63
|
+
|
64
|
+
res = $machine.read(fd, buffer, 1024, -1)
|
65
|
+
return nil if res == 0
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def get_request_line(fd, sio, buffer)
|
70
|
+
line = get_line(fd, sio, buffer)
|
71
|
+
|
72
|
+
m = line.match(RE_REQUEST_LINE)
|
73
|
+
return nil if !m
|
74
|
+
|
75
|
+
{
|
76
|
+
'method' => m[1].downcase,
|
77
|
+
'path' => m[2],
|
78
|
+
'protocol' => m[3].downcase
|
79
|
+
}
|
80
|
+
end
|
81
|
+
|
82
|
+
def parse_headers(fd)
|
83
|
+
buffer = String.new('', capacity: 4096)
|
84
|
+
sio = StringIO.new(buffer)
|
85
|
+
|
86
|
+
headers = get_request_line(fd, sio, buffer)
|
87
|
+
return nil if !headers
|
88
|
+
|
89
|
+
while true
|
90
|
+
line = get_line(fd, sio, buffer)
|
91
|
+
break if line.empty?
|
92
|
+
|
93
|
+
m = line.match(RE_HEADER_LINE)
|
94
|
+
raise "Invalid header" if !m
|
95
|
+
|
96
|
+
headers[m[1]] = m[2]
|
97
|
+
end
|
98
|
+
|
99
|
+
headers
|
100
|
+
end
|
101
|
+
|
102
|
+
def parse_http_stringio
|
103
|
+
current_fiber = Fiber.current
|
104
|
+
r, w = IO.pipe
|
105
|
+
|
106
|
+
$machine.spin do
|
107
|
+
headers = parse_headers(r.fileno)
|
108
|
+
$machine.schedule(current_fiber, headers)
|
109
|
+
rescue Exception => e
|
110
|
+
p e
|
111
|
+
puts e.backtrace.join("\n")
|
112
|
+
exit!
|
113
|
+
end
|
114
|
+
|
115
|
+
$machine.write(w.fileno, HTTP_MSG)
|
116
|
+
$machine.yield
|
117
|
+
ensure
|
118
|
+
$machine.close(r.fileno)
|
119
|
+
$machine.close(w.fileno)
|
120
|
+
end
|
121
|
+
|
122
|
+
# p parse_http_parser
|
123
|
+
# p parse_http_stringio
|
124
|
+
# exit
|
125
|
+
|
126
|
+
GC.disable
|
127
|
+
|
128
|
+
def alloc_count
|
129
|
+
count0 = ObjectSpace.count_objects[:TOTAL]
|
130
|
+
yield
|
131
|
+
count1 = ObjectSpace.count_objects[:TOTAL]
|
132
|
+
count1 - count0
|
133
|
+
end
|
134
|
+
|
135
|
+
X = 100
|
136
|
+
p(
|
137
|
+
alloc_http_parser: alloc_count { X.times { parse_http_parser } },
|
138
|
+
alloc_stringio: alloc_count { X.times { parse_http_stringio } }
|
139
|
+
)
|
140
|
+
exit
|
141
|
+
|
142
|
+
Benchmark.ips do |x|
|
143
|
+
x.config(:time => 5, :warmup => 3)
|
144
|
+
|
145
|
+
x.report("http_parser") { parse_http_parser }
|
146
|
+
x.report("homegrown") { parse_http_stringio }
|
147
|
+
|
148
|
+
x.compare!
|
149
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/inline'
|
4
|
+
|
5
|
+
gemfile do
|
6
|
+
source 'https://rubygems.org'
|
7
|
+
gem 'uringmachine', path: '..'
|
8
|
+
gem 'benchmark-ips'
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'benchmark/ips'
|
12
|
+
require 'uringmachine'
|
13
|
+
|
14
|
+
COUNT = 1000
|
15
|
+
NUM_PRODUCERS = 2
|
16
|
+
NUM_CONSUMERS = 10
|
17
|
+
|
18
|
+
def run_threads
|
19
|
+
queue = Queue.new
|
20
|
+
done = Queue.new
|
21
|
+
|
22
|
+
NUM_PRODUCERS.times do
|
23
|
+
Thread.new do
|
24
|
+
COUNT.times { queue << rand(1000) }
|
25
|
+
done << true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
total = 0
|
30
|
+
NUM_CONSUMERS.times do
|
31
|
+
Thread.new do
|
32
|
+
loop do
|
33
|
+
item = queue.shift
|
34
|
+
break if item.nil?
|
35
|
+
|
36
|
+
total += item
|
37
|
+
end
|
38
|
+
done << true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# wait for producers
|
43
|
+
NUM_PRODUCERS.times { done.shift }
|
44
|
+
|
45
|
+
# stop and wait for consumers
|
46
|
+
NUM_CONSUMERS.times do
|
47
|
+
queue << nil
|
48
|
+
done.shift
|
49
|
+
end
|
50
|
+
|
51
|
+
total
|
52
|
+
end
|
53
|
+
|
54
|
+
def run_um
|
55
|
+
machine = UM.new
|
56
|
+
queue = UM::Queue.new
|
57
|
+
done = UM::Queue.new
|
58
|
+
|
59
|
+
NUM_PRODUCERS.times do
|
60
|
+
machine.spin do
|
61
|
+
COUNT.times { machine.push(queue, rand(1000)) }
|
62
|
+
machine.push(done, true)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
total = 0
|
67
|
+
NUM_CONSUMERS.times do
|
68
|
+
machine.spin do
|
69
|
+
loop do
|
70
|
+
item = machine.shift(queue)
|
71
|
+
break if item.nil?
|
72
|
+
|
73
|
+
total += item
|
74
|
+
end
|
75
|
+
machine.push(done, true)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# wait for producers
|
80
|
+
NUM_PRODUCERS.times { machine.shift(done) }
|
81
|
+
|
82
|
+
# stop and wait for consumers
|
83
|
+
NUM_CONSUMERS.times do
|
84
|
+
machine.push(queue, nil)
|
85
|
+
machine.shift(done)
|
86
|
+
end
|
87
|
+
|
88
|
+
total
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
# puts "running"
|
93
|
+
# res = run_threads
|
94
|
+
# p threads: res
|
95
|
+
|
96
|
+
# 100.times {
|
97
|
+
# res = run_um
|
98
|
+
# p fibers: res
|
99
|
+
# }
|
100
|
+
|
101
|
+
|
102
|
+
# __END__
|
103
|
+
|
104
|
+
Benchmark.ips do |x|
|
105
|
+
x.config(:time => 5, :warmup => 2)
|
106
|
+
|
107
|
+
x.report("threads") { run_threads }
|
108
|
+
x.report("UM") { run_um }
|
109
|
+
|
110
|
+
x.compare!
|
111
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/inline'
|
4
|
+
|
5
|
+
gemfile do
|
6
|
+
source 'https://rubygems.org'
|
7
|
+
gem 'uringmachine', path: '..'
|
8
|
+
gem 'extralite'
|
9
|
+
gem 'benchmark-ips'
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'uringmachine'
|
13
|
+
require 'extralite'
|
14
|
+
|
15
|
+
class UM::Actor < Fiber
|
16
|
+
def initialize(machine, target)
|
17
|
+
@machine = machine
|
18
|
+
@target = target
|
19
|
+
@mailbox = UM::Queue.new
|
20
|
+
super { act }
|
21
|
+
end
|
22
|
+
|
23
|
+
def act
|
24
|
+
while (sym, a, k, peer = @machine.shift(@mailbox))
|
25
|
+
|
26
|
+
begin
|
27
|
+
ret = @target.send(sym, *a, **k)
|
28
|
+
@machine.schedule(peer, ret)
|
29
|
+
rescue => e
|
30
|
+
@machine.schedule(peer, e)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
rescue Exception => e
|
34
|
+
# handle unhandled exceptions
|
35
|
+
ensure
|
36
|
+
@machine.fiber_map.delete(self)
|
37
|
+
@machine.yield
|
38
|
+
end
|
39
|
+
|
40
|
+
def method_missing(sym, *a, **k)
|
41
|
+
@machine.push(@mailbox, [sym, a, k, Fiber.current])
|
42
|
+
ret = @machine.yield
|
43
|
+
raise(ret) if ret.is_a?(Exception)
|
44
|
+
ret
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class UM
|
49
|
+
def spin_actor(target)
|
50
|
+
f = UM::Actor.new(self, target)
|
51
|
+
schedule(f, nil)
|
52
|
+
@@fiber_map[f] = true
|
53
|
+
f
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class Locker
|
58
|
+
def initialize(machine, target)
|
59
|
+
@machine = machine
|
60
|
+
@target = target
|
61
|
+
@mutex = UM::Mutex.new
|
62
|
+
end
|
63
|
+
|
64
|
+
def method_missing(sym, *a, **k)
|
65
|
+
@machine.synchronize(@mutex) { @target.send(sym, *a, **k) }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
PATH = '/tmp/foo'
|
71
|
+
|
72
|
+
$machine = UM.new
|
73
|
+
$raw_db = Extralite::Database.new(PATH)
|
74
|
+
$actor_db = $machine.spin_actor(Extralite::Database.new(PATH))
|
75
|
+
$locker_db = Locker.new($machine, Extralite::Database.new(PATH))
|
76
|
+
|
77
|
+
[$raw_db, $actor_db, $locker_db].each do |db|
|
78
|
+
p db.query('select 1')
|
79
|
+
end
|
80
|
+
|
81
|
+
bm = Benchmark.ips do |x|
|
82
|
+
x.config(:time => 5, :warmup => 2)
|
83
|
+
|
84
|
+
x.report("raw") { $raw_db.query('select 1') }
|
85
|
+
x.report("actor") { $actor_db.query('select 1') }
|
86
|
+
x.report("locker") { $locker_db.query('select 1') }
|
87
|
+
|
88
|
+
x.compare!
|
89
|
+
end
|
data/examples/http_server.rb
CHANGED
@@ -35,7 +35,7 @@ end
|
|
35
35
|
|
36
36
|
server_fd = @machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0)
|
37
37
|
@machine.setsockopt(server_fd, UM::SOL_SOCKET, UM::SO_REUSEADDR, true)
|
38
|
-
@machine.bind(server_fd, '
|
38
|
+
@machine.bind(server_fd, '0.0.0.0', 1234)
|
39
39
|
@machine.listen(server_fd, UM::SOMAXCONN)
|
40
40
|
puts 'Listening on port 1234'
|
41
41
|
|
data/examples/pg.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
|
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
|
data/ext/um/extconf.rb
CHANGED
@@ -6,6 +6,61 @@ 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
66
|
if RUBY_PLATFORM !~ /linux/
|
@@ -35,6 +90,8 @@ def get_config
|
|
35
90
|
}
|
36
91
|
end
|
37
92
|
|
93
|
+
# config_ssl
|
94
|
+
|
38
95
|
config = get_config
|
39
96
|
puts "Building UringMachine (\n#{config.map { |(k, v)| " #{k}: #{v}\n"}.join})"
|
40
97
|
|