diff options
| -rw-r--r-- | ChangeLog | 22 | ||||
| -rw-r--r-- | cancel.c | 35 | ||||
| -rw-r--r-- | create.c | 15 | ||||
| -rw-r--r-- | implement.h | 7 | ||||
| -rw-r--r-- | private.c | 71 | ||||
| -rw-r--r-- | pthread.h | 6 | ||||
| -rw-r--r-- | sync.c | 56 | 
7 files changed, 122 insertions, 90 deletions
@@ -1,3 +1,25 @@ +Sun Jul 26 00:09:59 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> + +	* private.c (_pthread_delete_thread_entry): Mutex locks removed. +	Mutexes must be applied at the caller level. +	(_pthread_new_thread_entry): Ditto. +	(_pthread_new_thread_entry): Init cancelstate, canceltype, and +	cancel_pending to default values. +	(_pthread_new_thread_entry): Rename "this" to "new". +	(_pthread_find_thread_entry): Rename "this" to "entry". +	(_pthread_delete_thread_entry): Rename "thread_entry" to "entry". + +	* create.c (_pthread_start_call): Mutexes changed to +	_pthread_count_mutex. All access to the threads table entries is +	under the one mutex. Otherwise chaos reigns. + +Sat Jul 25 23:16:51 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> + +	* implement.h (_pthread_threads_thread): Move cancelstate and + 	canceltype members out of pthread_attr_t into here. + +	* fork.c (fork): Add comment. +  1998-07-25  Ben Elliston  <bje@cygnus.com>  	* fork.c (fork): Autoconfiscate. @@ -6,6 +6,7 @@   */  #include "pthread.h" +#include "implement.h"  int  pthread_setcancelstate(int state, @@ -14,53 +15,53 @@ pthread_setcancelstate(int state,    _pthread_threads_thread_t * this = *_PTHREAD_THIS;    /* Validate the new cancellation state. */ -  if (state != PTHREAD_CANCEL_ENABLE || state != PTHREAD_CANCEL_DISABLE) +  if (state != PTHREAD_CANCEL_ENABLE  +      || state != PTHREAD_CANCEL_DISABLE)      {        return EINVAL;      }    if (oldstate != NULL)      { -      *oldstate = this->cancelability; +      *oldstate = this->cancelstate;      } -  this->cancelability = state; +  this->cancelstate = state;    return 0;  }  int  pthread_setcanceltype(int type, int *oldtype)  { -  _pthread_threads_thread_t * this = *_PTHREAD_THIS; +  _pthread_threads_thread_t * us = _PTHREAD_THIS;    /* Validate the new cancellation type. */ -  if (type != PTHREAD_CANCEL_DEFERRED || type != PTHREAD_CANCEL_ASYNCHRONOUS) +  if (type != PTHREAD_CANCEL_DEFERRED  +      || type != PTHREAD_CANCEL_ASYNCHRONOUS)      {        return EINVAL;      }    if (oldtype != NULL)      { -      *oldtype = this->canceltype; +      *oldtype = us->canceltype;      } -  this->canceltype = type; +  us->canceltype = type;    return 0;  }  int  pthread_cancel(pthread_t thread)  { -  _pthread_threads_thread_t * this; - -  this = _PTHREAD_THIS; +  _pthread_threads_thread_t * us = _PTHREAD_THIS; -  if (this == NULL) +  if (us == NULL)      {        return ESRCH;      } -  this->cancelthread = _PTHREAD_YES; +  us->cancel_pending = TRUE;    return 0;  } @@ -68,17 +69,17 @@ pthread_cancel(pthread_t thread)  void  pthread_testcancel(void)  { -  _pthread_threads_thread_t * this; +  _pthread_threads_thread_t * us; -  this = _PTHREAD_THIS; +  us = _PTHREAD_THIS; -  if (this == NULL || -      this->attr.cancelstate == PTHREAD_CANCEL_DISABLE) +  if (us == NULL +      || us->cancelstate == PTHREAD_CANCEL_DISABLE)      {        return;      } -  if (this->cancelthread == _PTHREAD_YES) +  if (us->cancel_pending == TRUE)      {        pthread_exit(PTHREAD_CANCELED); @@ -20,7 +20,6 @@ _pthread_start_call(void * us_arg)       this threads private stack so we're safe to leave data in them       until we leave. */    _pthread_threads_thread__t * us; -  pthread_mutex_t * us_thread_mutex;    _pthread_call_t * call;    unsigned (*func)(void *);    void * arg; @@ -39,8 +38,6 @@ _pthread_start_call(void * us_arg)    func = us->call.routine;    arg = us->call.arg; -  us_thread_mutex = _PTHREAD_THREAD_MUTEX(us); -    /* FIXME: Should we be using sigsetjmp() here instead. */    from = setjmp(us->call.env); @@ -55,7 +52,7 @@ _pthread_start_call(void * us_arg)  	 was called and there are no waiting joins. */        /* CRITICAL SECTION */ -      pthread_mutex_lock(us_thread_mutex); +      pthread_mutex_lock(&_pthread_count_mutex);        if (us->detach == TRUE  	  && us->join_count == 0) @@ -63,7 +60,7 @@ _pthread_start_call(void * us_arg)  	  _pthread_delete_thread_entry(us);  	} -      pthread_mutex_lock(us_thread_mutex); +      pthread_mutex_lock(&_pthread_count_mutex);        /* END CRITICAL SECTION */      }    else @@ -76,7 +73,7 @@ _pthread_start_call(void * us_arg)  	 was called and there are no waiting joins. */        /* CRITICAL SECTION */ -      pthread_mutex_lock(us_thread_mutex); +      pthread_mutex_lock(&_pthread_count_mutex);        if (us->detach == TRUE  	  && us->join_count == 0) @@ -84,7 +81,7 @@ _pthread_start_call(void * us_arg)  	  _pthread_delete_thread_entry(us);  	} -      pthread_mutex_lock(us_thread_mutex); +      pthread_mutex_lock(&_pthread_count_mutex);        /* END CRITICAL SECTION */        ret = 0; @@ -130,10 +127,10 @@ pthread_create(pthread_t *thread,  #if HAVE_SIGSET_T  	  memcpy(&(attr_copy->sigmask), &(attr->sigmask), sizeof(sigset_t));   #endif /* HAVE_SIGSET_T */ - -	  this->detach = (attr->detachedstate == PTHREAD_CREATE_DETACHED);  	} +      this->detach = (attr->detachedstate == PTHREAD_CREATE_DETACHED); +        /* Start running, not suspended. */        flags = 0; diff --git a/implement.h b/implement.h index 807bf0e..3216573 100644 --- a/implement.h +++ b/implement.h @@ -62,7 +62,12 @@ struct _pthread_threads_thread {    pthread_t                   thread;    pthread_attr_t              attr;    _pthread_call_t             call; -  int                         cancelthread; +  int                         cancel_pending; +  int                         cancelstate;      /* PTHREAD_CANCEL_DISABLE +						   PTHREAD_CANCEL_ENABLE */ + +  int                         canceltype;       /* PTHREAD_CANCEL_ASYNCHRONOUS +						   PTHREAD_CANCEL_DEFERRED */    void **                     joinvalueptr;    int                         join_count;    _pthread_handler_node_t *   cleanupstack; @@ -6,8 +6,6 @@   * the implementation and may be used throughout it.   */ -#include <windows.h> -#include <process.h>  #include "pthread.h"  #include "implement.h" @@ -27,51 +25,48 @@  int  _pthread_new_thread_entry(pthread_t thread, _pthread_threads_thread_t * entry)  { -  _pthread_threads_thread_t * this; - -  /* CRITICAL SECTION */ -  pthread_mutex_lock(&_pthread_count_mutex); +  _pthread_threads_thread_t * new;    if (_pthread_threads_count >= PTHREAD_THREADS_MAX)      {        return EAGAIN;      } -  this = &_pthread_threads_table[_PTHREAD_HASH_INDEX(thread)]; +  new = &_pthread_threads_table[_PTHREAD_HASH_INDEX(thread)]; -  while (this->thread != NULL) +  while (new->thread != NULL)      { -      this++; +      new++; -      if (this == &_pthread_threads_table[PTHREAD_THREADS_MAX]) +      if (new == &_pthread_threads_table[PTHREAD_THREADS_MAX])  	{  	  /* Wrap to the top of the table. */ -	  this == _pthread_threads_table; +	  new == _pthread_threads_table;  	}      } -  if (this->thread != NULL) +  if (new->thread != NULL)      {        /* INTERNAL ERROR: There should be at least one slot left. */        return ESRCH;      }    else      { -      this->thread = thread; -      pthread_attr_init(&(this->attr)); -      this->joinvalueptr = NULL; -      this->cleanupstack = NULL; -      this->destructorstack = NULL; -      this->forkpreparestack = NULL; -      this->forkparentstack = NULL; -      this->forkchildstack = NULL; +      new->thread = thread; +      pthread_attr_init(&(new->attr)); +      new->joinvalueptr = NULL; +      new->cancelstate = PTHREAD_CANCEL_ENABLE; +      new->canceltype = PTHREAD_CANCEL_DEFERRED; +      new->cancel_pending = FALSE; +      new->cleanupstack = NULL; +      new->destructorstack = NULL; +      new->forkpreparestack = NULL; +      new->forkparentstack = NULL; +      new->forkchildstack = NULL;      }    _pthread_threads_count++; -  entry = this; - -  pthread_mutex_unlock(&_pthread_count_mutex); -  /* END CRITICAL SECTION */ +  entry = new;    return 0;  } @@ -79,45 +74,42 @@ _pthread_new_thread_entry(pthread_t thread, _pthread_threads_thread_t * entry)  _pthread_threads_thread *  _pthread_find_thread_entry(pthread_t thread)  { -  _pthread_threads_thread_t * this; +  _pthread_threads_thread_t * entry;    _pthread_threads_thread_t * start; -  start = this = &_pthread_threads_table[_PTHREAD_HASH_INDEX(thread)]; +  start = entry = &_pthread_threads_table[_PTHREAD_HASH_INDEX(thread)]; -  while (this->thread != thread) +  while (entry->thread != thread)      { -      this++; +      entry++; -      if (this == &_pthread_threads_table[PTHREAD_THREADS_MAX]) +      if (entry == &_pthread_threads_table[PTHREAD_THREADS_MAX])  	{  	  /* Wrap to top of table. */ -	  this = _pthread_threads_table; +	  entry = _pthread_threads_table;  	}      } -  if (this->thread == NULL || this == start) +  if (entry->thread == NULL || entry == start)      {        /* Failed to find the thread. */        return NULL;      } -  return this; +  return entry;  }  void -_pthread_delete_thread_entry(_pthread_threads_thread_t * thread_entry) +_pthread_delete_thread_entry(_pthread_threads_thread_t * entry)  {    /* We don't check that the thread has been properly cleaned up, so       it had better be done already. */ -  /* CRITICAL SECTION */ -  pthread_mutex_lock(&_pthread_count_mutex); -    /* Remove the thread entry if necessary. */ -  if (thread_entry->thread != NULL) +  if (entry->thread != NULL)      { -      thread_entry->thread = NULL; +      entry->thread = NULL;        if (_pthread_threads_count > 0)  	{ @@ -132,7 +124,4 @@ _pthread_delete_thread_entry(_pthread_threads_thread_t * thread_entry)      {        /* FIXME: INTERNAL ERROR: This should not happen. */      } - -  pthread_mutex_unlock(&_pthread_count_mutex); -  /* END CRITICAL SECTION */  } @@ -88,15 +88,9 @@ typedef struct {    size_t stacksize;                  /* PTHREAD_STACK_MIN */  #endif -  int cancelstate;                   /* PTHREAD_CANCEL_DISABLE -					PTHREAD_CANCEL_ENABLE */ -    int detachedstate;                 /* PTHREAD_CREATE_DETACHED  					PTHREAD_CREATE_JOINABLE */ -  int canceltype;                    /* PTHREAD_CANCEL_ASYNCHRONOUS -					PTHREAD_CANCEL_DEFERRED */ -  #ifdef HAVE_SIGSET_T    sigset_t sigmask;  #endif /* HAVE_SIGSET_T */ @@ -76,21 +76,25 @@ pthread_join(pthread_t thread, void ** valueptr)        target_thread_mutex = _PTHREAD_THREAD_MUTEX(target);        /* CRITICAL SECTION */ -      pthread_mutex_lock(target_thread_mutex); +      pthread_mutex_lock(&_pthread_count_mutex);        /* If the thread is in DETACHED state, then join will return  	 immediately. */ -      if (target->detach == TRUE) +      if (pthread_attr_getdetachedstate(&(target->attr), &detachstate) != 0  +	  || detachstate == PTHREAD_CREATE_DETACHED)  	{  	  return EINVAL;  	}        target->join_count++; -      pthread_mutex_lock(target_thread_mutex); +      pthread_mutex_lock(&_pthread_count_mutex);        /* END CRITICAL SECTION */ +      /* CANCELATION POINT */ +      pthread_testcancel(); +        /* Wait on the kernel thread object. */        switch (WaitForSingleObject(thread, INFINITE))  	{ @@ -152,26 +156,46 @@ pthread_join(pthread_t thread, void ** valueptr)  int  pthread_detach(pthread_t thread)  { -  _pthread_threads_thread_t * this; +  _pthread_threads_thread_t * target;    int detachstate; +  int ret; +  pthread_mutex_t * target_thread_mutex; -  this = _pthread_find_thread_entry(thread); +  /* CRITICAL SECTION */ +  pthread_mutex_lock(&_pthread_count_mutex); -  if (this == NULL) +  target = _pthread_find_thread_entry(thread); + +  if (target == NULL)      { -      return ESRCH; +      ret = ESRCH;      } - -  /* Check that we can detach this thread. */ -  if (pthread_attr_getdetachedstate(&(this->attr), &detachstate) != 0  -      || detachstate == PTHREAD_CREATE_DETACHED) +  else      { -      return EINVAL; + +      target_thread_mutex = _PTHREAD_THREAD_MUTEX(target); + +      /* Check that we can detach this thread. */ +      if (pthread_attr_getdetachedstate(&(target->attr), &detachstate) != 0  +	  || detachstate == PTHREAD_CREATE_DETACHED) +	{ +	  ret = EINVAL; +	} +      else +	{ + +	  /* This is all we do here - the rest is done either when the +	     thread exits or when pthread_join() exits. Once this is +	     set it will never be unset. */ +	  pthread_attr_setdetachedstate(&(this->attr),  +					PTHREAD_CREATE_DETACHED); + +	  ret = 0; +	}      } -  /* This is all we do here - the rest is done either when the thread -     exits or when pthread_join() exits. */ -  this->detach = TRUE; +  pthread_mutex_unlock(&_pthread_count_mutex); +  /* END CRITICAL SECTION */ -  return 0; +  return ret;  }  | 
