From b07964461e478d2f4970ac05479c47aa5855ce10 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 9 Dec 2016 16:53:29 -0600 Subject: [PATCH] pthread_mutex_destroy(): Fix an error in destorynig a mutex which can occur after a pthread has been canceled while holding the mutex. --- sched/pthread/pthread_mutexdestroy.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/sched/pthread/pthread_mutexdestroy.c b/sched/pthread/pthread_mutexdestroy.c index a6b945f670..bea9ba7c38 100644 --- a/sched/pthread/pthread_mutexdestroy.c +++ b/sched/pthread/pthread_mutexdestroy.c @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -90,7 +91,29 @@ int pthread_mutex_destroy(FAR pthread_mutex_t *mutex) if (mutex->pid != -1) { - ret = EBUSY; +#ifndef CONFIG_DISABLE_SIGNALS + /* Verify that the PID still exists. We may be destroying the + * mutex after cancelling a pthread and the mutex may have been + * in a bad state owned by the dead pthread. + */ + + ret = kill(mutex->pid, 0); + if (ret < 0) + { + /* That thread associated with the PID no longer exists */ + + mutex->pid = -1; + + /* Destroy the semaphore */ + + status = sem_destroy((FAR sem_t *)&mutex->sem); + ret = (status != OK) ? get_errno() : OK; + } + else +#endif + { + ret = EBUSY; + } } else { @@ -99,7 +122,7 @@ int pthread_mutex_destroy(FAR pthread_mutex_t *mutex) status = sem_destroy((FAR sem_t *)&mutex->sem); if (status != OK) { - ret = EINVAL; + ret = get_errno(); } }