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