зеркало из https://github.com/github/ruby.git
* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@20223 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
8bc28d82b4
Коммит
99cd3c512b
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
Wed Nov 12 03:28:41 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* 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@yugui.jp>
|
||||
|
||||
* man/ruby.1 (RUBYOPT): wrote which option can appear.
|
||||
|
|
|
@ -680,6 +680,7 @@ VALUE rb_mutex_synchronize(VALUE mutex, VALUE (*func)(VALUE arg), VALUE arg);
|
|||
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);
|
||||
|
|
12
load.c
12
load.c
|
@ -366,7 +366,7 @@ load_lock(const char *ftptr)
|
|||
}
|
||||
|
||||
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 @@ load_unlock(const char *ftptr)
|
|||
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 @@ rb_require_safe(VALUE fname, int safe)
|
|||
}
|
||||
}
|
||||
POP_TAG();
|
||||
load_unlock(ftptr);
|
||||
load_unlock(ftptr, !state);
|
||||
|
||||
rb_set_safe_level_force(saved.safe);
|
||||
if (state) {
|
||||
|
@ -600,7 +604,7 @@ ruby_init_ext(const char *name, void (*init)(void))
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
36
thread.c
36
thread.c
|
@ -3125,6 +3125,14 @@ rb_barrier_new(void)
|
|||
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_barrier_wait(VALUE self)
|
|||
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,21 +3157,38 @@ rb_barrier_wait(VALUE self)
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче