1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
https://issuetracker.google.com/issues/317357322
https://bugs.gentoo.org/912843
https://github.com/pkgconf/pkgconf/pull/339
From 478199b425b46e9dae36bb174f1bd08bf3ffb0f1 Mon Sep 17 00:00:00 2001
From: Yi Chou <yich@google.com>
Date: Fri, 22 Dec 2023 00:13:31 +0800
Subject: [PATCH] Use traverse_id to prevent traverse pkgdep twice
--- a/libpkgconf/libpkgconf.h
+++ b/libpkgconf/libpkgconf.h
@@ -137,6 +137,8 @@ struct pkgconf_path_ {
#define PKGCONF_PKG_PROPF_CACHED 0x02
#define PKGCONF_PKG_PROPF_UNINSTALLED 0x08
#define PKGCONF_PKG_PROPF_VIRTUAL 0x10
+#define PKGCONF_PKG_PROPF_VISITED 0x20
+#define PKGCONF_PKG_PROPF_VISITED_PRIVATE 0x40
struct pkgconf_pkg_ {
int refcount;
@@ -176,6 +178,7 @@ struct pkgconf_pkg_ {
uint64_t serial;
uint64_t identifier;
+ uint64_t traverse_id;
};
typedef bool (*pkgconf_pkg_iteration_func_t)(const pkgconf_pkg_t *pkg, void *data);
@@ -212,6 +215,7 @@ struct pkgconf_client_ {
uint64_t serial;
uint64_t identifier;
+ uint64_t traverse_id;
pkgconf_pkg_t **cache_table;
size_t cache_count;
--- a/libpkgconf/pkg.c
+++ b/libpkgconf/pkg.c
@@ -1628,6 +1628,21 @@ pkgconf_pkg_traverse_main(pkgconf_client_t *client,
if (maxdepth == 0)
return eflags;
+ unsigned int visited_flag = (client->flags & PKGCONF_PKG_PKGF_ITER_PKG_IS_PRIVATE) ? PKGCONF_PKG_PROPF_VISITED_PRIVATE : PKGCONF_PKG_PROPF_VISITED;
+
+ if (root->traverse_id == client->traverse_id)
+ {
+ if (root->flags & visited_flag)
+ return eflags;
+ }
+ else
+ {
+ root->traverse_id = client->traverse_id;
+ root->flags &= ~(PKGCONF_PKG_PROPF_VISITED | PKGCONF_PKG_PROPF_VISITED_PRIVATE);
+ }
+
+ root->flags |= visited_flag;
+
PKGCONF_TRACE(client, "%s: level %d, serial %"PRIu64, root->id, maxdepth, client->serial);
if ((root->flags & PKGCONF_PKG_PROPF_VIRTUAL) != PKGCONF_PKG_PROPF_VIRTUAL || (client->flags & PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL) != PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL)
@@ -1672,6 +1687,9 @@ pkgconf_pkg_traverse(pkgconf_client_t *client,
int maxdepth,
unsigned int skip_flags)
{
+ static uint64_t traverse_id = 0;
+ client->traverse_id = ++traverse_id;
+
if (root->flags & PKGCONF_PKG_PROPF_VIRTUAL)
client->serial++;
|