ruby-changes:10989
From: mame <ko1@a...>
Date: Tue, 24 Feb 2009 01:20:20 +0900 (JST)
Subject: [ruby-changes:10989] Ruby:r22577 (trunk): * thread.c (thread_cleanup_func): unlock all locked mutexes even when
mame 2009-02-24 01:20:06 +0900 (Tue, 24 Feb 2009) New Revision: 22577 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=22577 Log: * thread.c (thread_cleanup_func): unlock all locked mutexes even when forking. [ruby-core:22269] Modified files: trunk/ChangeLog trunk/bootstraptest/test_thread.rb trunk/thread.c Index: ChangeLog =================================================================== --- ChangeLog (revision 22576) +++ ChangeLog (revision 22577) @@ -1,3 +1,8 @@ +Tue Feb 24 01:19:38 2009 Yusuke Endoh <mame@t...> + + * thread.c (thread_cleanup_func): unlock all locked mutexes even when + forking. [ruby-core:22269] + Tue Feb 24 00:54:16 2009 Yukihiro Matsumoto <matz@r...> * insns.def (opt_minus): inline float operation. Index: bootstraptest/test_thread.rb =================================================================== --- bootstraptest/test_thread.rb (revision 22576) +++ bootstraptest/test_thread.rb (revision 22577) @@ -216,6 +216,18 @@ end } +assert_equal 'ok', %{ + open("zzz.rb", "w") do |f| + f.puts <<-END + Thread.new { fork { GC.start } }.join + pid, status = Process.wait2 + $result = status.success? ? :ok : :ng + END + end + require "zzz.rb" + $result +} + assert_finish 3, %{ th = Thread.new {sleep 2} th.join(1) Index: thread.c =================================================================== --- thread.c (revision 22576) +++ thread.c (revision 22577) @@ -291,7 +291,7 @@ struct rb_mutex_struct *next_mutex; } mutex_t; -static void rb_mutex_unlock_all(mutex_t *mutex); +static void rb_mutex_unlock_all(mutex_t *mutex, rb_thread_t *th); void rb_thread_terminate_all(void) @@ -305,7 +305,7 @@ /* unlock all locking mutexes */ if (th->keeping_mutexes) { - rb_mutex_unlock_all(th->keeping_mutexes); + rb_mutex_unlock_all(th->keeping_mutexes, GET_THREAD()); } thread_debug("rb_thread_terminate_all (main thread: %p)\n", (void *)th); @@ -339,6 +339,12 @@ thread_cleanup_func(void *th_ptr) { rb_thread_t *th = th_ptr; + + /* unlock all locking mutexes */ + if (th->keeping_mutexes) { + rb_mutex_unlock_all(th->keeping_mutexes, th); + th->keeping_mutexes = NULL; + } thread_cleanup_func_before_exec(th_ptr); native_thread_destroy(th); } @@ -434,12 +440,6 @@ (void *)th, th->locking_mutex); } - /* unlock all locking mutexes */ - if (th->keeping_mutexes) { - rb_mutex_unlock_all(th->keeping_mutexes); - th->keeping_mutexes = NULL; - } - /* delete self other than main thread from living_threads */ if (th != main_th) { st_delete_wrap(th->vm->living_threads, th->self); @@ -457,7 +457,6 @@ } join_th = join_th->join_list_next; } - if (th != main_th) rb_check_deadlock(th->vm); if (!th->root_fiber) { rb_thread_recycle_stack_release(th->stack); @@ -465,6 +464,7 @@ } } thread_cleanup_func(th); + if (th != main_th) rb_check_deadlock(th->vm); if (th->vm->main_thread == th) { ruby_cleanup(state); } @@ -3146,7 +3146,7 @@ } static void -rb_mutex_unlock_all(mutex_t *mutexes) +rb_mutex_unlock_all(mutex_t *mutexes, rb_thread_t *th) { const char *err; mutex_t *mutex; @@ -3156,7 +3156,7 @@ /* rb_warn("mutex #<%p> remains to be locked by terminated thread", mutexes); */ mutexes = mutex->next_mutex; - err = mutex_unlock(mutex, GET_THREAD()); + err = mutex_unlock(mutex, th); if (err) rb_bug("invalid keeping_mutexes: %s", err); } } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/