diff options
| author | rpj <rpj> | 2005-05-08 16:55:02 +0000 | 
|---|---|---|
| committer | rpj <rpj> | 2005-05-08 16:55:02 +0000 | 
| commit | ac8e3d247fa03af61b5411f92508481e7c3f49f8 (patch) | |
| tree | f5d9c2a8bc58a2e6135e8aa2b207daab23de14a7 /pthread_key_delete.c | |
| parent | 7523c7c4d75652f67cd31cb123e1268790394c8b (diff) | |
''
Diffstat (limited to 'pthread_key_delete.c')
| -rw-r--r-- | pthread_key_delete.c | 47 | 
1 files changed, 25 insertions, 22 deletions
diff --git a/pthread_key_delete.c b/pthread_key_delete.c index 99b00b9..7da9b2f 100644 --- a/pthread_key_delete.c +++ b/pthread_key_delete.c @@ -74,42 +74,41 @@ pthread_key_delete (pthread_key_t key)  	  key->destructor != NULL &&  	  pthread_mutex_lock (&(key->keyLock)) == 0)  	{ +	  ThreadKeyAssoc *assoc;  	  /*  	   * Run through all Thread<-->Key associations  	   * for this key. -	   * If the pthread_t still exists (ie the assoc->thread -	   * is not NULL) then leave the assoc for the thread to -	   * destroy. -	   * Notes: -	   *      If assoc->thread is NULL, then the associated thread -	   *      is no longer referencing this assoc. -	   *      The association is only referenced -	   *      by this key and must be released; otherwise -	   *      the assoc will be destroyed when the thread is destroyed. +	   * +	   * While we hold at least one of the locks guarding +	   * the assoc, we know that the assoc pointed to by +	   * key->threads is valid.  	   */ -	  ThreadKeyAssoc *assoc; - -	  assoc = (ThreadKeyAssoc *) key->threads; - -	  while (assoc != NULL) +	  while ((assoc = (ThreadKeyAssoc *) key->threads) != NULL)  	    { -	      ThreadKeyAssoc *next;  	      ptw32_thread_t * thread = assoc->thread; -	      if (thread != NULL -		  && pthread_mutex_lock (&(thread->threadLock)) == 0) +	      if (assoc == NULL)  		{ -		  next = assoc->nextThread; +		  /* Finished */ +		  break; +		} + +	      if (pthread_mutex_lock (&(thread->threadLock)) == 0) +		{ +		  /* +		   * Since we are starting at the head of the key's threads +		   * chain, this will also point key->threads at the next assoc. +		   * While we hold key->keyLock, no other thread can insert +		   * a new assoc via pthread_setspecific. +		   */  		  ptw32_tkAssocDestroy (assoc);  		  (void) pthread_mutex_unlock (&(thread->threadLock));  		}  	      else  		{ -		  /* Thread or lock is no longer valid */ -		  next = assoc->nextThread; +		  /* Thread or lock is no longer valid? */  		  ptw32_tkAssocDestroy (assoc);  		} -	      assoc = next;  	    }  	  pthread_mutex_unlock (&(key->keyLock));  	} @@ -117,7 +116,11 @@ pthread_key_delete (pthread_key_t key)        TlsFree (key->key);        if (key->destructor != NULL)  	{ -	  pthread_mutex_destroy (&(key->keyLock)); +	  /* A thread could be holding the keyLock */ +	  while (EBUSY == pthread_mutex_destroy (&(key->keyLock))) +	    { +	      Sleep(1); // Ugly. +	    }  	}  #if defined( _DEBUG )  | 
