From eafdb5db2871e893574fd0da01554d1a50b7471f Mon Sep 17 00:00:00 2001 From: rpj Date: Fri, 24 Jul 1998 12:21:27 +0000 Subject: Fri Jul 24 21:13:55 1998 Ross Johnson * cancel.c (pthread_cancel): Implement. (pthread_testcancel): Implement. * exit.c (pthread_exit): Add comment explaining the longjmp(). * implement.h (_pthread_threads_thread_t): New member cancelthread. (_PTHREAD_YES): Define. (_PTHREAD_NO): Define. (RND_SIZEOF): Remove. * create.c (pthread_create): Rename cancelability to cancelstate. * pthread.h (pthread_attr_t): Rename cancelability to cancelstate. (PTHREAD_CANCELED): Define. --- ChangeLog | 17 +++++++++++++++++ cancel.c | 38 ++++++++++++++++++++++++++++++++++++++ create.c | 12 ++++++++---- exit.c | 1 + implement.h | 9 ++++----- pthread.h | 7 ++++++- 6 files changed, 74 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index e13ca49..47e8acf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +Fri Jul 24 21:13:55 1998 Ross Johnson + + * cancel.c (pthread_cancel): Implement. + (pthread_testcancel): Implement. + + * exit.c (pthread_exit): Add comment explaining the longjmp(). + + * implement.h (_pthread_threads_thread_t): New member cancelthread. + (_PTHREAD_YES): Define. + (_PTHREAD_NO): Define. + (RND_SIZEOF): Remove. + + * create.c (pthread_create): Rename cancelability to cancelstate. + + * pthread.h (pthread_attr_t): Rename cancelability to cancelstate. + (PTHREAD_CANCELED): Define. + 1998-07-24 Ben Elliston * pthread.h (SIG_BLOCK): Define if not already defined. diff --git a/cancel.c b/cancel.c index 72c41ad..e9e33f1 100644 --- a/cancel.c +++ b/cancel.c @@ -47,3 +47,41 @@ pthread_setcanceltype(int type, int *oldtype) this->canceltype = type; return 0; } + +int +pthread_cancel(pthread_t thread) +{ + _pthread_threads_thread_t * this; + + this = _PTHREAD_THIS; + + if (this == NULL) + { + return ESRCH; + } + + this->cancelthread = _PTHREAD_YES; + + return 0; +} + +void +pthread_testcancel(void) +{ + _pthread_threads_thread_t * this; + + this = _PTHREAD_THIS; + + if (this == NULL || + this->attr.cancelstate == PTHREAD_CANCEL_DISABLE) + { + return; + } + + if (this->cancelthread == _PTHREAD_YES) + { + pthread_exit(PTHREAD_CANCELED); + + /* Never reached. */ + } +} diff --git a/create.c b/create.c index 74d207d..ce12849 100644 --- a/create.c +++ b/create.c @@ -19,13 +19,15 @@ _pthread_start_call(void * thisarg) /* We're now in a running thread. Any local variables here are on this threads private stack so we're safe to leave data in them until we leave. */ - _pthread_threads_thread__t * this = thisarg; + _pthread_threads_thread__t * this; _pthread_call_t * call; unsigned (*func)(void *); void * arg; unsigned ret; int from; + this = (_pthread_threads_thread__t *) thisarg; + if (this->detached == PTHREAD_CREATE_DETACHED) { (void) CloseHandle(this->thread); @@ -39,13 +41,15 @@ _pthread_start_call(void * thisarg) if (from == 0) { + /* Normal return from setjmp(). */ ret = (*func)(arg); _pthread_vacuum(); } else { - /* func() called pthread_exit() which called longjmp(). */ + /* longjmp() teleported us here. + func() called pthread_exit() which called longjmp(). */ _pthread_vacuum(); /* Never returns. */ @@ -82,7 +86,7 @@ pthread_create(pthread_t *thread, attr_copy->stacksize = PTHREAD_STACK_MIN; } - attr_copy->cancelability = attr->cancelability; + attr_copy->cancelstate = attr->cancelstate; attr_copy->canceltype = attr->canceltype; attr_copy->detached = attr->detached; attr_copy->priority = attr->priority; @@ -119,7 +123,7 @@ pthread_create(pthread_t *thread, } else { - /* Undo everything. */ + /* Remove the failed thread entry. */ _pthread_delete_thread_entry(this); } diff --git a/exit.c b/exit.c index 1e07ccd..a32e0ca 100644 --- a/exit.c +++ b/exit.c @@ -48,5 +48,6 @@ pthread_exit(void * value) /* FIXME: More to do here. IE, if pthread_detach() was called and value != NULL, do we free(value)? */ + /* Teleport back to _pthread_start_call() to cleanup and exit. */ longjmp(this->call.env, 1); } diff --git a/implement.h b/implement.h index 4a9a5ad..033e0e8 100644 --- a/implement.h +++ b/implement.h @@ -9,6 +9,9 @@ #define _PTHREAD_HASH_INDEX(x) (((ULONG) x) % PTHREAD_THREADS_MAX) +#define _PTHREAD_YES 1 +#define _PTHREAD_NO 0 + /* Handler execution flags. */ #define _PTHREAD_HANDLER_NOEXECUTE 0 #define _PTHREAD_HANDLER_EXECUTE 1 @@ -19,11 +22,6 @@ enum { _PTHREAD_HANDLER_POP_LIFO, _PTHREAD_HANDLER_POP_FIFO }; /* Special value to mark attribute objects as valid. */ #define _PTHREAD_ATTR_INVALID 0xC0FFEE -/* Round a sizeof(type) up to a multiple of sizeof(DWORD). - This is all compile time arithmetic. - */ -#define RND_SIZEOF(T) (((sizeof(T) / sizeof(DWORD)) + 1) * sizeof(DWORD)) - /* General description of a handler function on a stack. */ typedef struct _pthread_handler_node _pthread_handler_node_t; @@ -52,6 +50,7 @@ struct _pthread_threads_thread { pthread_t thread; pthread_attr_t attr; _pthread_call_t call; + int cancelthread; void ** joinvalueptr; _pthread_handler_node_t * cleanupstack; _pthread_handler_node_t * destructorstack; diff --git a/pthread.h b/pthread.h index 70ece60..de84697 100644 --- a/pthread.h +++ b/pthread.h @@ -70,6 +70,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define PTHREAD_CANCEL_ASYNCHRONOUS 0 #define PTHREAD_CANCEL_DEFERRED 1 +/* Cancelation return value. + This value must be neither NULL nor the value of any + pointer to an object in memory. */ +#define PTHREAD_CANCELED ((void *) 1) + typedef HANDLE pthread_t; typedef CRITICAL_SECTION pthread_mutex_t; typedef DWORD pthread_key_t; @@ -83,7 +88,7 @@ typedef struct { size_t stacksize; /* PTHREAD_STACK_MIN */ #endif - int cancelability; /* PTHREAD_CANCEL_DISABLE + int cancelstate; /* PTHREAD_CANCEL_DISABLE PTHREAD_CANCEL_ENABLE */ int detached; /* PTHREAD_CREATE_DETACHED -- cgit v1.2.3