Skip to content

Commit 42135c1

Browse files
committed
Mark mutex as robust to prevent deadlocks
Prevent application hangs that occur when a thread dies while holding a mutex, particularly during vTaskEndScheduler or exit calls. This is achieved by setting the PTHREAD_MUTEX_ROBUST attribute on the mutex. Fixes: - GitHub issue: FreeRTOS#1217 - Forum thread: freertos.org/t/22287 Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
1 parent b421abc commit 42135c1

File tree

1 file changed

+20
-4
lines changed

1 file changed

+20
-4
lines changed

portable/ThirdParty/GCC/Posix/utils/wait_for_event.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
struct event
3636
{
3737
pthread_mutex_t mutex;
38+
pthread_mutexattr_t mutexattr;
3839
pthread_cond_t cond;
3940
bool event_triggered;
4041
};
@@ -46,7 +47,9 @@ struct event * event_create( void )
4647
if( ev != NULL )
4748
{
4849
ev->event_triggered = false;
49-
pthread_mutex_init( &ev->mutex, NULL );
50+
pthread_mutexattr_init( &ev->mutexattr );
51+
pthread_mutexattr_setrobust( &ev->mutexattr, PTHREAD_MUTEX_ROBUST );
52+
pthread_mutex_init( &ev->mutex, &ev->mutexattr );
5053
pthread_cond_init( &ev->cond, NULL );
5154
}
5255

@@ -56,13 +59,18 @@ struct event * event_create( void )
5659
void event_delete( struct event * ev )
5760
{
5861
pthread_mutex_destroy( &ev->mutex );
62+
pthread_mutexattr_destroy( &ev->mutexattr );
5963
pthread_cond_destroy( &ev->cond );
6064
free( ev );
6165
}
6266

6367
bool event_wait( struct event * ev )
6468
{
65-
pthread_mutex_lock( &ev->mutex );
69+
if( pthread_mutex_lock( &ev->mutex ) == EOWNERDEAD )
70+
{
71+
/* If the thread owning the mutex died, make the mutex consistent. */
72+
pthread_mutex_consistent( &ev->mutex );
73+
}
6674

6775
while( ev->event_triggered == false )
6876
{
@@ -82,7 +90,11 @@ bool event_wait_timed( struct event * ev,
8290
clock_gettime( CLOCK_REALTIME, &ts );
8391
ts.tv_sec += ms / 1000;
8492
ts.tv_nsec += ( ( ms % 1000 ) * 1000000 );
85-
pthread_mutex_lock( &ev->mutex );
93+
if( pthread_mutex_lock( &ev->mutex ) == EOWNERDEAD )
94+
{
95+
/* If the thread owning the mutex died, make the mutex consistent. */
96+
pthread_mutex_consistent( &ev->mutex );
97+
}
8698

8799
while( ( ev->event_triggered == false ) && ( ret == 0 ) )
88100
{
@@ -101,7 +113,11 @@ bool event_wait_timed( struct event * ev,
101113

102114
void event_signal( struct event * ev )
103115
{
104-
pthread_mutex_lock( &ev->mutex );
116+
if( pthread_mutex_lock( &ev->mutex ) == EOWNERDEAD )
117+
{
118+
/* If the thread owning the mutex died, make the mutex consistent. */
119+
pthread_mutex_consistent( &ev->mutex );
120+
}
105121
ev->event_triggered = true;
106122
pthread_cond_signal( &ev->cond );
107123
pthread_mutex_unlock( &ev->mutex );

0 commit comments

Comments
 (0)