diff options
| author | Rich Felker <dalias@aerifal.cx> | 2011-03-08 12:08:40 -0500 | 
|---|---|---|
| committer | Rich Felker <dalias@aerifal.cx> | 2011-03-08 12:08:40 -0500 | 
| commit | 7e6be42a77989c01155bdc7333ea58206e1563d4 (patch) | |
| tree | b482baa82bff05cfa68ce7031328465405a74662 /src | |
| parent | 4820f9268d3dc1f2aac923de0a591ffd5d54ea89 (diff) | |
| download | musl-7e6be42a77989c01155bdc7333ea58206e1563d4.tar.gz | |
fix major breakage in pthread_once (it was always deadlocking)
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/thread/pthread_once.c | 15 | 
1 files changed, 7 insertions, 8 deletions
| diff --git a/src/thread/pthread_once.c b/src/thread/pthread_once.c index 72230054..41872f16 100644 --- a/src/thread/pthread_once.c +++ b/src/thread/pthread_once.c @@ -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;  } | 
