[macruby-changes] [3134] MacRuby/trunk/gcd.c
source_changes at macosforge.org
source_changes at macosforge.org
Fri Dec 18 16:26:23 PST 2009
Revision: 3134
http://trac.macosforge.org/projects/ruby/changeset/3134
Author: lsansonetti at apple.com
Date: 2009-12-18 16:26:22 -0800 (Fri, 18 Dec 2009)
Log Message:
-----------
when finalizing a dispatch semaphore, re-equilibrate before release to avoid a crash
Modified Paths:
--------------
MacRuby/trunk/gcd.c
Modified: MacRuby/trunk/gcd.c
===================================================================
--- 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) {
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20091218/d5d36a42/attachment.html>
More information about the macruby-changes
mailing list