mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
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/FreeRTOS-Kernel#1217 - Forum thread: freertos.org/t/22287 Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
This commit is contained in:
parent
b421abc7c3
commit
42135c1a22
|
@ -35,6 +35,7 @@
|
||||||
struct event
|
struct event
|
||||||
{
|
{
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
|
pthread_mutexattr_t mutexattr;
|
||||||
pthread_cond_t cond;
|
pthread_cond_t cond;
|
||||||
bool event_triggered;
|
bool event_triggered;
|
||||||
};
|
};
|
||||||
|
@ -46,7 +47,9 @@ struct event * event_create( void )
|
||||||
if( ev != NULL )
|
if( ev != NULL )
|
||||||
{
|
{
|
||||||
ev->event_triggered = false;
|
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 );
|
pthread_cond_init( &ev->cond, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,13 +59,18 @@ struct event * event_create( void )
|
||||||
void event_delete( struct event * ev )
|
void event_delete( struct event * ev )
|
||||||
{
|
{
|
||||||
pthread_mutex_destroy( &ev->mutex );
|
pthread_mutex_destroy( &ev->mutex );
|
||||||
|
pthread_mutexattr_destroy( &ev->mutexattr );
|
||||||
pthread_cond_destroy( &ev->cond );
|
pthread_cond_destroy( &ev->cond );
|
||||||
free( ev );
|
free( ev );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool event_wait( struct event * 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 )
|
while( ev->event_triggered == false )
|
||||||
{
|
{
|
||||||
|
@ -82,7 +90,11 @@ bool event_wait_timed( struct event * ev,
|
||||||
clock_gettime( CLOCK_REALTIME, &ts );
|
clock_gettime( CLOCK_REALTIME, &ts );
|
||||||
ts.tv_sec += ms / 1000;
|
ts.tv_sec += ms / 1000;
|
||||||
ts.tv_nsec += ( ( ms % 1000 ) * 1000000 );
|
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 ) )
|
while( ( ev->event_triggered == false ) && ( ret == 0 ) )
|
||||||
{
|
{
|
||||||
|
@ -101,7 +113,11 @@ bool event_wait_timed( struct event * ev,
|
||||||
|
|
||||||
void event_signal( 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;
|
ev->event_triggered = true;
|
||||||
pthread_cond_signal( &ev->cond );
|
pthread_cond_signal( &ev->cond );
|
||||||
pthread_mutex_unlock( &ev->mutex );
|
pthread_mutex_unlock( &ev->mutex );
|
||||||
|
|
Loading…
Reference in a new issue