diff options
author | 2000-01-06 07:25:15 +0000 | |
---|---|---|
committer | 2000-01-06 07:25:15 +0000 | |
commit | 1fd350b58aa1707b792dd7b23ea84328ea9adc58 (patch) | |
tree | b923580f6db2a84f49fef7e4f570d346cec61efb /lib/libpthread/thread/thread_storage.c | |
parent | quieten gcc (diff) | |
download | wireguard-openbsd-1fd350b58aa1707b792dd7b23ea84328ea9adc58.tar.xz wireguard-openbsd-1fd350b58aa1707b792dd7b23ea84328ea9adc58.zip |
thread-specific storage helper
Diffstat (limited to 'lib/libpthread/thread/thread_storage.c')
-rw-r--r-- | lib/libpthread/thread/thread_storage.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/lib/libpthread/thread/thread_storage.c b/lib/libpthread/thread/thread_storage.c new file mode 100644 index 00000000000..7d4012ecb35 --- /dev/null +++ b/lib/libpthread/thread/thread_storage.c @@ -0,0 +1,77 @@ + +/* libpthread's stronger functions */ + +#include <stdlib.h> +#include <pthread.h> +#include "pthread_private.h" + +void +_libc_private_storage_lock(mutex) + pthread_mutex_t *mutex; +{ + if (__isthreaded && pthread_mutex_lock(mutex) != 0) + PANIC("_libc_private_storage_lock"); +} + +void +_libc_private_storage_unlock(mutex) + pthread_mutex_t *mutex; +{ + if (__isthreaded && pthread_mutex_unlock(mutex) != 0) + PANIC("_libc_private_storage_unlock"); +} + +void * +_libc_private_storage(volkey, init, initsz, error) + volatile struct _thread_private_key_struct * volkey; + void * init; + size_t initsz; + void * error; +{ + void *result; + void (*cleanfn) __P((void *)); + struct _thread_private_key_struct * key; + + /* Use static storage while not threaded: */ + if (!__isthreaded) + return init; + + key = (struct _thread_private_key_struct *)volkey; /* for gcc */ + + /* Create the key once: */ + if (volkey->once.state == PTHREAD_NEEDS_INIT) { + if (pthread_mutex_lock(&key->once.mutex) != 0) + return error; + if (volkey->once.state == PTHREAD_NEEDS_INIT) { + if (key->cleanfn == NULL) + cleanfn = free; + else + cleanfn = key->cleanfn; + if (pthread_key_create(&key->key, cleanfn) != 0) { + pthread_mutex_unlock(&key->once.mutex); + return error; + } + key->once.state = PTHREAD_DONE_INIT; + } + pthread_mutex_unlock(&key->once.mutex); + } + + /* XXX signals may cause re-entrancy here? */ + + /* Acquire this key's thread-specific storage: */ + result = pthread_getspecific(key->key); + + /* Allocate and initialise storage if unallocated: */ + if (result == NULL) { + result = malloc(initsz); + if (result == NULL) + return error; + if (pthread_setspecific(key->key, result) != 0) { + free(result); + return error; + } + memcpy(result, init, initsz); + } + + return result; +} |