This is the mail archive of the mailing list for the glibc project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH v4] Destructor support for C++11 thread_local variables

On 02/15/2013 12:33 AM, Siddhesh Poyarekar wrote:
> On Thu, Feb 14, 2013 at 06:28:57PM -0500, Carlos O'Donell wrote:
>> You mentioned in the wiki page of the description of this patch
>> that because thread_local is destroyed *before* the key destructors
>> are called that you can't use thread_local in the key destructors.
>> This needs to be documented. Please create a pthreads section in
>> the manual, create an empty definition for pthread_key_create and
>> document that C++11 thread_local may not be used by those registered
>> destructors.
> Sure, will post a manual patch once this patch goes in.


>> Is there any way to avoid this restriction? Why can't we destory
>> the thread_local variables *after* calling the key destructors?
> It was a choice between either allowing thread_local destructors to
> use pthread_keys or allowing pthread_keys to allow thread_local
> destructors; we can't do both.  It's just a choice I made since it is
> unlikely that an implementation will use both and interleave them in
> such a manner.
>>> +  if (__builtin_expect (dso_handle_cache != dso_handle, 0))
>> IIUC this is simply an optimization for registering a series of thread_local
>> destructors for the same library?
> Yes.


>>> +    {
>>> +      ElfW(Addr) caller = (ElfW(Addr)) dso_handle;
>>> +
>>> +      /* If the address is not recognized the call comes from the main
>>> +         program (we hope).  */
>>> +      lm_cache = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
>>> +
>>> +      /* Find the highest-addressed object that DSO_HANDLE is not below.  */
>>> +      for (Lmid_t ns = 0; ns < GL(dl_nns); ++ns)
>>> +        for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL;
>>> +             l = l->l_next)
>>> +          if (caller >= l->l_map_start && caller < l->l_map_end
>>> +              && (l->l_contiguous || _dl_addr_inside_object (l, caller)))
>>> +            {
>>> +              lm_cache = l;
>>> +              break;
>>> +            }
>>> +
>> OK, I need some clarification here, is DSO_HANDLE a handle returned by
>> dlopen() or simply a symbol within the DSO that the compiler has?
>> I assume the latter, otherwise I don't think this would work.
> It's a symbol added (I think) by the linker.

As Jason pointed out this is a symbol.

The problem I have with using DSO handle is that it's a confusing
term already used within glibc to mean the return of a call to

>> Could we please create a utility function and get that patch 
>> checked in first?
> OK, will do that.

Thanks, I reviewed it.

>> (2) Do not use the word "DSO handle" since that might confuse people.
>> If it's a symbol from within the DSO that the compiler is using to mark
>> that DSO in some way then say "DSO symbol". A handle is what is returned
>> from dlopen.
> But that symbol has always been called the dso_handle.  Anyway, it
> doesn't matter to me what it's called, so I think I'll call it
> dso_symbol.

Thanks. Feel free to explain that the symbol is *named* `__dso_handle',
but that it is just another symbol.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]