From f845e96e7beef7d6db35c80e0075dcb07a71dce3 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 5 Jul 2002 18:13:18 +0000 Subject: 2002-07-05 Joel Sherrill * include/rtems/posix/cancel.h, src/cancel.c, src/cancelrun.c, src/mqueue.c, src/pthread.c, src/semaphore.c, src/setcancelstate.c, src/setcanceltype.c, src/testcancel.c: Per PR164, corrected the behavior of thread cancellation and did some cleanup as a side-effect. --- c/src/exec/posix/ChangeLog | 7 +++++++ c/src/exec/posix/include/rtems/posix/cancel.h | 4 ++-- c/src/exec/posix/src/cancel.c | 12 ++++++++++++ c/src/exec/posix/src/cancelrun.c | 22 +++++++++++++++------- c/src/exec/posix/src/mqueue.c | 2 +- c/src/exec/posix/src/pthread.c | 7 +++++-- c/src/exec/posix/src/semaphore.c | 2 +- c/src/exec/posix/src/setcancelstate.c | 23 +++++++++++++++++------ c/src/exec/posix/src/setcanceltype.c | 23 +++++++++++++++++------ c/src/exec/posix/src/testcancel.c | 17 ++++++++++++++--- 10 files changed, 91 insertions(+), 28 deletions(-) (limited to 'c/src/exec/posix') diff --git a/c/src/exec/posix/ChangeLog b/c/src/exec/posix/ChangeLog index b90a5ff854..1e6184b3fa 100644 --- a/c/src/exec/posix/ChangeLog +++ b/c/src/exec/posix/ChangeLog @@ -1,3 +1,10 @@ +2002-07-05 Joel Sherrill + + * include/rtems/posix/cancel.h, src/cancel.c, src/cancelrun.c, + src/mqueue.c, src/pthread.c, src/semaphore.c, src/setcancelstate.c, + src/setcanceltype.c, src/testcancel.c: Per PR164, corrected the + behavior of thread cancellation and did some cleanup as a side-effect. + 2002-07-05 Ralf Corsepius * configure.ac: RTEMS_TOP(../..). diff --git a/c/src/exec/posix/include/rtems/posix/cancel.h b/c/src/exec/posix/include/rtems/posix/cancel.h index f50b8c6f06..935912a298 100644 --- a/c/src/exec/posix/include/rtems/posix/cancel.h +++ b/c/src/exec/posix/include/rtems/posix/cancel.h @@ -13,7 +13,7 @@ typedef struct { } POSIX_Cancel_Handler_control; /* - * _POSIX_Thread_cancel_run + * _POSIX_Threads_cancel_run * * DESCRIPTION: * @@ -21,7 +21,7 @@ typedef struct { * have been registered and executes them. */ -void _POSIX_Thread_cancel_run( +void _POSIX_Threads_cancel_run( Thread_Control *the_thread ); diff --git a/c/src/exec/posix/src/cancel.c b/c/src/exec/posix/src/cancel.c index 88012040fb..f1310d5ab1 100644 --- a/c/src/exec/posix/src/cancel.c +++ b/c/src/exec/posix/src/cancel.c @@ -31,6 +31,13 @@ int pthread_cancel( POSIX_API_Control *thread_support; Objects_Locations location; + /* + * Don't even think about deleting a resource from an ISR. + */ + + if ( _ISR_Is_in_progress() ) + return EPROTO; + the_thread = _POSIX_Threads_Get( thread, &location ); switch ( location ) { case OBJECTS_ERROR: @@ -42,6 +49,11 @@ int pthread_cancel( thread_support->cancelation_requested = 1; + if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE && + thread_support->cancelability_type == PTHREAD_CANCEL_ASYNCHRONOUS ) { + _POSIX_Threads_cancel_run( the_thread ); + } + _Thread_Enable_dispatch(); return 0; } diff --git a/c/src/exec/posix/src/cancelrun.c b/c/src/exec/posix/src/cancelrun.c index 1a120ba504..4806e6d378 100644 --- a/c/src/exec/posix/src/cancelrun.c +++ b/c/src/exec/posix/src/cancelrun.c @@ -20,15 +20,19 @@ /*PAGE * - * _POSIX_Thread_cancel_run + * _POSIX_Threads_cancel_run * */ -void _POSIX_Thread_cancel_run( +#if !defined(PTHREAD_CANCELED) +#warning "PTHREAD_CANCELED NOT DEFINED -- patch newlib" +#define PTHREAD_CANCELED ((void *) -1) +#endif + +void _POSIX_Threads_cancel_run( Thread_Control *the_thread ) { - int old_cancel_state; POSIX_Cancel_Handler_control *handler; Chain_Control *handler_stack; POSIX_API_Control *thread_support; @@ -38,8 +42,6 @@ void _POSIX_Thread_cancel_run( handler_stack = &thread_support->Cancellation_Handlers; - old_cancel_state = thread_support->cancelability_state; - thread_support->cancelability_state = PTHREAD_CANCEL_DISABLE; while ( !_Chain_Is_empty( handler_stack ) ) { @@ -53,7 +55,13 @@ void _POSIX_Thread_cancel_run( _Workspace_Free( handler ); } - thread_support->cancelation_requested = 0; + /* Now we can delete the thread */ + + the_thread->Wait.return_argument = (unsigned32 *)PTHREAD_CANCELED; + _Thread_Close( + _Objects_Get_information( the_thread->Object.id ), + the_thread + ); + _POSIX_Threads_Free( the_thread ); - thread_support->cancelability_state = old_cancel_state; } diff --git a/c/src/exec/posix/src/mqueue.c b/c/src/exec/posix/src/mqueue.c index 8a97d50505..28003b8eee 100644 --- a/c/src/exec/posix/src/mqueue.c +++ b/c/src/exec/posix/src/mqueue.c @@ -55,7 +55,7 @@ void _POSIX_Message_queue_Manager_initialization( maximum_message_queues, /* maximum objects of this class */ sizeof( POSIX_Message_queue_Control ), /* size of this object's control block */ - FALSE, /* TRUE if names for this object are strings */ + TRUE, /* TRUE if names for this object are strings */ _POSIX_PATH_MAX /* maximum length of each object's name */ #if defined(RTEMS_MULTIPROCESSING) , diff --git a/c/src/exec/posix/src/pthread.c b/c/src/exec/posix/src/pthread.c index e1bade3baf..e91bcd4708 100644 --- a/c/src/exec/posix/src/pthread.c +++ b/c/src/exec/posix/src/pthread.c @@ -207,7 +207,9 @@ User_extensions_routine _POSIX_Threads_Delete_extension( api = deleted->API_Extensions[ THREAD_API_POSIX ]; - /* XXX run cancellation handlers */ + /* + * Run the POSIX cancellation handlers + */ _POSIX_Keys_Run_destructors( deleted ); @@ -373,8 +375,9 @@ void _POSIX_Threads_Manager_initialization( */ _User_extensions_Add_API_set( &_POSIX_Threads_User_extensions ); - + _API_extensions_Add( &_POSIX_Threads_API_extensions ); + /* * If we supported MP, then here we would ... diff --git a/c/src/exec/posix/src/semaphore.c b/c/src/exec/posix/src/semaphore.c index e3f6ec9c84..1fdca2d4ab 100644 --- a/c/src/exec/posix/src/semaphore.c +++ b/c/src/exec/posix/src/semaphore.c @@ -43,7 +43,7 @@ void _POSIX_Semaphore_Manager_initialization( maximum_semaphores /* maximum objects of this class */, sizeof( POSIX_Semaphore_Control ), /* size of this object's control block */ - FALSE, /* TRUE if names for this object are strings */ + TRUE, /* TRUE if names for this object are strings */ _POSIX_PATH_MAX /* maximum length of each object's name */ #if defined(RTEMS_MULTIPROCESSING) , diff --git a/c/src/exec/posix/src/setcancelstate.c b/c/src/exec/posix/src/setcancelstate.c index 8a1df67c9d..4a2fb1f93f 100644 --- a/c/src/exec/posix/src/setcancelstate.c +++ b/c/src/exec/posix/src/setcancelstate.c @@ -30,6 +30,15 @@ int pthread_setcancelstate( { POSIX_API_Control *thread_support; + /* + * Don't even think about deleting a resource from an ISR. + * Besides this request is supposed to be for _Thread_Executing + * and the ISR context is not a thread. + */ + + if ( _ISR_Is_in_progress() ) + return EPROTO; + if ( !oldstate ) return EINVAL; @@ -38,13 +47,15 @@ int pthread_setcancelstate( thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; - *oldstate = thread_support->cancelability_state; - thread_support->cancelability_state = state; + _Thread_Disable_dispatch(); + *oldstate = thread_support->cancelability_state; + thread_support->cancelability_state = state; - if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE && - thread_support->cancelability_type == PTHREAD_CANCEL_ASYNCHRONOUS && - thread_support->cancelation_requested ) - _POSIX_Thread_cancel_run( _Thread_Executing ); + if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE && + thread_support->cancelability_type == PTHREAD_CANCEL_ASYNCHRONOUS && + thread_support->cancelation_requested ) + _POSIX_Threads_cancel_run( _Thread_Executing ); + _Thread_Enable_dispatch(); return 0; } diff --git a/c/src/exec/posix/src/setcanceltype.c b/c/src/exec/posix/src/setcanceltype.c index ae8de273c4..aff7d84dda 100644 --- a/c/src/exec/posix/src/setcanceltype.c +++ b/c/src/exec/posix/src/setcanceltype.c @@ -30,6 +30,15 @@ int pthread_setcanceltype( { POSIX_API_Control *thread_support; + /* + * Don't even think about deleting a resource from an ISR. + * Besides this request is supposed to be for _Thread_Executing + * and the ISR context is not a thread. + */ + + if ( _ISR_Is_in_progress() ) + return EPROTO; + if ( !oldtype ) return EINVAL; @@ -38,13 +47,15 @@ int pthread_setcanceltype( thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; - *oldtype = thread_support->cancelability_type; - thread_support->cancelability_type = type; + _Thread_Disable_dispatch(); + *oldtype = thread_support->cancelability_type; + thread_support->cancelability_type = type; - if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE && - thread_support->cancelability_type == PTHREAD_CANCEL_ASYNCHRONOUS && - thread_support->cancelation_requested ) - _POSIX_Thread_cancel_run( _Thread_Executing ); + if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE && + thread_support->cancelability_type == PTHREAD_CANCEL_ASYNCHRONOUS && + thread_support->cancelation_requested ) + _POSIX_Threads_cancel_run( _Thread_Executing ); + _Thread_Enable_dispatch(); return 0; } diff --git a/c/src/exec/posix/src/testcancel.c b/c/src/exec/posix/src/testcancel.c index b4007526de..08a423747f 100644 --- a/c/src/exec/posix/src/testcancel.c +++ b/c/src/exec/posix/src/testcancel.c @@ -27,9 +27,20 @@ void pthread_testcancel( void ) { POSIX_API_Control *thread_support; + /* + * Don't even think about deleting a resource from an ISR. + * Besides this request is supposed to be for _Thread_Executing + * and the ISR context is not a thread. + */ + + if ( _ISR_Is_in_progress() ) + return; + thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; - if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE && - thread_support->cancelation_requested ) - _POSIX_Thread_cancel_run( _Thread_Executing ); + _Thread_Disable_dispatch(); + if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE && + thread_support->cancelation_requested ) + _POSIX_Threads_cancel_run( _Thread_Executing ); + _Thread_Enable_dispatch(); } -- cgit v1.2.3