From a416ab17ecf9f2cb0f1e3f7bd645a8d1ce690ca2 Mon Sep 17 00:00:00 2001 From: rpj Date: Mon, 18 Feb 2002 03:16:52 +0000 Subject: Major reorganisation of source code; new routine and tests added. --- tsd.c | 308 +----------------------------------------------------------------- 1 file changed, 4 insertions(+), 304 deletions(-) (limited to 'tsd.c') diff --git a/tsd.c b/tsd.c index 1fa9b5a..52c3517 100644 --- a/tsd.c +++ b/tsd.c @@ -37,310 +37,10 @@ #include "pthread.h" #include "implement.h" -/* TLS_OUT_OF_INDEXES not defined on WinCE */ -#ifndef TLS_OUT_OF_INDEXES -#define TLS_OUT_OF_INDEXES 0xffffffff -#endif -int -pthread_key_create (pthread_key_t * key, void (*destructor) (void *)) - /* - * ------------------------------------------------------ - * DOCPUBLIC - * This function creates a thread-specific data key visible - * to all threads. All existing and new threads have a value - * NULL for key until set using pthread_setspecific. When any - * thread with a non-NULL value for key terminates, 'destructor' - * is called with key's current value for that thread. - * - * PARAMETERS - * key - * pointer to an instance of pthread_key_t - * - * - * DESCRIPTION - * This function creates a thread-specific data key visible - * to all threads. All existing and new threads have a value - * NULL for key until set using pthread_setspecific. When any - * thread with a non-NULL value for key terminates, 'destructor' - * is called with key's current value for that thread. - * - * RESULTS - * 0 successfully created semaphore, - * EAGAIN insufficient resources or PTHREAD_KEYS_MAX - * exceeded, - * ENOMEM insufficient memory to create the key, - * - * ------------------------------------------------------ - */ -{ - int result = 0; - pthread_key_t newkey; +#include "pthread_key_create.c" +#include "pthread_key_delete.c" +#include "pthread_setspecific.c" +#include "pthread_getspecific.c" - if ((newkey = (pthread_key_t) calloc (1, sizeof (*newkey))) == NULL) - { - result = ENOMEM; - } - else if ((newkey->key = TlsAlloc()) == TLS_OUT_OF_INDEXES) - { - result = EAGAIN; - - free (newkey); - newkey = NULL; - } - else if (destructor != NULL) - { - /* - * Have to manage associations between thread and key; - * Therefore, need a lock that allows multiple threads - * to gain exclusive access to the key->threads list. - * - * The mutex will only be created when it is first locked. - */ - newkey->threadsLock = PTHREAD_MUTEX_INITIALIZER; - newkey->destructor = destructor; - } - - *key = newkey; - - return (result); -} - -int -pthread_key_delete (pthread_key_t key) - /* - * ------------------------------------------------------ - * DOCPUBLIC - * This function deletes a thread-specific data key. This - * does not change the value of the thread spcific data key - * for any thread and does not run the key's destructor - * in any thread so it should be used with caution. - * - * PARAMETERS - * key - * pointer to an instance of pthread_key_t - * - * - * DESCRIPTION - * This function deletes a thread-specific data key. This - * does not change the value of the thread spcific data key - * for any thread and does not run the key's destructor - * in any thread so it should be used with caution. - * - * RESULTS - * 0 successfully deleted the key, - * EINVAL key is invalid, - * - * ------------------------------------------------------ - */ -{ - int result = 0; - - if (key != NULL) - { - if (key->threads != NULL && - key->destructor != NULL && - pthread_mutex_lock (&(key->threadsLock)) == 0) - { - /* - * Run through all Thread<-->Key associations - * for this key. - * If the pthread_t still exits (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. - */ - ThreadKeyAssoc *assoc; - - assoc = (ThreadKeyAssoc *) key->threads; - - while (assoc != NULL) - { - if (pthread_mutex_lock (&(assoc->lock)) == 0) - { - ThreadKeyAssoc *next; - - assoc->key = NULL; - next = assoc->nextThread; - assoc->nextThread = NULL; - - pthread_mutex_unlock (&(assoc->lock)); - - ptw32_tkAssocDestroy (assoc); - - assoc = next; - } - } - pthread_mutex_unlock (&(key->threadsLock)); - } - - TlsFree (key->key); - if (key->destructor != NULL) - { - pthread_mutex_destroy (&(key->threadsLock)); - } - -#if defined( _DEBUG ) - memset ((char *) key, 0, sizeof (*key)); -#endif - free (key); - } - - return (result); -} - - -int -pthread_setspecific (pthread_key_t key, const void *value) - /* - * ------------------------------------------------------ - * DOCPUBLIC - * This function sets the value of the thread specific - * key in the calling thread. - * - * PARAMETERS - * key - * an instance of pthread_key_t - * value - * the value to set key to - * - * - * DESCRIPTION - * This function sets the value of the thread specific - * key in the calling thread. - * - * RESULTS - * 0 successfully set value - * EAGAIN could not set value - * ENOENT SERIOUS!! - * - * ------------------------------------------------------ - */ -{ - pthread_t self; - int result = 0; - - if (key != ptw32_selfThreadKey) - { - /* - * Using pthread_self will implicitly create - * an instance of pthread_t for the current - * thread if one wasn't explicitly created - */ - self = pthread_self (); - if (self == NULL) - { - return ENOENT; - } - } - else - { - /* - * Resolve catch-22 of registering thread with threadSelf - * key - */ - self = (pthread_t) pthread_getspecific (ptw32_selfThreadKey); - if (self == NULL) - { - self = (pthread_t) value; - } - } - - result = 0; - - if (key != NULL) - { - ThreadKeyAssoc *assoc; - - if (self != NULL && - key->destructor != NULL && - value != NULL) - { - /* - * Only require associations if we have to - * call user destroy routine. - * Don't need to locate an existing association - * when setting data to NULL for WIN32 since the - * data is stored with the operating system; not - * on the association; setting assoc to NULL short - * circuits the search. - */ - assoc = (ThreadKeyAssoc *) self->keys; - /* - * Locate existing association - */ - while (assoc != NULL) - { - if (assoc->key == key) - { - /* - * Association already exists - */ - break; - } - assoc = assoc->nextKey; - } - - /* - * create an association if not found - */ - if (assoc == NULL) - { - result = ptw32_tkAssocCreate (&assoc, self, key); - } - } - - if (result == 0) - { - if ( ! TlsSetValue (key->key, (LPVOID) value)) - { - result = EAGAIN; - } - } - } - - return (result); -} /* pthread_setspecific */ - - -void * -pthread_getspecific (pthread_key_t key) - /* - * ------------------------------------------------------ - * DOCPUBLIC - * This function returns the current value of key in the - * calling thread. If no value has been set for 'key' in - * the thread, NULL is returned. - * - * PARAMETERS - * key - * an instance of pthread_key_t - * - * - * DESCRIPTION - * This function returns the current value of key in the - * calling thread. If no value has been set for 'key' in - * the thread, NULL is returned. - * - * RESULTS - * key value or NULL on failure - * - * ------------------------------------------------------ - */ -{ - int lasterror = GetLastError(); - int lastWSAerror = WSAGetLastError(); - - void *ptr = TlsGetValue (key->key); - - SetLastError( lasterror ); - WSASetLastError( lastWSAerror ); - - return ptr; -} -- cgit v1.2.3