fix major breakage in pthread_once (it was always deadlocking)
authorRich Felker <dalias@aerifal.cx>
Tue, 8 Mar 2011 17:08:40 +0000 (12:08 -0500)
committerRich Felker <dalias@aerifal.cx>
Tue, 8 Mar 2011 17:08:40 +0000 (12:08 -0500)
the issue was a break statement that was breaking only from the
switch, not the enclosing for loop, and a failure to set the final
success state.

src/thread/pthread_once.c

index 72230054ea72cbc546777a7550131c4048a93714..41872f16cb47462845c62d70417e2143448fdfa5 100644 (file)
@@ -20,7 +20,13 @@ int pthread_once(pthread_once_t *control, void (*init)(void))
 
        for (;;) switch (a_swap(control, 1)) {
        case 0:
-               break;
+               pthread_cleanup_push(undo, control);
+               init();
+               pthread_cleanup_pop(0);
+
+               a_store(control, 2);
+               if (waiters) __wake(control, -1, 0);
+               return 0;
        case 1:
                __wait(control, &waiters, 1, 0);
                continue;
@@ -28,11 +34,4 @@ int pthread_once(pthread_once_t *control, void (*init)(void))
                a_store(control, 2);
                return 0;
        }
-
-       pthread_cleanup_push(undo, control);
-       init();
-       pthread_cleanup_pop(0);
-
-       if (waiters) __wake(control, -1, 0);
-       return 0;
 }