From fea848bbbc8b63204677765cdcf8f5957e0ccf86 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 17 Feb 2021 08:05:37 +0100 Subject: score: Change thread action locking Require that the corresponding lock is acquired before the action handler returns. This helps to avoid recursion in the signal processing. Update #4244. --- cpukit/include/rtems/score/thread.h | 19 +++++++++++-------- cpukit/posix/src/psignalunblockthread.c | 2 ++ cpukit/rtems/src/signalcatch.c | 6 ++++-- cpukit/score/src/threaddispatch.c | 3 --- 4 files changed, 17 insertions(+), 13 deletions(-) (limited to 'cpukit') diff --git a/cpukit/include/rtems/score/thread.h b/cpukit/include/rtems/score/thread.h index 0920a44177..e23261701a 100644 --- a/cpukit/include/rtems/score/thread.h +++ b/cpukit/include/rtems/score/thread.h @@ -594,20 +594,23 @@ typedef enum { typedef struct Thread_Action Thread_Action; /** - * @brief Thread action handler. + * @brief This type defines the prototype of thread action handlers. * * The thread action handler will be called with interrupts disabled and a - * corresponding lock acquired, e.g. _Thread_State_acquire(). The handler must - * release the corresponding lock, e.g. _Thread_State_release(). So, the - * corresponding lock may be used to protect private data used by the - * particular action. + * corresponding lock acquired, e.g. _Thread_State_acquire(). The handler may + * release the corresponding lock, e.g. _Thread_State_release(). If the lock + * is released, it shall be acquired before the handler returns using the lock + * context. The lock may be used to protect private data used by the action. * * Since the action is passed to the handler additional data may be accessed * via RTEMS_CONTAINER_OF(). * - * @param[in] the_thread The thread performing the action. - * @param[in] action The thread action. - * @param[in] lock_context The lock context to use for the lock release. + * @param[in, out] the_thread is the thread performing the action. + * + * @param[in, out] action is the thread action. + * + * @param[in, out] lock_context is the lock context to use for the optional + * lock release and acquire. */ typedef void ( *Thread_Action_handler )( Thread_Control *the_thread, diff --git a/cpukit/posix/src/psignalunblockthread.c b/cpukit/posix/src/psignalunblockthread.c index 80a0f33a09..63ed823ab3 100644 --- a/cpukit/posix/src/psignalunblockthread.c +++ b/cpukit/posix/src/psignalunblockthread.c @@ -159,6 +159,8 @@ static void _POSIX_signals_Action_handler( } executing->Wait.return_code = hold_errno; + + _Thread_State_acquire( executing, lock_context ); } static bool _POSIX_signals_Unblock_thread_done( diff --git a/cpukit/rtems/src/signalcatch.c b/cpukit/rtems/src/signalcatch.c index c59e132ad3..2fd7c13374 100644 --- a/cpukit/rtems/src/signalcatch.c +++ b/cpukit/rtems/src/signalcatch.c @@ -51,12 +51,12 @@ void _Signal_Action_handler( asr = &api->Signal; signal_set = _ASR_Get_posted_signals( asr ); - _Thread_State_release( executing, lock_context ); - if ( signal_set == 0 ) { return; } + _Thread_State_release( executing, lock_context ); + asr->nest_level += 1; rtems_task_mode( asr->mode_set, RTEMS_ALL_MODE_MASKS, &prev_mode ); @@ -64,6 +64,8 @@ void _Signal_Action_handler( asr->nest_level -= 1; rtems_task_mode( prev_mode, RTEMS_ALL_MODE_MASKS, &prev_mode ); + + _Thread_State_acquire( executing, lock_context ); } rtems_status_code rtems_signal_catch( diff --git a/cpukit/score/src/threaddispatch.c b/cpukit/score/src/threaddispatch.c index c4dadc0ff1..bae2902bda 100644 --- a/cpukit/score/src/threaddispatch.c +++ b/cpukit/score/src/threaddispatch.c @@ -249,10 +249,7 @@ static void _Thread_Run_post_switch_actions( Thread_Control *executing ) while ( action != NULL ) { _Chain_Set_off_chain( &action->Node ); - ( *action->handler )( executing, action, &lock_context ); - - _Thread_State_acquire( executing, &lock_context ); action = _Thread_Get_post_switch_action( executing ); } -- cgit v1.2.3