-
-
Notifications
You must be signed in to change notification settings - Fork 942
Closed
Milestone
Description
Environment
jruby -v:
jruby 9.1.13.0 (2.3.3) 2017-09-06 8e1c115 Java HotSpot(TM) 64-Bit Server VM 25.181-b13 on 1.8.0_181-b13 +jit [darwin-x86_64]
and
jruby 9.1.17.0 (2.3.3) 2018-04-20 d8b1ff9 Java HotSpot(TM) 64-Bit Server VM 25.181-b13 on 1.8.0_181-b13 +jit [darwin-x86_64]
and
jruby 9.2.7.0 (2.5.3) 2019-04-09 8a269e3 Java HotSpot(TM) 64-Bit Server VM 25.181-b13 on 1.8.0_181-b13 +jit [darwin-x86_64]
JRUBY_OPTS:
-J-Dapple.awt.UIElement=true -J-Djava.awt.headless=true -X+O
java -version:
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
uname -a
Darwin hades.local 18.5.0 Darwin Kernel Version 18.5.0: Mon Mar 11 20:40:32 PDT 2019; root:xnu-4903.251.3~3/RELEASE_X86_64 x86_64
Expected Behavior
When executing IO.read_nonblock on a socket with no data to be read while another thread is concurrently writing to the same socket, an EOFError can be raised. The expected behavior is for an Errno::EAGAIN or Errno::EWOULDBLOCK to be raised for every read_nonblock Same behavior appears to happen when using TCPSockets.
The socket appears to still be functional after these EOFErrors, as more data can still be read/written to/from socket.
In Ruby (C) this either appears to be threadsafe (or at least more threadsafe).
require 'socket'
s1, s2 = UNIXSocket.pair
ITRS = 2000
failures = {}
t1 = Thread.new do
ITRS.times do |i|
begin
s1.read_nonblock(1)
rescue EOFError, IOError => eof
failures[i] = eof
rescue Errno::EAGAIN, Errno::EWOULDBLOCK
# ignore
end
end
end
ITRS.times { |i| s1.write(".") }
t1.join
# verify that despite all the EOFErrors the socket is not actually EOF
s2.write('.')
puts "read from s1 (after all EOFs): #{s1.read_nonblock(1)}"
s1.close
s2.close
# show some info about failures
puts "#{failures.length} / #{ITRS} read_nonblock(1) failed"
iteration, error = failures.first
if error
puts error
puts error.backtrace
end
output on ruby-2.5.1 (MRI) ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]
$ ruby socket_test.rb
read from s1 (after all EOFs): .
0 / 2000 read_nonblock(1) failed
Actual Behavior
output on jruby-9.1.17.0:
$ ruby socket_test.rb
read from s1 (after all EOFs): .
87 / 2000 read_nonblock(1) failed
End of file reached
org/jruby/RubyIO.java:2855:in `read_nonblock'
socket_test.rb:13:in `block in socket_test.rb'
org/jruby/RubyFixnum.java:305:in `times'
socket_test.rb:11:in `block in socket_test.rb'
stack trace with -Xbacktrace.style=full
End of file reached
java/lang/Thread.java:1559:in `getStackTrace'
org/jruby/runtime/backtrace/TraceType.java:244:in `getBacktraceData'
org/jruby/runtime/backtrace/TraceType.java:47:in `getBacktrace'
org/jruby/RubyException.java:245:in `prepareBacktrace'
org/jruby/exceptions/RaiseException.java:216:in `preRaise'
org/jruby/exceptions/RaiseException.java:183:in `preRaise'
org/jruby/exceptions/RaiseException.java:111:in `<init>'
org/jruby/Ruby.java:4127:in `newRaiseException'
org/jruby/Ruby.java:4078:in `newEOFError'
org/jruby/RubyIO.java:2872:in `nonblockEOF'
org/jruby/RubyIO.java:2959:in `getPartial'
org/jruby/RubyIO.java:2864:in `doReadNonblock'
org/jruby/RubyIO.java:2855:in `read_nonblock'
org/jruby/RubyIO$INVOKER$i$0$2$read_nonblock.gen:-1:in `call'
org/jruby/internal/runtime/methods/JavaMethod.java:796:in `call'
org/jruby/internal/runtime/methods/DynamicMethod.java:202:in `call'
org/jruby/runtime/callsite/CachingCallSite.java:153:in `call'
socket_test.rb:13:in `invokeOther1:read_nonblock'
socket_test.rb:13:in `block in socket_test.rb'
org/jruby/runtime/CompiledIRBlockBody.java:156:in `yieldDirect'
org/jruby/runtime/BlockBody.java:114:in `yield'
org/jruby/runtime/Block.java:165:in `yield'
org/jruby/RubyFixnum.java:305:in `times'
org/jruby/RubyFixnum$INVOKER$i$0$0$times.gen:-1:in `call'
org/jruby/runtime/callsite/CachingCallSite.java:308:in `cacheAndCall'
org/jruby/runtime/callsite/CachingCallSite.java:137:in `call'
org/jruby/runtime/callsite/CachingCallSite.java:142:in `callIter'
socket_test.rb:11:in `invokeOther4:times'
socket_test.rb:11:in `block in socket_test.rb'
org/jruby/runtime/CompiledIRBlockBody.java:145:in `callDirect'
org/jruby/runtime/IRBlockBody.java:71:in `call'
org/jruby/runtime/Block.java:124:in `call'
org/jruby/RubyProc.java:289:in `call'
org/jruby/RubyProc.java:246:in `call'
org/jruby/internal/runtime/RubyRunnable.java:104:in `run'
java/lang/Thread.java:748:in `run'
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels