From 1df9c2bc1cde43d454146691ea9a68f2ff6fbe16 Mon Sep 17 00:00:00 2001 From: normal Date: Tue, 18 Dec 2018 09:21:05 +0000 Subject: thread_sync.c (mutex_ptr): only reinitalize waitqueue at fork Mutexes need to remain locked after forking. This fixes "[BUG] invalid keeping_mutexes: Attempt to unlock a mutex which is locked by another thread" and should fix test_fork_while_parent_locked failures in CI [ruby-core:90581] [Bug #15424] [ruby-core:90595] [Bug #15430] Fixes: r66230 ("handle mutexes held by parent threads in children") git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66438 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- test/ruby/test_thread.rb | 15 +++++++++++++++ thread_sync.c | 2 -- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/test/ruby/test_thread.rb b/test/ruby/test_thread.rb index 78d6d82e23..6557f881fc 100644 --- a/test/ruby/test_thread.rb +++ b/test/ruby/test_thread.rb @@ -1260,6 +1260,21 @@ q.pop assert_equal 0, failures, '[ruby-core:90312] [Bug #15383]' end + def test_fork_while_mutex_locked_by_forker + skip 'needs fork' unless Process.respond_to?(:fork) + m = Mutex.new + m.synchronize do + pid = fork do + exit!(2) unless m.locked? + m.unlock rescue exit!(3) + m.synchronize {} rescue exit!(4) + exit!(0) + end + _, st = Timeout.timeout(30) { Process.waitpid2(pid) } + assert_predicate st, :success?, '[ruby-core:90595] [Bug #15430]' + end + end + def test_subclass_no_initialize t = Module.new do break eval("class C\u{30b9 30ec 30c3 30c9} < Thread; self; end") diff --git a/thread_sync.c b/thread_sync.c index 4a3cb2ad6a..36ed71bf88 100644 --- a/thread_sync.c +++ b/thread_sync.c @@ -130,8 +130,6 @@ mutex_ptr(VALUE obj) /* forked children can't reach into parent thread stacks */ mutex->fork_gen = fork_gen; list_head_init(&mutex->waitq); - mutex->next_mutex = 0; - mutex->th = 0; } return mutex; -- cgit v1.2.3