diff --git a/sched/pthread/Make.defs b/sched/pthread/Make.defs index 9f2c8c6479..a39a35d208 100644 --- a/sched/pthread/Make.defs +++ b/sched/pthread/Make.defs @@ -39,7 +39,7 @@ CSRCS += pthread_create.c pthread_exit.c pthread_join.c pthread_detach.c CSRCS += pthread_yield.c pthread_getschedparam.c pthread_setschedparam.c CSRCS += pthread_mutexinit.c pthread_mutexdestroy.c pthread_mutex.c CSRCS += pthread_mutexlock.c pthread_mutextrylock.c pthread_mutexunlock.c -CSRCS += pthread_mutexconsistent.c +CSRCS += pthread_mutexconsistent.c pthread_mutexinconsistent.c CSRCS += pthread_condinit.c pthread_conddestroy.c CSRCS += pthread_condwait.c pthread_condsignal.c pthread_condbroadcast.c CSRCS += pthread_barrierinit.c pthread_barrierdestroy.c pthread_barrierwait.c diff --git a/sched/pthread/pthread.h b/sched/pthread/pthread.h index 79492d930d..bf97c0c018 100644 --- a/sched/pthread/pthread.h +++ b/sched/pthread/pthread.h @@ -111,6 +111,7 @@ int pthread_takesemaphore(sem_t *sem, bool intr); int pthread_givesemaphore(sem_t *sem); int pthread_takemutex(FAR struct pthread_mutex_s *mutex, bool intr); int pthread_givemutex(FAR struct pthread_mutex_s *mutex); +void pthread_mutex_inconsistent(FAR struct pthread_tcb_s *tcb); #ifdef CONFIG_MUTEX_TYPES int pthread_mutexattr_verifytype(int type); diff --git a/sched/pthread/pthread_cancel.c b/sched/pthread/pthread_cancel.c index a9b7e8270b..3a520b1f93 100644 --- a/sched/pthread/pthread_cancel.c +++ b/sched/pthread/pthread_cancel.c @@ -162,6 +162,10 @@ int pthread_cancel(pthread_t thread) (void)pthread_completejoin((pid_t)thread, PTHREAD_CANCELED); + /* Recover any mutexes still held by the canceled thread */ + + pthread_mutex_inconsistent(tcb); + /* Then let task_terminate do the real work */ return task_terminate((pid_t)thread, false); diff --git a/sched/pthread/pthread_exit.c b/sched/pthread/pthread_exit.c index 40a5b7fb0d..4654d86371 100644 --- a/sched/pthread/pthread_exit.c +++ b/sched/pthread/pthread_exit.c @@ -123,6 +123,10 @@ void pthread_exit(FAR void *exit_value) exit(EXIT_FAILURE); } + /* Recover any mutexes still held by the canceled thread */ + + pthread_mutex_inconsistent(tcb); + /* Perform common task termination logic. This will get called again later * through logic kicked off by _exit(). However, we need to call it before * calling _exit() in order certain operations if this is the last thread diff --git a/sched/pthread/pthread_mutexinit.c b/sched/pthread/pthread_mutexinit.c index fe9620da0b..b521137683 100644 --- a/sched/pthread/pthread_mutexinit.c +++ b/sched/pthread/pthread_mutexinit.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/pthread/pthread_mutexinit.c * - * Copyright (C) 2007-2009, 2011, 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011, 2016-2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -123,6 +123,10 @@ int pthread_mutex_init(FAR pthread_mutex_t *mutex, ret = get_errno(); } #endif + /* Initial internal fields of the mutex */ + + mutex->flink = NULL; + mutex->flags = 0; /* Set up attributes unique to the mutex type */