diff --git a/ldso/dynlink.c b/ldso/dynlink.c index c689084..cb82b2c 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -67,6 +67,7 @@ struct dso { char constructed; char kernel_mapped; struct dso **deps, *needed_by; + size_t next_dep; char *rpath_orig, *rpath; struct tls_module tls; size_t tls_id; @@ -1211,13 +1212,14 @@ void __libc_exit_fini() static void do_init_fini(struct dso *p) { size_t dyn[DYN_CNT]; - int need_locking = libc.threads_minus_1; - /* Allow recursive calls that arise when a library calls - * dlopen from one of its constructors, but block any - * other threads until all ctors have finished. */ - if (need_locking) pthread_mutex_lock(&init_fini_lock); - for (; p; p=p->prev) { - if (p->constructed) continue; + pthread_mutex_lock(&init_fini_lock); + while (!p->constructed) { + while (p->deps[p->next_dep] && p->deps[p->next_dep]->constructed) + p->next_dep++; + if (p->deps[p->next_dep]) { + p = p->deps[p->next_dep++]; + continue; + } p->constructed = 1; decode_vec(p->dynv, dyn, DYN_CNT); if (dyn[0] & ((1<needed_by; } - if (need_locking) pthread_mutex_unlock(&init_fini_lock); + pthread_mutex_unlock(&init_fini_lock); } void __libc_start_init(void)