~mmach/netext73/pkgconf

« back to all changes in this revision

Viewing changes to libpkgconf/cache.c

  • Committer: mmach
  • Date: 2024-02-21 19:22:23 UTC
  • Revision ID: netbit73@gmail.com-20240221192223-5l809fiqh21udwrd
1.8.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * cache.c
 
3
 * package object cache
 
4
 *
 
5
 * Copyright (c) 2013 pkgconf authors (see AUTHORS).
 
6
 *
 
7
 * Permission to use, copy, modify, and/or distribute this software for any
 
8
 * purpose with or without fee is hereby granted, provided that the above
 
9
 * copyright notice and this permission notice appear in all copies.
 
10
 *
 
11
 * This software is provided 'as is' and without any warranty, express or
 
12
 * implied.  In no event shall the authors be liable for any damages arising
 
13
 * from the use of this software.
 
14
 */
 
15
 
 
16
#include <libpkgconf/stdinc.h>
 
17
#include <libpkgconf/libpkgconf.h>
 
18
 
 
19
/*
 
20
 * !doc
 
21
 *
 
22
 * libpkgconf `cache` module
 
23
 * =========================
 
24
 *
 
25
 * The libpkgconf `cache` module manages a package/module object cache, allowing it to
 
26
 * avoid loading duplicate copies of a package/module.
 
27
 *
 
28
 * A cache is tied to a specific pkgconf client object, so package objects should not
 
29
 * be shared across threads.
 
30
 */
 
31
 
 
32
/*
 
33
 * !doc
 
34
 *
 
35
 * .. c:function:: pkgconf_pkg_t *pkgconf_cache_lookup(const pkgconf_client_t *client, const char *id)
 
36
 *
 
37
 *    Looks up a package in the cache given an `id` atom,
 
38
 *    such as ``gtk+-3.0`` and returns the already loaded version
 
39
 *    if present.
 
40
 *
 
41
 *    :param pkgconf_client_t* client: The client object to access.
 
42
 *    :param char* id: The package atom to look up in the client object's cache.
 
43
 *    :return: A package object if present, else ``NULL``.
 
44
 *    :rtype: pkgconf_pkg_t *
 
45
 */
 
46
pkgconf_pkg_t *
 
47
pkgconf_cache_lookup(pkgconf_client_t *client, const char *id)
 
48
{
 
49
        pkgconf_node_t *node;
 
50
 
 
51
        PKGCONF_FOREACH_LIST_ENTRY(client->pkg_cache.head, node)
 
52
        {
 
53
                pkgconf_pkg_t *pkg = node->data;
 
54
 
 
55
                if (!strcmp(pkg->id, id))
 
56
                {
 
57
                        PKGCONF_TRACE(client, "found: %s @%p", id, pkg);
 
58
                        return pkgconf_pkg_ref(client, pkg);
 
59
                }
 
60
        }
 
61
 
 
62
        PKGCONF_TRACE(client, "miss: %s", id);
 
63
        return NULL;
 
64
}
 
65
 
 
66
/*
 
67
 * !doc
 
68
 *
 
69
 * .. c:function:: void pkgconf_cache_add(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
 
70
 *
 
71
 *    Adds an entry for the package to the package cache.
 
72
 *    The cache entry must be removed if the package is freed.
 
73
 *
 
74
 *    :param pkgconf_client_t* client: The client object to modify.
 
75
 *    :param pkgconf_pkg_t* pkg: The package object to add to the client object's cache.
 
76
 *    :return: nothing
 
77
 */
 
78
void
 
79
pkgconf_cache_add(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
 
80
{
 
81
        if (pkg == NULL)
 
82
                return;
 
83
 
 
84
        pkgconf_pkg_ref(client, pkg);
 
85
        pkgconf_node_insert(&pkg->cache_iter, pkg, &client->pkg_cache);
 
86
 
 
87
        PKGCONF_TRACE(client, "added @%p to cache", pkg);
 
88
 
 
89
        /* mark package as cached */
 
90
        pkg->flags |= PKGCONF_PKG_PROPF_CACHED;
 
91
}
 
92
 
 
93
/*
 
94
 * !doc
 
95
 *
 
96
 * .. c:function:: void pkgconf_cache_remove(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
 
97
 *
 
98
 *    Deletes a package from the client object's package cache.
 
99
 *
 
100
 *    :param pkgconf_client_t* client: The client object to modify.
 
101
 *    :param pkgconf_pkg_t* pkg: The package object to remove from the client object's cache.
 
102
 *    :return: nothing
 
103
 */
 
104
void
 
105
pkgconf_cache_remove(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
 
106
{
 
107
        if (pkg == NULL)
 
108
                return;
 
109
 
 
110
        if (!(pkg->flags & PKGCONF_PKG_PROPF_CACHED))
 
111
                return;
 
112
 
 
113
        PKGCONF_TRACE(client, "removed @%p from cache", pkg);
 
114
 
 
115
        pkgconf_node_delete(&pkg->cache_iter, &client->pkg_cache);
 
116
}
 
117
 
 
118
/*
 
119
 * !doc
 
120
 *
 
121
 * .. c:function:: void pkgconf_cache_free(pkgconf_client_t *client)
 
122
 *
 
123
 *    Releases all resources related to a client object's package cache.
 
124
 *    This function should only be called to clear a client object's package cache,
 
125
 *    as it may release any package in the cache.
 
126
 *
 
127
 *    :param pkgconf_client_t* client: The client object to modify.
 
128
 */
 
129
void
 
130
pkgconf_cache_free(pkgconf_client_t *client)
 
131
{
 
132
        pkgconf_node_t *iter, *iter2;
 
133
 
 
134
        PKGCONF_FOREACH_LIST_ENTRY_SAFE(client->pkg_cache.head, iter2, iter)
 
135
        {
 
136
                pkgconf_pkg_t *pkg = iter->data;
 
137
                pkgconf_pkg_unref(client, pkg);
 
138
        }
 
139
 
 
140
        memset(&client->pkg_cache, 0, sizeof client->pkg_cache);
 
141
 
 
142
        PKGCONF_TRACE(client, "cleared package cache");
 
143
}