rb: NonblockingServer: Use a select() loop in the acceptor thread
Using a select() loop with a timeout allows the acceptor thread to be shut down
cleanly under JRuby.
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@669042 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/rb/lib/thrift/server/nonblockingserver.rb b/lib/rb/lib/thrift/server/nonblockingserver.rb
index f84a109..dc0f646 100644
--- a/lib/rb/lib/thrift/server/nonblockingserver.rb
+++ b/lib/rb/lib/thrift/server/nonblockingserver.rb
@@ -25,14 +25,17 @@
begin
loop do
+ break if @serverTransport.closed?
+ rd, = select([@serverTransport], nil, nil, 0.1)
+ next if rd.nil?
socket = @serverTransport.accept
@logger.debug "Accepted socket: #{socket.inspect}"
@io_manager.add_connection socket
end
rescue IOError => e
- # we must be shutting down
- @logger.info "#{self} is shutting down, goodbye"
end
+ # we must be shutting down
+ @logger.info "#{self} is shutting down, goodbye"
ensure
@transport_semaphore.synchronize do
@serverTransport.close
diff --git a/lib/rb/lib/thrift/transport.rb b/lib/rb/lib/thrift/transport.rb
index 0710bd7..14e9dbe 100644
--- a/lib/rb/lib/thrift/transport.rb
+++ b/lib/rb/lib/thrift/transport.rb
@@ -62,6 +62,8 @@
def accept; nil; end
def close; nil; end
+
+ def closed?; nil; end
end
deprecate_class! :TServerTransport => ServerTransport
diff --git a/lib/rb/lib/thrift/transport/socket.rb b/lib/rb/lib/thrift/transport/socket.rb
index 8d6f1ed..636244c 100644
--- a/lib/rb/lib/thrift/transport/socket.rb
+++ b/lib/rb/lib/thrift/transport/socket.rb
@@ -110,6 +110,12 @@
@handle.close unless @handle.nil? or @handle.closed?
@handle = nil
end
+
+ def closed?
+ @handle.nil? or @handle.closed?
+ end
+
+ alias to_io handle
end
deprecate_class! :TServerSocket => ServerSocket
end
diff --git a/lib/rb/lib/thrift/transport/unixsocket.rb b/lib/rb/lib/thrift/transport/unixsocket.rb
index af686ca..b24e7df 100644
--- a/lib/rb/lib/thrift/transport/unixsocket.rb
+++ b/lib/rb/lib/thrift/transport/unixsocket.rb
@@ -47,5 +47,11 @@
File.delete(@path)
end
end
+
+ def closed?
+ @handle.nil? or @handle.closed?
+ end
+
+ alias to_io handle
end
end
diff --git a/lib/rb/spec/socket_spec.rb b/lib/rb/spec/socket_spec.rb
index ed2f56a..3fede96 100644
--- a/lib/rb/spec/socket_spec.rb
+++ b/lib/rb/spec/socket_spec.rb
@@ -69,5 +69,19 @@
it "should return nil when accepting if there is no handle" do
@socket.accept.should be_nil
end
+
+ it "should return true for closed? when appropriate" do
+ handle = mock("TCPServer", :closed? => false)
+ TCPServer.stub!(:new).and_return(handle)
+ @socket.listen
+ @socket.should_not be_closed
+ handle.stub!(:close)
+ @socket.close
+ @socket.should be_closed
+ @socket.listen
+ @socket.should_not be_closed
+ handle.stub!(:closed?).and_return(true)
+ @socket.should be_closed
+ end
end
end
diff --git a/lib/rb/spec/unixsocket_spec.rb b/lib/rb/spec/unixsocket_spec.rb
index abc166a..ff5c96c 100644
--- a/lib/rb/spec/unixsocket_spec.rb
+++ b/lib/rb/spec/unixsocket_spec.rb
@@ -66,5 +66,20 @@
it "should return nil when accepting if there is no handle" do
@socket.accept.should be_nil
end
+
+ it "should return true for closed? when appropriate" do
+ handle = mock("UNIXServer", :closed? => false)
+ UNIXServer.stub!(:new).and_return(handle)
+ File.stub!(:delete)
+ @socket.listen
+ @socket.should_not be_closed
+ handle.stub!(:close)
+ @socket.close
+ @socket.should be_closed
+ @socket.listen
+ @socket.should_not be_closed
+ handle.stub!(:closed?).and_return(true)
+ @socket.should be_closed
+ end
end
end