score: Use PTHREAD_CANCELED for _Thread_Cancel()

The rtems_task_delete() directive is basically just a combined pthread_cancel()
and pthread_join().  In addition, it removes the PTHREAD_DETACHED state.  The
exit value returned by pthread_join() of threads cancelled by
rtems_task_delete() should reflect this by getting a PTHREAD_CANCELED value
instead of NULL which could be a normal exit value.

Close #4680.
This commit is contained in:
Sebastian Huber
2022-07-19 10:38:12 +02:00
parent 31036f1dc8
commit 8a864bc62c
4 changed files with 8 additions and 11 deletions

View File

@@ -429,14 +429,11 @@ typedef enum {
* @param[in, out] life_states_to_clear is the set of thread life states to * @param[in, out] life_states_to_clear is the set of thread life states to
* clear for the thread to cancel. * clear for the thread to cancel.
* @param exit_value is the exit value for the thread to cancel.
*/ */
Thread_Cancel_state _Thread_Cancel( Thread_Cancel_state _Thread_Cancel(
Thread_Control *the_thread, Thread_Control *the_thread,
Thread_Control *executing, Thread_Control *executing,
Thread_Life_state life_states_to_clear, Thread_Life_state life_states_to_clear
void *exit_value
); );
/** /**

View File

@@ -75,7 +75,7 @@ int pthread_cancel( pthread_t thread )
} else { } else {
_Thread_Dispatch_disable_with_CPU( cpu_self, &lock_context ); _Thread_Dispatch_disable_with_CPU( cpu_self, &lock_context );
_ISR_lock_ISR_enable( &lock_context ); _ISR_lock_ISR_enable( &lock_context );
(void) _Thread_Cancel( the_thread, executing, 0, PTHREAD_CANCELED ); (void) _Thread_Cancel( the_thread, executing, 0 );
_Thread_Dispatch_enable( cpu_self ); _Thread_Dispatch_enable( cpu_self );
} }
return 0; return 0;

View File

@@ -55,6 +55,8 @@
#include <rtems/score/userextimpl.h> #include <rtems/score/userextimpl.h>
#include <rtems/score/watchdogimpl.h> #include <rtems/score/watchdogimpl.h>
#include <pthread.h>
#define THREAD_JOIN_TQ_OPERATIONS &_Thread_queue_Operations_priority_inherit #define THREAD_JOIN_TQ_OPERATIONS &_Thread_queue_Operations_priority_inherit
static void _Thread_Life_action_handler( static void _Thread_Life_action_handler(
@@ -433,8 +435,7 @@ static void _Thread_Try_life_change_request(
Thread_Cancel_state _Thread_Cancel( Thread_Cancel_state _Thread_Cancel(
Thread_Control *the_thread, Thread_Control *the_thread,
Thread_Control *executing, Thread_Control *executing,
Thread_Life_state life_states_to_clear, Thread_Life_state life_states_to_clear
void *exit_value
) )
{ {
ISR_lock_Context lock_context; ISR_lock_Context lock_context;
@@ -444,7 +445,7 @@ Thread_Cancel_state _Thread_Cancel(
_Thread_State_acquire( the_thread, &lock_context ); _Thread_State_acquire( the_thread, &lock_context );
_Thread_Set_exit_value( the_thread, exit_value ); _Thread_Set_exit_value( the_thread, PTHREAD_CANCELED );
previous = _Thread_Change_life_locked( previous = _Thread_Change_life_locked(
the_thread, the_thread,
life_states_to_clear, life_states_to_clear,
@@ -476,8 +477,7 @@ Status_Control _Thread_Close(
); );
_ISR_lock_ISR_enable( &queue_context->Lock_context.Lock_context ); _ISR_lock_ISR_enable( &queue_context->Lock_context.Lock_context );
cancel_state = cancel_state = _Thread_Cancel( the_thread, executing, THREAD_LIFE_DETACHED );
_Thread_Cancel( the_thread, executing, THREAD_LIFE_DETACHED, NULL );
if ( cancel_state == THREAD_CANCEL_DONE ) { if ( cancel_state == THREAD_CANCEL_DONE ) {
_Thread_Dispatch_enable( cpu_self ); _Thread_Dispatch_enable( cpu_self );

View File

@@ -146,7 +146,7 @@ static void test_delete_deadlock( void )
value = NULL; value = NULL;
eno = pthread_join( ctx.protected_join, &value ); eno = pthread_join( ctx.protected_join, &value );
rtems_test_assert( eno == 0 ); rtems_test_assert( eno == 0 );
rtems_test_assert( value == NULL ); rtems_test_assert( value == PTHREAD_CANCELED );
rtems_test_assert( ctx.delete_status == RTEMS_INCORRECT_STATE ); rtems_test_assert( ctx.delete_status == RTEMS_INCORRECT_STATE );
} }