Skip to content

Commit c2be3db

Browse files
Only release GVL if there are no messages pending.
1 parent 4dd8e59 commit c2be3db

File tree

2 files changed

+27
-15
lines changed

2 files changed

+27
-15
lines changed

ext/hyper_ruby/src/lib.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,17 @@ impl Server {
9999
if let Some(work_rx) = self.work_rx.borrow().as_ref() {
100100

101101
loop {
102-
// Use nogvl to wait for requests outside the GVL
103-
let work_request = nogvl(|| work_rx.recv());
104-
102+
// try getting the next request without yielding the GVL, if there's nothing, wait for one
103+
let work_request = match work_rx.try_recv() {
104+
Ok(work_request) => Ok(work_request),
105+
Err(crossbeam_channel::TryRecvError::Empty) => {
106+
nogvl(|| work_rx.recv())
107+
},
108+
Err(crossbeam_channel::TryRecvError::Disconnected) => {
109+
break;
110+
}
111+
};
112+
105113
match work_request {
106114
Ok(work_request) => {
107115
let request = Request {

test/test_hyper_ruby.rb

+16-12
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,13 @@ def with_server(request_handler, &block)
7979
# Create ruby worker threads that process requests;
8080
# 1 is usually enough, and generally handles better than multiple threads
8181
# if there's no IO (because of the GIL)
82-
worker = Thread.new do
83-
server.run_worker do |request|
84-
# Process the request in Ruby
85-
# request is a hash with :method, :path, :headers, and :body keys
86-
request_handler.call(request)
82+
workers = 1.times.map do
83+
Thread.new do
84+
server.run_worker do |request|
85+
# Process the request in Ruby
86+
# request is a hash with :method, :path, :headers, and :body keys
87+
request_handler.call(request)
88+
end
8789
end
8890
end
8991

@@ -92,7 +94,7 @@ def with_server(request_handler, &block)
9294

9395
ensure
9496
server.stop if server
95-
worker.join if worker
97+
workers.map(&:join) if workers
9698
end
9799

98100
def with_unix_socket_server(request_handler, &block)
@@ -103,11 +105,13 @@ def with_unix_socket_server(request_handler, &block)
103105
# Create ruby worker threads that process requests;
104106
# 1 is usually enough, and generally handles better than multiple threads
105107
# if there's no IO (because of the GIL)
106-
worker = Thread.new do
107-
server.run_worker do |request|
108-
# Process the request in Ruby
109-
# request is a hash with :method, :path, :headers, and :body keys
110-
request_handler.call(request)
108+
workers = 2.times.map do
109+
Thread.new do
110+
server.run_worker do |request|
111+
# Process the request in Ruby
112+
# request is a hash with :method, :path, :headers, and :body keys
113+
request_handler.call(request)
114+
end
111115
end
112116
end
113117

@@ -117,7 +121,7 @@ def with_unix_socket_server(request_handler, &block)
117121

118122
ensure
119123
server.stop if server
120-
worker.join if worker
124+
workers.map(&:join) if workers
121125
end
122126

123127
def handler_simple(request)

0 commit comments

Comments
 (0)