diff options
author | Ulrich Drepper <drepper@redhat.com> | 2001-11-29 07:43:03 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2001-11-29 07:43:03 +0000 |
commit | 03a2c6475bd251773ddce5e9e5bb9b8d4c0baeab (patch) | |
tree | e3b83e302b2f166d9520df5dcfa0195fe051c2ba /linuxthreads/specific.c | |
parent | e0e86ccb1d2848678b5c32f65bf6239ba5fb9d24 (diff) | |
download | glibc-03a2c6475bd251773ddce5e9e5bb9b8d4c0baeab.tar.gz glibc-03a2c6475bd251773ddce5e9e5bb9b8d4c0baeab.tar.xz glibc-03a2c6475bd251773ddce5e9e5bb9b8d4c0baeab.zip |
Update.
* iconvdata/ibm1163.c: New file. * iconvdata/ibm1163.h: New file. * iconvdata/ibm1164.c: New file. * iconvdata/ibm1164.h: New file. * iconvdata/TESTS: Add entries for IBM1163 and IBM1164. * iconvdata/Makefile: Likewise. * iconvdata/testdata/IBM1163: New file. * iconvdata/testdata/IBM1163..UTF8: New file. * iconvdata/testdata/IBM1164: New file. * iconvdata/testdata/IBM1164..UTF8: New file. Patch by Masahide Washizawa <WASHI@jp.ibm.com>. * iconvdata/ibm1046.h: Optimize. Remove duplicate mappings. * iconvdata/ibm1124.h: Likewise. * iconvdata/ibm1132.h: Likewise. * iconvdata/ibm1133.h: Likewise. * iconvdata/ibm1160.h: Likewise. * iconvdata/ibm1161.h: Likewise. * iconvdata/ibm1162.h: Likewise. * iconvdata/ibm856.h: Likewise. * iconvdata/ibm922.h: Likewise. * iconvdata/ibm930.h: Likewise. * iconvdata/ibm932.h: Likewise. * iconvdata/ibm933.h: Likewise. * iconvdata/ibm935.h: Likewise. * iconvdata/ibm937.h: Likewise. * iconvdata/ibm939.h: Likewise. * iconvdata/ibm943.h: Likewise. * iconvdata/ibm930.c: Pretty printing. * iconvdata/ibm937.c: Avoid access accross array boundary.
Diffstat (limited to 'linuxthreads/specific.c')
-rw-r--r-- | linuxthreads/specific.c | 66 |
1 files changed, 49 insertions, 17 deletions
diff --git a/linuxthreads/specific.c b/linuxthreads/specific.c index a7fa8ff5b7..1a0cab10b6 100644 --- a/linuxthreads/specific.c +++ b/linuxthreads/specific.c @@ -20,6 +20,7 @@ #include "pthread.h" #include "internals.h" #include "spinlock.h" +#include "restart.h" #include <bits/libc-lock.h> @@ -58,13 +59,38 @@ int __pthread_key_create(pthread_key_t * key, destr_function destr) } strong_alias (__pthread_key_create, pthread_key_create) -/* Delete a key */ +/* Reset deleted key's value to NULL in each live thread. + * NOTE: this executes in the context of the thread manager! */ + +struct pthread_key_delete_helper_args { + /* Damn, we need lexical closures in C! ;) */ + unsigned int idx1st, idx2nd; + pthread_descr self; +}; + +static void pthread_key_delete_helper(void *arg, pthread_descr th) +{ + struct pthread_key_delete_helper_args *args = arg; + unsigned int idx1st = args->idx1st; + unsigned int idx2nd = args->idx2nd; + pthread_descr self = args->self; + + if (self == 0) + self = args->self = thread_self(); + + if (!th->p_terminated) { + /* pthread_exit() may try to free th->p_specific[idx1st] concurrently. */ + __pthread_lock(THREAD_GETMEM(th, p_lock), self); + if (th->p_specific[idx1st] != NULL) + th->p_specific[idx1st][idx2nd] = NULL; + __pthread_unlock(THREAD_GETMEM(th, p_lock)); + } +} +/* Delete a key */ int pthread_key_delete(pthread_key_t key) { pthread_descr self = thread_self(); - pthread_descr th; - unsigned int idx1st, idx2nd; pthread_mutex_lock(&pthread_keys_mutex); if (key >= PTHREAD_KEYS_MAX || !pthread_keys[key].in_use) { @@ -73,23 +99,29 @@ int pthread_key_delete(pthread_key_t key) } pthread_keys[key].in_use = 0; pthread_keys[key].destr = NULL; + /* Set the value of the key to NULL in all running threads, so that if the key is reallocated later by pthread_key_create, its associated values will be NULL in all threads. */ - idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE; - idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE; - th = self; - do { - /* If the thread already is terminated don't modify the memory. */ - if (!th->p_terminated) { - /* pthread_exit() may try to free th->p_specific[idx1st] concurrently. */ - __pthread_lock(THREAD_GETMEM(th, p_lock), self); - if (th->p_specific[idx1st] != NULL) - th->p_specific[idx1st][idx2nd] = NULL; - __pthread_unlock(THREAD_GETMEM(th, p_lock)); - } - th = th->p_nextlive; - } while (th != self); + + { + struct pthread_key_delete_helper_args args; + struct pthread_request request; + + args.idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE; + args.idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE; + args.self = 0; + + request.req_thread = self; + request.req_kind = REQ_FOR_EACH_THREAD; + request.req_args.for_each.arg = &args; + request.req_args.for_each.fn = pthread_key_delete_helper; + + TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, + (char *) &request, sizeof(request))); + suspend(self); + } + pthread_mutex_unlock(&pthread_keys_mutex); return 0; } |