forked from ariadne/pkgconf
pkg: prevent circular ownership
Otherwise in a case where A references B, and B references A, A and B will have mutual ownership of each other and prevent each other from being free'd.bsdstubs-errno
parent
301d8fa0c6
commit
1cfa2d1e20
|
@ -1445,9 +1445,9 @@ pkgconf_pkg_walk_list(pkgconf_client_t *client,
|
||||||
unsigned int skip_flags)
|
unsigned int skip_flags)
|
||||||
{
|
{
|
||||||
unsigned int eflags = PKGCONF_PKG_ERRF_OK;
|
unsigned int eflags = PKGCONF_PKG_ERRF_OK;
|
||||||
pkgconf_node_t *node;
|
pkgconf_node_t *node, *next;
|
||||||
|
|
||||||
PKGCONF_FOREACH_LIST_ENTRY(deplist->head, node)
|
PKGCONF_FOREACH_LIST_ENTRY_SAFE(deplist->head, next, node)
|
||||||
{
|
{
|
||||||
unsigned int eflags_local = PKGCONF_PKG_ERRF_OK;
|
unsigned int eflags_local = PKGCONF_PKG_ERRF_OK;
|
||||||
pkgconf_dependency_t *depnode = node->data;
|
pkgconf_dependency_t *depnode = node->data;
|
||||||
|
@ -1470,6 +1470,14 @@ pkgconf_pkg_walk_list(pkgconf_client_t *client,
|
||||||
if (pkgdep->serial == client->serial)
|
if (pkgdep->serial == client->serial)
|
||||||
{
|
{
|
||||||
pkgdep->hits++;
|
pkgdep->hits++;
|
||||||
|
/* In this case we have a circular reference.
|
||||||
|
* We break that by deleteing the circular node from the
|
||||||
|
* the list, so that we dont create a situation where
|
||||||
|
* memory is leaked due to circular ownership.
|
||||||
|
* i.e: A owns B owns A
|
||||||
|
*/
|
||||||
|
pkgconf_node_delete(node, deplist);
|
||||||
|
pkgconf_dependency_unref(client, depnode);
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue