summaryrefslogtreecommitdiff
path: root/thread.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-11-11 18:28:47 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-11-11 18:28:47 +0000
commit99cd3c512b78774c8c4ecb92ca4c6278577a58c5 (patch)
treee6c003efc85c4b0ac51a4e91dd9893240f481927 /thread.c
parent8bc28d82b44654f907c5ee468b79de2afab97e8d (diff)
* 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
Diffstat (limited to 'thread.c')
-rw-r--r--thread.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/thread.c b/thread.c
index f6bcc9801f..f0a26df7ed 100644
--- a/thread.c
+++ b/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;
}