Revision: 3134 http://trac.macosforge.org/projects/ruby/changeset/3134 Author: lsansonetti@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) {
participants (1)
-
source_changes@macosforge.org