mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
Fix possible deadlock in 'lock-mutex'.
If we got interrupted while waiting on our condition variable, we unlock the kernel mutex momentarily while executing asynchronous operations before putting us back into the waiting queue. However, we have to retry acquiring the mutex before getting back into the queue, otherwise it's possible that we wait indefinitely since nobody could be the owner for a while. * libguile/threads.c (lock_mutex): Try acquring the mutex after signal interruption. Signed-off-by: Ludovic Courtès <ludo@gnu.org>
This commit is contained in:
parent
e47a153317
commit
a1a85581f1
1 changed files with 10 additions and 9 deletions
|
@ -1022,14 +1022,7 @@ lock_mutex (enum scm_mutex_kind kind, struct scm_mutex *m,
|
|||
|
||||
if (err == 0)
|
||||
{
|
||||
if (scm_is_eq (m->owner, SCM_BOOL_F))
|
||||
{
|
||||
m->owner = current_thread->handle;
|
||||
scm_i_pthread_mutex_unlock (&m->lock);
|
||||
return SCM_BOOL_T;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
goto maybe_acquire;
|
||||
}
|
||||
else if (err == ETIMEDOUT)
|
||||
{
|
||||
|
@ -1041,7 +1034,7 @@ lock_mutex (enum scm_mutex_kind kind, struct scm_mutex *m,
|
|||
scm_i_pthread_mutex_unlock (&m->lock);
|
||||
scm_async_tick ();
|
||||
scm_i_scm_pthread_mutex_lock (&m->lock);
|
||||
continue;
|
||||
goto maybe_acquire;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1050,6 +1043,14 @@ lock_mutex (enum scm_mutex_kind kind, struct scm_mutex *m,
|
|||
errno = err;
|
||||
SCM_SYSERROR;
|
||||
}
|
||||
|
||||
maybe_acquire:
|
||||
if (scm_is_eq (m->owner, SCM_BOOL_F))
|
||||
{
|
||||
m->owner = current_thread->handle;
|
||||
scm_i_pthread_mutex_unlock (&m->lock);
|
||||
return SCM_BOOL_T;
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef FUNC_NAME
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue