From 5e9b32b439627068a0292370fe595220dbfc95a0 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Tue, 26 Sep 1995 19:27:15 +0000 Subject: posix support initially added --- cpukit/posix/src/cancel.c | 226 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 cpukit/posix/src/cancel.c (limited to 'cpukit/posix/src/cancel.c') diff --git a/cpukit/posix/src/cancel.c b/cpukit/posix/src/cancel.c new file mode 100644 index 0000000000..32a9a90890 --- /dev/null +++ b/cpukit/posix/src/cancel.c @@ -0,0 +1,226 @@ +/* cancel.c + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * POSIX_Thread_cancel_run + * + */ + +void POSIX_Thread_cancel_run( + Thread_Control *the_thread +) +{ + int old_cancel_state; + POSIX_Cancel_Handler_control *handler; + Chain_Control *handler_stack; + POSIX_API_Thread_Support_Control *thread_support; + ISR_Level level; + + thread_support = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + 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 ) ) { + _ISR_Disable( level ); + handler = (POSIX_Cancel_Handler_control *) _Chain_Tail( handler_stack ); + _Chain_Extract_unprotected( &handler->Node ); + _ISR_Enable( level ); + + (*handler->routine)( handler->arg ); + + _Workspace_Free( handler ); + } + + thread_support->cancelation_requested = 0; + + thread_support->cancelability_state = old_cancel_state; +} + +/*PAGE + * + * 18.2.1 Canceling Execution of a Thread, P1003.1c/Draft 10, p. 181 + */ + +int pthread_cancel( + pthread_t thread +) +{ + Thread_Control *the_thread; + POSIX_API_Thread_Support_Control *thread_support; + Objects_Locations location; + + the_thread = _POSIX_Threads_Get( &thread, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return EINVAL; + case OBJECTS_REMOTE: + return POSIX_MP_NOT_IMPLEMENTED(); + case OBJECTS_LOCAL: + thread_support = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + thread_support->cancelation_requested = 1; + + _Thread_Enable_dispatch(); + return 0; + } + + return POSIX_BOTTOM_REACHED(); +} + +/*PAGE + * + * 18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183 + */ + +int pthread_setcancelstate( + int state, + int *oldstate +) +{ + POSIX_API_Thread_Support_Control *thread_support; + + if ( !oldstate ) + return EINVAL; + + if ( state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE ) + return EINVAL; + + thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; + + *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 ); + + return 0; +} + +/*PAGE + * + * 18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183 + */ + +int pthread_setcanceltype( + int type, + int *oldtype +) +{ + POSIX_API_Thread_Support_Control *thread_support; + + if ( !oldtype ) + return EINVAL; + + if ( type != PTHREAD_CANCEL_DEFERRED && type != PTHREAD_CANCEL_ASYNCHRONOUS ) + return EINVAL; + + thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; + + *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 ); + + return 0; +} + +/*PAGE + * + * 18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183 + */ + +void pthread_testcancel( void ) +{ + POSIX_API_Thread_Support_Control *thread_support; + + 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 ); +} + +/*PAGE + * + * 18.2.3.1 Establishing Cancellation Handlers, P1003.1c/Draft 10, p. 184 + */ + +void pthread_cleanup_push( + void (*routine)( void * ), + void *arg +) +{ + POSIX_Cancel_Handler_control *handler; + Chain_Control *handler_stack; + POSIX_API_Thread_Support_Control *thread_support; + + if ( !routine ) + return; /* XXX what to do really? */ + + handler = _Workspace_Allocate( sizeof( POSIX_Cancel_Handler_control ) ); + + if ( !handler ) + return; /* XXX what to do really? */ + + thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; + + handler_stack = &thread_support->Cancellation_Handlers; + + handler->routine = routine; + handler->arg = arg; + + _Chain_Append( handler_stack, &handler->Node ); +} + +/*PAGE + * + * 18.2.3.1 Establishing Cancellation Handlers, P1003.1c/Draft 10, p. 184 + */ + +void pthread_cleanup_pop( + int execute +) +{ + POSIX_Cancel_Handler_control *handler; + Chain_Control *handler_stack; + POSIX_API_Thread_Support_Control *thread_support; + ISR_Level level; + + thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; + + handler_stack = &thread_support->Cancellation_Handlers; + + if ( _Chain_Is_empty( handler_stack ) ) + return; + + _ISR_Disable( level ); + handler = (POSIX_Cancel_Handler_control *) _Chain_Tail( handler_stack ); + _Chain_Extract_unprotected( &handler->Node ); + _ISR_Enable( level ); + + if ( execute ) + (*handler->routine)( handler->arg ); + + _Workspace_Free( handler ); +} -- cgit v1.2.3