summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-12-18 09:21:05 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-12-18 09:21:05 +0000
commit1df9c2bc1cde43d454146691ea9a68f2ff6fbe16 (patch)
treec88cb81175b12c1aab253ee35b7412bcd321592b
parent47127762e72cce69587849905dcf646710e0b7d8 (diff)
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
-rw-r--r--test/ruby/test_thread.rb15
-rw-r--r--thread_sync.c2
2 files changed, 15 insertions, 2 deletions
diff --git a/test/ruby/test_thread.rb b/test/ruby/test_thread.rb
index 78d6d82e23e..6557f881fc5 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 4a3cb2ad6a9..36ed71bf88b 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;