Errno::EBADF is sometimes raised instead of IOError when TCPSocket#readline is
called after TCPSocket#close
-----------------------------------------------------------------------------------------------------------
Key: JRUBY-5514
URL: http://jira.codehaus.org/browse/JRUBY-5514
Project: JRuby
Issue Type: Bug
Affects Versions: JRuby 1.6RC2, JRuby 1.5.6, JRuby 1.5.1
Environment: Linux desk4 2.6.32-28-generic #55-Ubuntu SMP Mon Jan 10
23:42:43 UTC 2011 x86_64 GNU/Linux
java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
Java HotSpot(TM) 64-Bit Server VM (build 17.1-b03, mixed mode)
Reporter: Alex Young
Assignee: Thomas E Enebo
Priority: Minor
When TCPSocket#readline is called after a TCPSocket#close on the same client
socket, if the #close comes from another thread, sometimes an Errno::EBADF is
the result instead of an IOError: closed stream.
Tracing through the code, what's happening is that the ChannelDescriptor
responds to the getline() call with a BadDescriptorException because the
underlying Channel responds false to isOpen(), which on the face of it seems
wrong but I'm not familiar enough with the semantics to make a convincing
argument. Also, given that the readStream.getline() call is guarded by a
beforeBlockingCall(), I suspect that this actually indicates a race somewhere
else in the code.
It is proving difficult to narrow this down to a single test case, but the
following code at least demonstrates the problem:
require 'socket'
server = TCPServer.new(0)
server_thread = Thread.new{ server.accept while true }
exceptions = []
1000.times do |i|
client_socket = TCPSocket.new("localhost", server.addr[1])
close_thread = Thread.new{ sleep(Kernel.rand/100); client_socket.close }
read_thread = Thread.new do
sleep(Kernel.rand/100);
begin
client_socket.readline
rescue Exception => e
exceptions << e
end
end
close_thread.join
read_thread.join
end
p exceptions.map{|e| e.class.to_s}.inject({}){|m,r| m.merge r =>
true}.keys.sort
The final output is, for me:
["EOFError", "Errno::EBADF", "Errno::EPIPE", "IOError"]
EOFError and IOError are expected. EBADF and EPIPE are not.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://jira.codehaus.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email