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/