Skip to content

StringIO is not thread-safe (throws a Java exception) #4417

@glebm

Description

@glebm

Environment

$ jruby -v
jruby 9.1.6.0 (2.3.1) 2016-11-09 0150a76 Java HotSpot(TM) 64-Bit Server VM 25.45-b02 on 1.8.0_45-b14 +jit [darwin-x86_64]
$ uname -a
Darwin Macintosh.local 16.3.0 Darwin Kernel Version 16.3.0: Thu Nov 17 20:23:58 PST 2016; root:xnu-3789.31.2~1/RELEASE_X86_64 x86_64

Expected Behavior

Given this test.rb file:

a = StringIO.new
100.times.map do
  Thread.start do
    # 'hello' seems to work but not *%w(hello)
    100.times { a.puts *%w(hello) }
  end
end.each(&:join)

Its execution should succeed:

$ jruby test.rb

Actual Behavior

Exception in thread "Ruby-0-Thread-100: test.rb:1" Exception in thread "Ruby-0-Thread-99: test.rb:1" java.lang.ArrayIndexOutOfBoundsException
	at java.lang.System.arraycopy(Native Method)
	at org.jruby.util.ByteList.grow(ByteList.java:1102)
	at org.jruby.util.ByteList.length(ByteList.java:584)
	at org.jruby.RubyString.resize(RubyString.java:995)
	at org.jruby.ext.stringio.StringIO.strioExtend(StringIO.java:701)
	at org.jruby.ext.stringio.StringIO.write(StringIO.java:1024)
	at org.jruby.ext.stringio.StringIO$INVOKER$i$1$0$write.call(StringIO$INVOKER$i$1$0$write.gen)
	at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:161)
	at org.jruby.RubyIO.write(RubyIO.java:2567)
	at org.jruby.ext.stringio.StringIO$GenericWritable.puts(StringIO.java:1213)
	at org.jruby.ext.stringio.StringIO$GenericWritable$INVOKER$s$0$0$puts.call(StringIO$GenericWritable$INVOKER$s$0$0$puts.gen)
	at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:67)
	at test.invokeOther1:puts(test.rb:4)
	at test.RUBY$block$\=test\,rb$2(test.rb:4)
	at org.jruby.runtime.CompiledIRBlockBody.yieldDirect(CompiledIRBlockBody.java:156)
	at org.jruby.runtime.IRBlockBody.yieldSpecific(IRBlockBody.java:76)
	at org.jruby.runtime.Block.yieldSpecific(Block.java:136)
	at org.jruby.RubyFixnum.times(RubyFixnum.java:299)
	at org.jruby.RubyFixnum$INVOKER$i$0$0$times.call(RubyFixnum$INVOKER$i$0$0$times.gen)
	at org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:139)
	at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:145)
	at test.invokeOther4:times(test.rb:4)
	at test.RUBY$block$\=test\,rb$1(test.rb:4)
	at org.jruby.runtime.CompiledIRBlockBody.callDirect(CompiledIRBlockBody.java:145)
	at org.jruby.runtime.IRBlockBody.call(IRBlockBody.java:67)
	at org.jruby.runtime.Block.call(Block.java:126)
	at org.jruby.RubyProc.call(RubyProc.java:324)
	at org.jruby.RubyProc.call(RubyProc.java:249)
	at org.jruby.internal.runtime.RubyRunnable.run(RubyRunnable.java:104)
	at java.lang.Thread.run(Thread.java:745)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions