diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2005-12-14 04:01:45 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2005-12-14 04:01:45 +0000 |
commit | 0f6755503e756f87fe75b6ace4596d4a9fc3d33d (patch) | |
tree | cb9a60f2b26ee457591092ea4bc6cb04b39779c5 /lib/librthread/rthread_tls.c | |
parent | cd51fc7a4da29f9239d2a4d77eae12364e7fe16f (diff) |
change keys to use table instead of list, makes a sane destructor implementation
possible
Diffstat (limited to 'lib/librthread/rthread_tls.c')
-rw-r--r-- | lib/librthread/rthread_tls.c | 58 |
1 files changed, 41 insertions, 17 deletions
diff --git a/lib/librthread/rthread_tls.c b/lib/librthread/rthread_tls.c index 7f18e148357..a028a04dc50 100644 --- a/lib/librthread/rthread_tls.c +++ b/lib/librthread/rthread_tls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread_tls.c,v 1.2 2005/12/07 02:56:59 tedu Exp $ */ +/* $OpenBSD: rthread_tls.c,v 1.3 2005/12/14 04:01:44 tedu Exp $ */ /* * Copyright (c) 2004 Ted Unangst <tedu@openbsd.org> * All Rights Reserved. @@ -36,26 +36,29 @@ #include "rthread.h" -struct rthread_key *rthread_key_list; +static struct rthread_key rkeys[PTHREAD_KEYS_MAX]; int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)) { - static int last_key; - struct rthread_key *rkey; - - last_key++; - - rkey = malloc(sizeof(*rkey)); - if (!rkey) - return (errno); - memset(rkey, 0, sizeof(*rkey)); - rkey->keyid = last_key; - rkey->destructor = destructor; - rkey->next = rthread_key_list; - rthread_key_list = rkey; - - *key = last_key; + static int hint; + int i; + + if (rkeys[hint].used) { + for (i = 0; i < PTHREAD_KEYS_MAX; i++) { + if (!rkeys[i].used) + break; + } + if (i == PTHREAD_KEYS_MAX) + return (EAGAIN); + hint = i; + } + rkeys[hint].used = 1; + rkeys[hint].destructor = destructor; + + *key = hint++; + if (hint >= PTHREAD_KEYS_MAX) + hint = 0; return (0); } @@ -64,6 +67,9 @@ int pthread_key_delete(pthread_key_t key) { + rkeys[key].used = 0; + rkeys[key].destructor = NULL; + return (0); } @@ -117,3 +123,21 @@ pthread_setspecific(pthread_key_t key, const void *data) return (0); } + +void +rthread_tls_destructors(pthread_t thread) +{ + struct rthread_storage *rs; + int i; + + for (i = 0; i < PTHREAD_DESTRUCTOR_ITERATIONS; i++) { + for (rs = thread->local_storage; rs; rs = rs->next) { + if (!rs->data) + continue; + if (rkeys[rs->keyid].destructor) { + rkeys[rs->keyid].destructor(rs->data); + rs->data = NULL; + } + } + } +} |