Deleted Added
full compact
26c26
< * $FreeBSD: head/libexec/rtld-elf/rtld.c 214777 2010-11-04 09:29:00Z kib $
---
> * $FreeBSD: head/libexec/rtld-elf/rtld.c 216489 2010-12-16 16:56:44Z jh $
113c113
< static void objlist_call_fini(Objlist *, bool, int *);
---
> static void objlist_call_fini(Objlist *, Obj_Entry *, int *);
1612,1613c1612,1615
< * which are unreferenced. All of the objects are expected to have
< * non-NULL fini functions.
---
> * belonging to the DAG of "root" and referenced once. If NULL "root"
> * is specified, every finalization function will be called regardless
> * of the reference count and the list elements won't be freed. All of
> * the objects are expected to have non-NULL fini functions.
1616c1618
< objlist_call_fini(Objlist *list, bool force, int *lockstate)
---
> objlist_call_fini(Objlist *list, Obj_Entry *root, int *lockstate)
1618c1620
< Objlist_Entry *elm, *elm_tmp;
---
> Objlist_Entry *elm;
1620a1623,1624
> assert(root == NULL || root->refcount == 1);
>
1626,1627c1630,1634
< STAILQ_FOREACH_SAFE(elm, list, link, elm_tmp) {
< if (elm->obj->refcount == 0 || force) {
---
> do {
> STAILQ_FOREACH(elm, list, link) {
> if (root != NULL && (elm->obj->refcount != 1 ||
> objlist_find(&root->dagmembers, elm->obj) == NULL))
> continue;
1633a1641,1647
> /*
> * XXX: If a dlopen() call references an object while the
> * fini function is in progress, we might end up trying to
> * unload the referenced object in dlclose() or the object
> * won't be unloaded although its fini function has been
> * called.
> */
1638c1652
< if (!force)
---
> if (root != NULL)
1639a1654,1659
> /*
> * We must restart the list traversal after every fini call
> * because a dlclose() call from the fini function or from
> * another thread might have modified the reference counts.
> */
> break;
1641c1661
< }
---
> } while (elm != NULL);
1829c1849
< objlist_call_fini(&list_fini, true, &lockstate);
---
> objlist_call_fini(&list_fini, NULL, &lockstate);
1942,1944c1962
< unref_dag(root);
<
< if (root->refcount == 0) {
---
> if (root->refcount == 1) {
1946c1964
< * The object is no longer referenced, so we must unload it.
---
> * The object will be no longer referenced, so we must unload it.
1949c1967
< objlist_call_fini(&list_fini, false, &lockstate);
---
> objlist_call_fini(&list_fini, root, &lockstate);
1950a1969,1970
> unref_dag(root);
>
1955c1975,1977
< }
---
> } else
> unref_dag(root);
>