Modified: MacRuby/trunk/gcd.c (3133 => 3134)
--- MacRuby/trunk/gcd.c 2009-12-18 22:49:41 UTC (rev 3133)
+++ MacRuby/trunk/gcd.c 2009-12-19 00:26:22 UTC (rev 3134)
@@ -86,6 +86,7 @@
typedef struct {
struct RBasic basic;
dispatch_semaphore_t sem;
+ long count;
} rb_semaphore_t;
#define RSemaphore(val) ((rb_semaphore_t*)val)
@@ -838,6 +839,7 @@
NEWOBJ(s, rb_semaphore_t);
OBJSETUP(s, klass, RUBY_T_NATIVE);
s->sem = NULL;
+ s->count = 0;
return (VALUE)s;
}
@@ -850,6 +852,7 @@
NUM2LONG(value));
}
RSemaphore(self)->sem = s;
+ RSemaphore(self)->count = NUM2LONG(value);
return self;
}
@@ -875,6 +878,12 @@
rb_semaphore_finalize(void *rcv, SEL sel)
{
if (RSemaphore(rcv)->sem != NULL) {
+ // We must re-equilibrate the semaphore count before releasing it,
+ // otherwise GCD will violently crash the program by an assertion.
+ while (dispatch_semaphore_signal(RSemaphore(rcv)->sem) != 0) { }
+ while (--RSemaphore(rcv)->count >= 0) {
+ dispatch_semaphore_signal(RSemaphore(rcv)->sem);
+ }
dispatch_release(RSemaphore(rcv)->sem);
}
if (rb_semaphore_finalize_super != NULL) {