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

ruby-changes:2005

From: ko1@a...
Date: 23 Sep 2007 09:02:22 +0900
Subject: [ruby-changes:2005] shyouhei - Ruby:r13495 (ruby_1_8_6): * eval.c, intern.h, ext/thread/thread.c: should not free queue while

shyouhei	2007-09-23 09:01:50 +0900 (Sun, 23 Sep 2007)

  New Revision: 13495

  Modified files:
    branches/ruby_1_8_6/ChangeLog
    branches/ruby_1_8_6/eval.c
    branches/ruby_1_8_6/ext/thread/thread.c
    branches/ruby_1_8_6/version.h

  Log:
    * eval.c, intern.h, ext/thread/thread.c: should not free queue while
      any live threads are waiting.  [ruby-dev:30653]


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_6/ChangeLog?r1=13495&r2=13494
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_6/version.h?r1=13495&r2=13494
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_6/ext/thread/thread.c?r1=13495&r2=13494
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_6/eval.c?r1=13495&r2=13494

Index: ruby_1_8_6/ext/thread/thread.c
===================================================================
--- ruby_1_8_6/ext/thread/thread.c	(revision 13494)
+++ ruby_1_8_6/ext/thread/thread.c	(revision 13495)
@@ -24,11 +24,12 @@
 static VALUE set_critical(VALUE value);
 
 static VALUE
-thread_exclusive_do(void)
+thread_exclusive(VALUE (*func)(ANYARGS), VALUE arg)
 {
-    rb_thread_critical = 1;
+    VALUE critical = rb_thread_critical;
 
-    return rb_yield(Qundef);
+    rb_thread_critical = 1;
+    return rb_ensure(func, arg, set_critical, (VALUE)critical);
 }
 
 /*
@@ -43,7 +44,7 @@
 static VALUE
 rb_thread_exclusive(void)
 {
-    return rb_ensure(thread_exclusive_do, Qundef, set_critical, rb_thread_critical);
+    return thread_exclusive(rb_yield, Qundef);
 }
 
 typedef struct _Entry {
@@ -147,7 +148,7 @@
     VALUE value;
 
     entry = list->entries;
-    if (!entry) return Qundef;
+    if (!entry) return Qnil;
 
     list->entries = entry->next;
     if (entry == list->last_entry) {
@@ -269,21 +270,13 @@
 }
 
 static void
-assert_no_survivors(List *waiting, const char *label, void *addr)
+kill_waiting_threads(List *waiting)
 {
     Entry *entry;
-    VALUE ths = 0;
 
     for (entry = waiting->entries; entry; entry = entry->next) {
-	if (RTEST(wake_thread(entry->value))) {
-	    if (!ths) ths = rb_ary_new();
-	    rb_ary_push(ths, entry->value);
-	}
+	rb_thread_kill(entry->value);
     }
-    if (ths) {
-	rb_bug("%s %p freed with live thread(s) %s waiting",
-	       label, addr, RSTRING_PTR(rb_inspect(ths)));
-    }
 }
 
 /*
@@ -334,7 +327,7 @@
 static void
 free_mutex(Mutex *mutex)
 {
-    assert_no_survivors(&mutex->waiting, "mutex", mutex);
+    kill_waiting_threads(&mutex->waiting);
     finalize_mutex(mutex);
     xfree(mutex);
 }
@@ -493,10 +486,8 @@
 static VALUE
 unlock_mutex(Mutex *mutex)
 {
-    VALUE waking;
+    VALUE waking = thread_exclusive(unlock_mutex_inner, (VALUE)mutex);
 
-    rb_thread_critical = 1;
-    waking = rb_ensure(unlock_mutex_inner, (VALUE)mutex, set_critical, 0);
     if (!RTEST(waking)) {
         return Qfalse;
     }
@@ -544,10 +535,9 @@
     VALUE waking;
     Data_Get_Struct(self, Mutex, mutex);
 
-    rb_thread_critical = 1;
-    waking = rb_ensure(rb_mutex_exclusive_unlock_inner, (VALUE)mutex, set_critical, 0);
+    waking = thread_exclusive(rb_mutex_exclusive_unlock_inner, (VALUE)mutex);
 
-    if (waking == Qundef || !RTEST(waking)) {
+    if (!RTEST(waking)) {
         return Qnil;
     }
 
@@ -622,7 +612,7 @@
 static void
 free_condvar(ConditionVariable *condvar)
 {
-    assert_no_survivors(&condvar->waiting, "condition variable", condvar);
+    kill_waiting_threads(&condvar->waiting);
     finalize_condvar(condvar);
     xfree(condvar);
 }
@@ -732,8 +722,7 @@
 
     Data_Get_Struct(self, ConditionVariable, condvar);
   
-    rb_thread_critical = 1;
-    rb_ensure(wake_all, (VALUE)&condvar->waiting, set_critical, 0);
+    thread_exclusive(wake_all, (VALUE)&condvar->waiting);
     rb_thread_schedule();
 
     return self;
@@ -750,9 +739,8 @@
 static void
 signal_condvar(ConditionVariable *condvar)
 {
-    VALUE waking;
-    rb_thread_critical = 1;
-    waking = rb_ensure(wake_one, (VALUE)&condvar->waiting, set_critical, 0);
+    VALUE waking = thread_exclusive(wake_one, (VALUE)&condvar->waiting);
+
     if (RTEST(waking)) {
         run_thread(waking);
     }
@@ -827,9 +815,9 @@
 static void
 free_queue(Queue *queue)
 {
-    assert_no_survivors(&queue->mutex.waiting, "queue", queue);
-    assert_no_survivors(&queue->space_available.waiting, "queue", queue);
-    assert_no_survivors(&queue->value_available.waiting, "queue", queue);
+    kill_waiting_threads(&queue->mutex.waiting);
+    kill_waiting_threads(&queue->space_available.waiting);
+    kill_waiting_threads(&queue->value_available.waiting);
     finalize_queue(queue);
     xfree(queue);
 }
Index: ruby_1_8_6/ChangeLog
===================================================================
--- ruby_1_8_6/ChangeLog	(revision 13494)
+++ ruby_1_8_6/ChangeLog	(revision 13495)
@@ -1,3 +1,8 @@
+Sun Sep 23 07:49:49 2007  Nobuyoshi Nakada  <nobu@r...>
+
+	* eval.c, intern.h, ext/thread/thread.c: should not free queue while
+	  any live threads are waiting.  [ruby-dev:30653]
+
 Sun Sep 23 06:05:35 2007  Nobuyoshi Nakada  <nobu@r...>
 
 	* ext/stringio/stringio.c (strio_init): separate from strio_initialize
Index: ruby_1_8_6/version.h
===================================================================
--- ruby_1_8_6/version.h	(revision 13494)
+++ ruby_1_8_6/version.h	(revision 13495)
@@ -2,7 +2,7 @@
 #define RUBY_RELEASE_DATE "2007-09-23"
 #define RUBY_VERSION_CODE 186
 #define RUBY_RELEASE_CODE 20070923
-#define RUBY_PATCHLEVEL 109
+#define RUBY_PATCHLEVEL 110
 
 #define RUBY_VERSION_MAJOR 1
 #define RUBY_VERSION_MINOR 8
Index: ruby_1_8_6/eval.c
===================================================================
--- ruby_1_8_6/eval.c	(revision 13494)
+++ ruby_1_8_6/eval.c	(revision 13495)
@@ -6825,7 +6825,6 @@
     volatile VALUE self = ruby_top_self;
     NODE *volatile last_node;
     NODE *saved_cref = ruby_cref;
-    TMP_PROTECT;
 
     if (wrap && ruby_safe_level >= 4) {
 	StringValue(fname);

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

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