Skip to content

Commit 3d8f97b

Browse files
committed
fix dead lock when using condition variable
1 parent 845a4ff commit 3d8f97b

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

src/internal/event_loop/thread_pool.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ int moonbitlang_async_job_poll_fd(struct job *job) {
174174
struct worker {
175175
pthread_t id;
176176
struct job *job;
177+
int waiting;
177178
#ifdef WAKEUP_METHOD_COND_VAR
178179
pthread_mutex_t mutex;
179180
pthread_cond_t cond;
@@ -375,21 +376,23 @@ void *worker_loop(void *data) {
375376
break;
376377
}
377378
}
379+
self->waiting = 1;
378380
write(pool.notify_send, &(job->job_id), sizeof(int));
379381

380-
job = 0;
381382
#ifdef WAKEUP_METHOD_SIGNAL
382383
sigwait(&pool.wakeup_signal, &sig);
383384
#elif defined(WAKEUP_METHOD_COND_VAR)
384385
pthread_mutex_lock(&(self->mutex));
386+
while (self->waiting) {
385387
#ifdef __MACH__
386-
// There's a bug in the MacOS's `pthread_cond_wait`,
387-
// see https://github.com/graphia-app/graphia/issues/33
388-
// We know the arguments must be valid here, so use a loop to work around
389-
while (pthread_cond_wait(&(self->cond), &(self->mutex)) == EINVAL) {}
388+
// There's a bug in the MacOS's `pthread_cond_wait`,
389+
// see https://github.com/graphia-app/graphia/issues/33
390+
// We know the arguments must be valid here, so use a loop to work around
391+
while (pthread_cond_wait(&(self->cond), &(self->mutex)) == EINVAL) {}
390392
#else
391-
pthread_cond_wait(&(self->cond), &(self->mutex));
393+
pthread_cond_wait(&(self->cond), &(self->mutex));
392394
#endif
395+
}
393396
pthread_mutex_unlock(&(self->mutex));
394397
#endif
395398
job = self->job;
@@ -404,6 +407,7 @@ void moonbitlang_async_wake_worker(struct worker *worker, struct job *job) {
404407
pthread_kill(worker->id, SIGUSR1);
405408
#elif defined(WAKEUP_METHOD_COND_VAR)
406409
pthread_mutex_lock(&(worker->mutex));
410+
worker->waiting = 0;
407411
pthread_cond_signal(&(worker->cond));
408412
pthread_mutex_unlock(&(worker->mutex));
409413
#endif
@@ -459,6 +463,7 @@ struct worker *moonbitlang_async_spawn_worker(struct job *init_job) {
459463
sizeof(struct worker)
460464
);
461465
worker->job = init_job;
466+
worker->waiting = 0;
462467
pthread_create(&(worker->id), &attr, &worker_loop, worker);
463468
pthread_attr_destroy(&attr);
464469
return worker;

0 commit comments

Comments
 (0)