From: eregontp@... Date: 2018-08-19T00:13:23+00:00 Subject: [ruby-core:88549] [Ruby trunk Bug#14999] ConditionVariable doesn't reacquire the Mutex if Thread#kill-ed Issue #14999 has been updated by Eregon (Benoit Daloze). normalperson (Eric Wong) wrote: > Maybe wishful thinking, but r64464 might be the right fix. Seems it's not yet fully fixed unfortunately: http://ci.rvm.jp/results/trunk_clang_39@silicon-docker/1236189 http://ci.rvm.jp/results/trunk_gcc5@silicon-docker/1236243 http://ci.rvm.jp/results/trunk-asserts-nopara@silicon-docker/1236250 http://ci.rvm.jp/results/trunk_gcc5@silicon-docker/1236262 http://ci.rvm.jp/results/trunk-mjit-wait@silicon-docker/1236304 I think we need to give some thinking on this, and I don't want to stress you to fix it to fix the build. (although this should be solved soon IMHO, latest before the next preview/RC) So I propose to "tag" the spec so it won't run in CI, so you can focus on it when there is time. I'll do that tomorrow if you agree. It would be also be interesting to see if Ruby <= 2.5 actually ensured the semantics I described above. ---------------------------------------- Bug #14999: ConditionVariable doesn't reacquire the Mutex if Thread#kill-ed https://bugs.ruby-lang.org/issues/14999#change-73610 * Author: Eregon (Benoit Daloze) * Status: Closed * Priority: Normal * Assignee: normalperson (Eric Wong) * Target version: * ruby -v: ruby 2.6.0dev (2018-08-16 trunk 64394) [x86_64-linux] * Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN ---------------------------------------- These specs reproduce the issue: https://raw.githubusercontent.com/oracle/truffleruby/master/spec/ruby/library/conditionvariable/wait_spec.rb I can commit them, but of course they will fail. Feel free to just copy it to MRI's spec/ruby/library/conditionvariable/wait_spec.rb (I would do it when synchronizing specs anyway) I'd guess it's caused by the recent timer thread changes or so. This spec works fine on 2.5.1 and older. Just copy-pasting the spec out allows for a standalone reproducer: ~~~ ruby m = Mutex.new cv = ConditionVariable.new in_synchronize = false owned = nil th = Thread.new do m.synchronize do in_synchronize = true begin cv.wait(m) ensure owned = m.owned? $stderr.puts "\nThe Thread doesn't own the Mutex!" unless owned end end end # wait for m to acquire the mutex Thread.pass until in_synchronize # wait until th is sleeping (ie waiting) Thread.pass while th.status and th.status != "sleep" m.synchronize { cv.signal # Wait that the thread is blocked on acquiring the Mutex sleep 0.001 # Kill the thread, yet the thread should first acquire the Mutex before going on th.kill } th.join ~~~ Result on trunk: ~~~ The Thread doesn't own the Mutex! # terminated with exception (report_on_exception is true): Traceback (most recent call last): 1: from cv_bug.rb:7:in `block in
' cv_bug.rb:7:in `synchronize': Attempt to unlock a mutex which is not locked (ThreadError) Traceback (most recent call last): 1: from cv_bug.rb:7:in `block in
' cv_bug.rb:7:in `synchronize': Attempt to unlock a mutex which is not locked (ThreadError) ~~~ -- https://bugs.ruby-lang.org/ Unsubscribe: