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

ruby-changes:11781

From: nobu <ko1@a...>
Date: Fri, 15 May 2009 17:34:06 +0900 (JST)
Subject: [ruby-changes:11781] Ruby:r23432 (ruby_1_8): * eval.c (rb_thread_join), ext/thread/thread.c (wake_one): adjusts

nobu	2009-05-15 17:33:52 +0900 (Fri, 15 May 2009)

  New Revision: 23432

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=23432

  Log:
    * eval.c (rb_thread_join), ext/thread/thread.c (wake_one): adjusts
      targets of rest waiting threads to join.  [ruby-core:23457]

  Modified files:
    branches/ruby_1_8/ChangeLog
    branches/ruby_1_8/eval.c
    branches/ruby_1_8/ext/thread/thread.c
    branches/ruby_1_8/test/thread/test_thread.rb

Index: ruby_1_8/ext/thread/thread.c
===================================================================
--- ruby_1_8/ext/thread/thread.c	(revision 23431)
+++ ruby_1_8/ext/thread/thread.c	(revision 23432)
@@ -205,6 +205,16 @@
     return ary;
 }
 
+static void
+adjust_join(const List *list, VALUE new)
+{
+    extern void rb_thread_set_join _((VALUE, VALUE));
+    Entry *entry;
+    for (entry = list->entries; entry; entry = entry->next) {
+	rb_thread_set_join(entry->value, new);
+    }
+}
+
 static VALUE
 wake_thread(VALUE thread)
 {
@@ -221,7 +231,7 @@
 }
 
 static VALUE
-wake_one(List *list)
+wake_first(List *list)
 {
     VALUE waking;
 
@@ -234,10 +244,22 @@
 }
 
 static VALUE
+wake_one(List *list)
+{
+    VALUE waking = wake_first(list);
+
+    if (!NIL_P(waking)) {
+	adjust_join(list, waking);
+    }
+
+    return waking;
+}
+
+static VALUE
 wake_all(List *list)
 {
     while (list->entries) {
-        wake_one(list);
+        wake_first(list);
     }
     return Qnil;
 }
Index: ruby_1_8/ChangeLog
===================================================================
--- ruby_1_8/ChangeLog	(revision 23431)
+++ ruby_1_8/ChangeLog	(revision 23432)
@@ -1,3 +1,8 @@
+Fri May 15 17:33:51 2009  Nobuyoshi Nakada  <nobu@r...>
+
+	* eval.c (rb_thread_join), ext/thread/thread.c (wake_one): adjusts
+	  targets of rest waiting threads to join.  [ruby-core:23457]
+
 Sat May  9 23:26:04 2009  Akinori MUSHA  <knu@i...>
 
 	* lib/delegate.rb (Delegator#method_missing)
Index: ruby_1_8/test/thread/test_thread.rb
===================================================================
--- ruby_1_8/test/thread/test_thread.rb	(revision 23431)
+++ ruby_1_8/test/thread/test_thread.rb	(revision 23432)
@@ -85,5 +85,68 @@
     assert_nothing_raised("[ruby-dev:37545]") {assert_equal(1, queue.pop)}
     assert(queue.empty?)
   end
+
+  # This test checks that a thread in Mutex#lock which is raised is
+  # completely removed from the wait_list of the mutex
+  def test_mutex_exception_handling
+    m = Mutex.new
+    m.lock
+
+    sleeping = false
+    t = Thread.new do
+      begin
+        m.lock
+      rescue
+      end
+
+      sleeping = true
+      # Keep that thread alive: if the thread returns, the test method
+      # won't be able to check that +m+ has not been taken (dead mutex
+      # owners are ignored)
+      sleep
+    end
+
+    # Wait for t to wait for the mutex and raise it
+    while true
+      sleep 0.1
+      break if t.stop?
+    end
+    t.raise ArgumentError
+    assert(t.alive? || sleeping)
+
+    # Wait for +t+ to reach the sleep
+    while true
+      sleep 0.1
+      break if t.stop?
+    end
+
+    # Now unlock. The mutex should be free, so Mutex#unlock should return nil
+    assert(! m.unlock)
+  end
+
+  def test_mutex_join
+    m = Mutex.new
+    m.lock
+    wt2 = Thread.new do
+      m.lock
+      sleep 0.5
+      m.unlock
+    end
+
+    # Ensure wt2 is waiting on m
+    sleep 0.1
+
+    wt1 = Thread.new do
+      m.lock
+      m.unlock
+    end
+    # Ensure wt1 is waiting on m
+    sleep 0.1
+
+    # Give it to wt2
+    m.unlock
+
+    assert_nothing_raised {wt1.join}
+  end
 end
 
Index: ruby_1_8/eval.c
===================================================================
--- ruby_1_8/eval.c	(revision 23431)
+++ ruby_1_8/eval.c	(revision 23432)
@@ -11670,7 +11670,17 @@
     return rb_thread_join0(rb_thread_check(thread), limit);
 }
 
+void
+rb_thread_set_join(thread, join)
+    VALUE thread, join;
+{
+    rb_thread_t th = rb_thread_check(thread);
+    rb_thread_t jth = rb_thread_check(join);
+    th->wait_for = WAIT_JOIN;
+    th->join = jth;
+}
 
+
 /*
  *  call-seq:
  *     thr.join          => thr

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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