While looking into some tests that appear to be unreliable I discovered that we are adopting some JVM threads very early in execution due to early IO streams for parsing being allowed to close on their own via finalization.
The test I was investigating was CRuby's ruby/test_thread.rb in test_stop, which tests that stopping the sole thread (the main thread in a new subprocess) raises an error, since there are no other threads to schedule.
The IO here is created for the parser, but nobody closes the stream after the parse is complete. This would be appropriate if it were held open for the magic DATA variable, but that's not the case here. The IO should be gracefully cleaned up when it's not needed anymore.
Because it is left to finalize, the finalizer thread is adopted into our thread lists, which breaks any tests that assume only threads created from Ruby code will be present. (Again, maybe we should be hiding adopted threads?)
I have confirmed that the other path here, for a main file opened as a FileInputStream, exhibits the same problem.
The best fix would be that the parser eagerly cleans up IO objects it uses for parsing once they are no longer needed. This will prevent any early finalization from needing to be adopted into our thread structures.
If the streams are set to not autoclose, the finalizer will do nothing to them and will not need to be adopted. This is a low-impact fix, but it seems messy to leave them out there, and I believe this call path may be used for other load logic.
The text was updated successfully, but these errors were encountered:
@headius ah yeah and it is two paths (other gets in underlying IO which is closed further up the call stack). I believe this is will be checking to see if DATA is that io and otherwise closing it in the finally of that same method. Should not be too hard. I will fix this.