diff options
author | Jakub Jelinek <jakub@redhat.com> | 2008-01-31 08:43:22 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2008-01-31 08:43:22 +0000 |
commit | a21d44637e4c53cce4760a2e2b13f0213c49a33d (patch) | |
tree | e28730f085cf343d98da117b41773940b365dd37 /elf/dl-tls.c | |
parent | 07b7d301cc62d3f4ff1bbaf668ddc2510f7a55d8 (diff) | |
download | glibc-a21d44637e4c53cce4760a2e2b13f0213c49a33d.tar.gz glibc-a21d44637e4c53cce4760a2e2b13f0213c49a33d.tar.xz glibc-a21d44637e4c53cce4760a2e2b13f0213c49a33d.zip |
Updated to fedora-glibc-20080131T0821 cvs/fedora-glibc-2_7_90-4
Diffstat (limited to 'elf/dl-tls.c')
-rw-r--r-- | elf/dl-tls.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/elf/dl-tls.c b/elf/dl-tls.c index d5865ab409..3059481043 100644 --- a/elf/dl-tls.c +++ b/elf/dl-tls.c @@ -413,7 +413,8 @@ _dl_allocate_tls_init (void *result) not be the generation counter. */ maxgen = MAX (maxgen, listp->slotinfo[cnt].gen); - if (map->l_tls_offset == NO_TLS_OFFSET) + if (map->l_tls_offset == NO_TLS_OFFSET + || map->l_tls_offset == FORCED_DYNAMIC_TLS_OFFSET) { /* For dynamically loaded modules we simply store the value indicating deferred allocation. */ @@ -702,6 +703,7 @@ __tls_get_addr (GET_ADDR_ARGS) if (__builtin_expect (dtv[0].counter != GL(dl_tls_generation), 0)) the_map = _dl_update_slotinfo (GET_ADDR_MODULE); + retry: p = dtv[GET_ADDR_MODULE].pointer.val; if (__builtin_expect (p == TLS_DTV_UNALLOCATED, 0)) @@ -722,6 +724,28 @@ __tls_get_addr (GET_ADDR_ARGS) the_map = listp->slotinfo[idx].map; } + /* Make sure that, if a dlopen running in parallel forces the + variable into static storage, we'll wait until the address in + the static TLS block is set up, and use that. If we're + undecided yet, make sure we make the decision holding the + lock as well. */ + if (__builtin_expect (the_map->l_tls_offset + != FORCED_DYNAMIC_TLS_OFFSET, 0)) + { + __rtld_lock_lock_recursive (GL(dl_load_lock)); + if (__builtin_expect (the_map->l_tls_offset == NO_TLS_OFFSET, 1)) + { + the_map->l_tls_offset = FORCED_DYNAMIC_TLS_OFFSET; + __rtld_lock_unlock_recursive (GL(dl_load_lock)); + } + else + { + __rtld_lock_unlock_recursive (GL(dl_load_lock)); + if (__builtin_expect (the_map->l_tls_offset + != FORCED_DYNAMIC_TLS_OFFSET, 1)) + goto retry; + } + } p = dtv[GET_ADDR_MODULE].pointer.val = allocate_and_init (the_map); dtv[GET_ADDR_MODULE].pointer.is_static = false; } |