@@ -72,44 +72,52 @@ __run_exit_handlers (int status, struct exit_function_list **listp,
struct exit_function *const f = &cur->fns[--cur->idx];
const uint64_t new_exitfn_called = __new_exitfn_called;
- /* Unlock the list while we call a foreign function. */
- __libc_lock_unlock (__exit_funcs_lock);
switch (f->flavor)
{
void (*atfct) (void);
void (*onfct) (int status, void *arg);
void (*cxafct) (void *arg, int status);
+ void *arg;
case ef_free:
case ef_us:
break;
case ef_on:
onfct = f->func.on.fn;
+ arg = f->func.on.arg;
+ /* Unlock the list while we call a foreign function. */
+ __libc_lock_unlock (__exit_funcs_lock);
#ifdef PTR_DEMANGLE
PTR_DEMANGLE (onfct);
#endif
- onfct (status, f->func.on.arg);
+ onfct (status, arg);
+ __libc_lock_lock (__exit_funcs_lock);
break;
case ef_at:
atfct = f->func.at;
+ /* Unlock the list while we call a foreign function. */
+ __libc_lock_unlock (__exit_funcs_lock);
#ifdef PTR_DEMANGLE
PTR_DEMANGLE (atfct);
#endif
atfct ();
+ __libc_lock_lock (__exit_funcs_lock);
break;
case ef_cxa:
/* To avoid dlclose/exit race calling cxafct twice (BZ 22180),
we must mark this function as ef_free. */
f->flavor = ef_free;
cxafct = f->func.cxa.fn;
+ arg = f->func.cxa.arg;
+ /* Unlock the list while we call a foreign function. */
+ __libc_lock_unlock (__exit_funcs_lock);
#ifdef PTR_DEMANGLE
PTR_DEMANGLE (cxafct);
#endif
- cxafct (f->func.cxa.arg, status);
+ cxafct (arg, status);
+ __libc_lock_lock (__exit_funcs_lock);
break;
}
- /* Re-lock again before looking at global state. */
- __libc_lock_lock (__exit_funcs_lock);
if (__glibc_unlikely (new_exitfn_called != __new_exitfn_called))
/* The last exit function, or another thread, has registered