I committed an update to my fix for JRUBY-5114. Originally I had hoped
we could get away with never autoclosing streams, since users SHOULD
be closing them manually and not leaving them for GC to clean up.
However, that behavior is expected by so many Ruby users, I backed off
on that change.

Instead, all IO objects now have an "autoclose" flag, just like Ruby
1.9.2 does (and obviously, we'd have needed it for 1.9 support
anyway). All IO objects (with a couple exceptions, below) will default
to autoclose=true, meaning that when they finalize, they'll attempt to
close their associated stream (if other IOs hold references to the
same stream, it will remain open until they finalize or close too).
Setting autoclose=false disables the close-on-finalize behavior,
leaving IO channels floating.

The ultimate cause of JRUBY-5114 was the fact that all IO objects
autoclosed, even those wrapping streams/channels "adopted" from other
parts of the JVM. The servlet engine would give JRuby a servlet stream
to process a POST request, we'd wrap it in an IO and do some basic
operations, and then we'd dereference it. That would frequently cause
it to GC, finalize, and close before the servlet engine had a chance
to flush and close it itself, resulting in the EBADF and 500 errors
many of you have seen.

jruby-rack and other libraries that integrate JRuby with
externally-sourced IO streams/channels will need to use
autoclose=false to avoid our IO objects damaging streams coming from
outside. Alternatively, you can do what I believe the Torquebox guys
did...wrap the stream in a pseudo-stream that has a stubbed-out dummy
"close" method. Either way, because of Ruby semantics, Ruby IO objects
will autoclose on finalize by default...so you need to tell it not to.

We probably want to mark all paths that construct RubyIO objects with
CLEARLY STATED javadoc indicating that you're handing the stream off
and it will be autoclosed.

It may also be useful to add some Java APIs so you can create new IO
wrappers without autoclose defaulting to true. To that end, I've
modified some of our Java extensions: InputStream#to_io,
OutputStream#to_io, and Channel#to_io now accept hash args :autoclose
= (true|false), so when coercing a Java stream or channel to an IO
from Ruby you can disable autoclose at the same time.

I have also made IO#autoclose and IO#autoclose= methods available in
1.8 mode, since without them it's difficult to disable autoclosing
from Ruby. RubyIO itself has isAutoclose() and setAutoclose() Java
methods, as you'd expect.

Thanks for your patience, folks.

- Charlie

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply via email to