Skip to content

Commit

Permalink
Mark mutex as robust to prevent deadlocks
Browse files Browse the repository at this point in the history
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: #1217
- Forum thread: freertos.org/t/22287

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
  • Loading branch information
aggarg committed Jan 25, 2025
1 parent b421abc commit 42135c1
Showing 1 changed file with 20 additions and 4 deletions.
24 changes: 20 additions & 4 deletions portable/ThirdParty/GCC/Posix/utils/wait_for_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
struct event
{
pthread_mutex_t mutex;
pthread_mutexattr_t mutexattr;
pthread_cond_t cond;
bool event_triggered;
};
Expand All @@ -46,7 +47,9 @@ struct event * event_create( void )
if( ev != NULL )
{
ev->event_triggered = false;
pthread_mutex_init( &ev->mutex, NULL );
pthread_mutexattr_init( &ev->mutexattr );
pthread_mutexattr_setrobust( &ev->mutexattr, PTHREAD_MUTEX_ROBUST );
pthread_mutex_init( &ev->mutex, &ev->mutexattr );
pthread_cond_init( &ev->cond, NULL );
}

Expand All @@ -56,13 +59,18 @@ struct event * event_create( void )
void event_delete( struct event * ev )
{
pthread_mutex_destroy( &ev->mutex );
pthread_mutexattr_destroy( &ev->mutexattr );
pthread_cond_destroy( &ev->cond );
free( ev );
}

bool event_wait( struct event * ev )
{
pthread_mutex_lock( &ev->mutex );
if( pthread_mutex_lock( &ev->mutex ) == EOWNERDEAD )
{
/* If the thread owning the mutex died, make the mutex consistent. */
pthread_mutex_consistent( &ev->mutex );
}

while( ev->event_triggered == false )
{
Expand All @@ -82,7 +90,11 @@ bool event_wait_timed( struct event * ev,
clock_gettime( CLOCK_REALTIME, &ts );
ts.tv_sec += ms / 1000;
ts.tv_nsec += ( ( ms % 1000 ) * 1000000 );
pthread_mutex_lock( &ev->mutex );
if( pthread_mutex_lock( &ev->mutex ) == EOWNERDEAD )
{
/* If the thread owning the mutex died, make the mutex consistent. */
pthread_mutex_consistent( &ev->mutex );
}

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

void event_signal( struct event * ev )
{
pthread_mutex_lock( &ev->mutex );
if( pthread_mutex_lock( &ev->mutex ) == EOWNERDEAD )
{
/* If the thread owning the mutex died, make the mutex consistent. */
pthread_mutex_consistent( &ev->mutex );
}
ev->event_triggered = true;
pthread_cond_signal( &ev->cond );
pthread_mutex_unlock( &ev->mutex );
Expand Down

0 comments on commit 42135c1

Please sign in to comment.