[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]