[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