Sometimes, if pthread_create() failed, then pthread_cond_wait() could accidentally be called in the worker threads after the uninit function had already called pthread_cond_broadcast(), leading to a deadlock. Don't call pthread_cond_wait() if c->done is set.
Unified · Split
| @@ -152,7 +152,8 @@ static void* attribute_align_arg worker(void *v) · 151 unmodified lines | ||
| 152 | 152 | if (c->current_job == thread_count + c->job_count) |
| 153 | 153 | pthread_cond_signal(&c->last_job_cond); |
| 154 | 154 | |
| 155 | − pthread_cond_wait(&c->current_job_cond, &c->current_job_lock); | |
| 155 | + if (!c->done) | |
| 156 | + pthread_cond_wait(&c->current_job_cond, &c->current_job_lock); | |
| 156 | 157 | our_job = self_id; |
| 157 | 158 | |
| 158 | 159 | if (c->done) { |
| @@ -73,7 +73,8 @@ static void* attribute_align_arg worker(void *v) · 72 unmodified lines | ||
| 73 | 73 | if (c->current_job == nb_threads + c->nb_jobs) |
| 74 | 74 | pthread_cond_signal(&c->last_job_cond); |
| 75 | 75 | |
| 76 | − pthread_cond_wait(&c->current_job_cond, &c->current_job_lock); | |
| 76 | + if (!c->done) | |
| 77 | + pthread_cond_wait(&c->current_job_cond, &c->current_job_lock); | |
| 77 | 78 | our_job = self_id; |
| 78 | 79 | |
| 79 | 80 | if (c->done) { |