]> git.saurik.com Git - apple/libc.git/blobdiff - pthreads.subproj/pthread_cond.c
Libc-186.tar.gz
[apple/libc.git] / pthreads.subproj / pthread_cond.c
index 49e4c360136050b662819c2404f176721ea6e5d5..4eee4a52dcb47de8603ae311a8c54cfc0b96939d 100644 (file)
@@ -78,7 +78,7 @@ int
 pthread_cond_broadcast(pthread_cond_t *cond)
 {
     kern_return_t kern_res;
-    int res, delta;
+    int res;
     if (cond->sig == _PTHREAD_COND_SIG_init) {
         if ((res = pthread_cond_init(cond, NULL)) != 0) {
             return (res);
@@ -89,17 +89,16 @@ pthread_cond_broadcast(pthread_cond_t *cond)
         return (EINVAL);
     }
     LOCK(cond->lock);
-    delta = cond->waiters - cond->sigspending;
-    if (delta <= 0) {
-        /* Avoid kernel call since there are not enough waiters... */
+    if (cond->sem == MACH_PORT_NULL) {
+        /* Avoid kernel call since there are no waiters... */
         UNLOCK(cond->lock);
         return (ESUCCESS);
     }
-    cond->sigspending += delta;
+    cond->sigspending++;
     UNLOCK(cond->lock);
     PTHREAD_MACH_CALL(semaphore_signal_all(cond->sem), kern_res);
     LOCK(cond->lock);
-    cond->sigspending -= delta;
+    cond->sigspending--;
     if (cond->waiters == 0 && cond->sigspending == 0) {
         restore_sem_to_pool(cond->sem);
         cond->sem = MACH_PORT_NULL;
@@ -128,7 +127,7 @@ pthread_cond_signal_thread_np(pthread_cond_t *cond, pthread_t thread)
         return (EINVAL); /* Not a condition variable */
     }
     LOCK(cond->lock);
-    if (cond->waiters <= cond->sigspending) {
+    if (cond->sem == MACH_PORT_NULL) {
         /* Avoid kernel call since there are not enough waiters... */
         UNLOCK(cond->lock);
         return (ESUCCESS);
@@ -296,7 +295,8 @@ _pthread_cond_wait(pthread_cond_t *cond,
     if ((res = pthread_mutex_lock(mutex)) != ESUCCESS) {
         return (res);
     }
-    if (kern_res == KERN_SUCCESS) {
+    /* KERN_ABORTED can be treated as a spurious wakeup */
+    if ((kern_res == KERN_SUCCESS) || (kern_res == KERN_ABORTED)) {
         return (ESUCCESS);
     } else if (kern_res == KERN_OPERATION_TIMED_OUT) {
         return (ETIMEDOUT);