diff options
author | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-12-05 18:58:45 +0000 |
---|---|---|
committer | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-12-05 18:58:45 +0000 |
commit | 818f1c65ab6534acdbe539616843cfec3ac794fa (patch) | |
tree | 01852c8e2482eb356c6409cb9ec99fbe4e08aed6 /test/ruby/test_thread.rb | |
parent | e941daa6dd114b52356a63d3c3db5684e6c66717 (diff) |
thread_sync.c (mutex_ptr): handle mutexes held by parent threads in children
Mutexes may be held by threads which only exist in the parent
process, so their waitqueues may be populated with references
to other dead threads. We must reset them at fork.
I am a moron for introducing this bug :<
[ruby-core:90312] [Bug #15383]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66230 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'test/ruby/test_thread.rb')
-rw-r--r-- | test/ruby/test_thread.rb | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/test/ruby/test_thread.rb b/test/ruby/test_thread.rb index 2b120b4a17..78d6d82e23 100644 --- a/test/ruby/test_thread.rb +++ b/test/ruby/test_thread.rb @@ -1239,6 +1239,27 @@ q.pop end end if Process.respond_to?(:fork) + def test_fork_while_parent_locked + skip 'needs fork' unless Process.respond_to?(:fork) + m = Thread::Mutex.new + failures = 0 + run = true + thrs = 50.times.map do + Thread.new do + while run + pid = fork { m.synchronize {} } + m.synchronize {} + _, st = Process.waitpid2(pid) + m.synchronize { failures += 1 } unless st.success? + end + end + end + sleep 0.5 + run = false + thrs.each(&:join) + assert_equal 0, failures, '[ruby-core:90312] [Bug #15383]' + end + def test_subclass_no_initialize t = Module.new do break eval("class C\u{30b9 30ec 30c3 30c9} < Thread; self; end") |