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

ruby-changes:8688

From: nobu <ko1@a...>
Date: Wed, 12 Nov 2008 03:29:08 +0900 (JST)
Subject: [ruby-changes:8688] Ruby:r20223 (trunk): * load.c (rb_require_safe): destroys barrier after successfully

nobu	2008-11-12 03:28:47 +0900 (Wed, 12 Nov 2008)

  New Revision: 20223

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

  Log:
    * load.c (rb_require_safe): destroys barrier after successfully
      loaded, to get rid of loading same library again.  [ruby-core:19798]
    * thread.c (rb_barrier_wait): can not wait destroyed barrier.
    
    * thread.c (rb_barrier_destroy): destroys barrier so that no longer
      waited.

  Modified files:
    trunk/ChangeLog
    trunk/include/ruby/intern.h
    trunk/load.c
    trunk/thread.c

Index: include/ruby/intern.h
===================================================================
--- include/ruby/intern.h	(revision 20222)
+++ include/ruby/intern.h	(revision 20223)
@@ -680,6 +680,7 @@
 VALUE rb_barrier_new(void);
 VALUE rb_barrier_wait(VALUE self);
 VALUE rb_barrier_release(VALUE self);
+VALUE rb_barrier_destroy(VALUE self);
 /* time.c */
 VALUE rb_time_new(time_t, long);
 VALUE rb_time_nano_new(time_t, long);
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 20222)
+++ ChangeLog	(revision 20223)
@@ -1,3 +1,13 @@
+Wed Nov 12 03:28:41 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* load.c (rb_require_safe): destroys barrier after successfully
+	  loaded, to get rid of loading same library again.  [ruby-core:19798]
+
+	* thread.c (rb_barrier_wait): can not wait destroyed barrier.
+
+	* thread.c (rb_barrier_destroy): destroys barrier so that no longer
+	  waited.
+
 Tue Nov 11 23:02:27 2008  Yuki Sonoda (Yugui)  <yugui@y...>
 
 	* man/ruby.1 (RUBYOPT): wrote which option can appear.
Index: load.c
===================================================================
--- load.c	(revision 20222)
+++ load.c	(revision 20223)
@@ -366,7 +366,7 @@
 }
 
 static void
-load_unlock(const char *ftptr)
+load_unlock(const char *ftptr, int done)
 {
     if (ftptr) {
 	st_data_t key = (st_data_t)ftptr;
@@ -374,8 +374,12 @@
 	st_table *loading_tbl = get_loading_table();
 
 	if (st_delete(loading_tbl, &key, &data)) {
+	    VALUE barrier = (VALUE)data;
 	    xfree((char *)key);
-	    rb_barrier_release((VALUE)data);
+	    if (done)
+		rb_barrier_destroy(barrier);
+	    else
+		rb_barrier_release(barrier);
 	}
     }
 }
@@ -561,7 +565,7 @@
 	}
     }
     POP_TAG();
-    load_unlock(ftptr);
+    load_unlock(ftptr, !state);
 
     rb_set_safe_level_force(saved.safe);
     if (state) {
@@ -600,7 +604,7 @@
 	rb_vm_call_cfunc(rb_vm_top_self(), init_ext_call, (VALUE)init,
 			 0, rb_str_new2(name));
 	rb_provide(name);
-	load_unlock(name);
+	load_unlock(name, 1);
     }
 }
 
Index: thread.c
===================================================================
--- thread.c	(revision 20222)
+++ thread.c	(revision 20223)
@@ -3125,6 +3125,14 @@
     return barrier_alloc(rb_cBarrier);
 }
 
+static int
+rb_barrier_signal(rb_barrier_t *barrier, unsigned int maxth)
+{
+    int n = thlist_signal(&barrier->waiting, maxth, &barrier->owner);
+    if (!barrier->waiting) barrier->tail = &barrier->waiting;
+    return n;
+}
+
 VALUE
 rb_barrier_wait(VALUE self)
 {
@@ -3133,9 +3141,10 @@
     rb_thread_t *th = GET_THREAD();
 
     Data_Get_Struct(self, rb_barrier_t, barrier);
+    if (!barrier->tail) return Qfalse;
     if (!barrier->owner || barrier->owner->status == THREAD_KILLED) {
 	barrier->owner = 0;
-	if (thlist_signal(&barrier->waiting, 1, &barrier->owner)) return Qfalse;
+	if (rb_barrier_signal(barrier, 1)) return Qfalse;
 	barrier->owner = th;
 	return Qtrue;
     }
@@ -3148,24 +3157,41 @@
 	q->next = 0;
 	barrier->tail = &q->next;
 	rb_thread_sleep_forever();
+	if (!barrier->tail) return Qfalse;
 	return barrier->owner == th ? Qtrue : Qfalse;
     }
 }
 
-VALUE
-rb_barrier_release(VALUE self)
+static rb_barrier_t *
+rb_barrier_owned_ptr(VALUE self)
 {
     rb_barrier_t *barrier;
-    unsigned int n;
 
     Data_Get_Struct(self, rb_barrier_t, barrier);
     if (barrier->owner != GET_THREAD()) {
 	rb_raise(rb_eThreadError, "not owned");
     }
-    n = thlist_signal(&barrier->waiting, 0, &barrier->owner);
+    return barrier;
+}
+
+VALUE
+rb_barrier_release(VALUE self)
+{
+    rb_barrier_t *barrier = rb_barrier_owned_ptr(self);
+    unsigned int n = rb_barrier_signal(barrier, 0);
     return n ? UINT2NUM(n) : Qfalse;
 }
 
+VALUE
+rb_barrier_destroy(VALUE self)
+{
+    rb_barrier_t *barrier = rb_barrier_owned_ptr(self);
+    int n = thlist_signal(&barrier->waiting, 0, 0);
+    barrier->owner = 0;
+    barrier->tail = 0;
+    return n ? UINT2NUM(n) : Qfalse;
+}
+
 /* variables for recursive traversals */
 static ID recursive_key;
 

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

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