Kernel#sleep hangs on CI #5365
jruby 22.214.171.124-SNAPSHOT (2.5.0) 2018-10-12 b2f694c Java HotSpot(TM) 64-Bit Server VM 25.181-b13 on 1.8.0_181-b13 +jit [linux-x86_64]
100.times do t = Thread.new do Kernel.sleep :ok end JRuby.reference(t).native_thread.interrupt t.value end
JRuby.reference(t).native_thread.interrupt should stop the thread
t = Thread.new do Kernel.sleep :ok end JRuby.reference(t).native_thread.interrupt => #<Thread:0x69aabcb0@(irb):31 dead>
under load (if I run it in a loop), some threads sometimes remain still in a sleep state
=> #<Thread:0x2dfeb141@(irb):39 sleep>
t.value calls Thread#join and because the thread is alive, it sleeps forever
it looks like there's a race condition somewhere? If I add a sleep call between Thread.new and thread.interrupt it won't hang. Or is it just a bad test?
100.times do t = Thread.new do Kernel.sleep :ok end sleep 0.25 JRuby.reference(t).native_thread.interrupt t.value end
hangs in an infinite loop
Have you confirmed that the thread is actually sleeping before you try to interrupt it? The race here is that the thread may or may not have actually called sleep, so the interrupt call might happen when it's just running the preamble code for the block. It's possible the thread hasn't even been scheduled yet by the time you call interrupt.
I think this is the case
Since that's the case...is there really anything to fix? You are basically interrupting the sleep before it happens. If you wait for status == sleep it should work better, I believe.
Let us know if you believe there's something more we should be doing in JRuby for this case.
no, I think the behaviour is ok, but the test is wrong.
if the thread isn't scheduled yet, it'll cause random failures like this
the test should wait until the thread is ready before calling
otherwise it hangs
makes sense? @headius ?