diff options
| -rw-r--r-- | ChangeLog | 17 | ||||
| -rw-r--r-- | cancel.c | 38 | ||||
| -rw-r--r-- | create.c | 12 | ||||
| -rw-r--r-- | exit.c | 1 | ||||
| -rw-r--r-- | implement.h | 9 | ||||
| -rw-r--r-- | pthread.h | 7 | 
6 files changed, 74 insertions, 10 deletions
| @@ -1,3 +1,20 @@ +Fri Jul 24 21:13:55 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> + +	* 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  <bje@cygnus.com>  	* pthread.h (SIG_BLOCK): Define if not already defined. @@ -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. */ +    } +} @@ -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);      } @@ -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; @@ -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 | 
