summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDavid Leonard <d@cvs.openbsd.org>2000-01-06 07:25:16 +0000
committerDavid Leonard <d@cvs.openbsd.org>2000-01-06 07:25:16 +0000
commit58ca2ba3d7b23e0a7d454dcbad7fcf720b1880cb (patch)
tree107943a0352e10864c6d8d3e06344849de245009 /lib
parentaa15e0fdc87c0d8c0b06d252425b1e5125f31209 (diff)
thread-specific storage helper
Diffstat (limited to 'lib')
-rw-r--r--lib/libc_r/thread/Makefile.inc5
-rw-r--r--lib/libc_r/thread/thread_storage.c77
-rw-r--r--lib/libpthread/thread/Makefile.inc5
-rw-r--r--lib/libpthread/thread/thread_storage.c77
4 files changed, 164 insertions, 0 deletions
diff --git a/lib/libc_r/thread/Makefile.inc b/lib/libc_r/thread/Makefile.inc
new file mode 100644
index 00000000000..919300d08ae
--- /dev/null
+++ b/lib/libc_r/thread/Makefile.inc
@@ -0,0 +1,5 @@
+# $OpenBSD: Makefile.inc,v 1.1 2000/01/06 07:25:15 d Exp $
+
+.PATH: ${LIBC_RSRCDIR}/thread
+
+SRCS+= thread_storage.c
diff --git a/lib/libc_r/thread/thread_storage.c b/lib/libc_r/thread/thread_storage.c
new file mode 100644
index 00000000000..7d4012ecb35
--- /dev/null
+++ b/lib/libc_r/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;
+}
diff --git a/lib/libpthread/thread/Makefile.inc b/lib/libpthread/thread/Makefile.inc
new file mode 100644
index 00000000000..919300d08ae
--- /dev/null
+++ b/lib/libpthread/thread/Makefile.inc
@@ -0,0 +1,5 @@
+# $OpenBSD: Makefile.inc,v 1.1 2000/01/06 07:25:15 d Exp $
+
+.PATH: ${LIBC_RSRCDIR}/thread
+
+SRCS+= thread_storage.c
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;
+}