Edit

kc3-lang/pkgconf/libpkgconf/cache.c

Branch :

  • Show log

    Commit

  • Author : William Pitcock
    Date : 2017-02-04 20:01:41
    Hash : f7f0bfc4
    Message : libpkgconf: cache: add trace points

  • libpkgconf/cache.c
  • /*
     * cache.c
     * package object cache
     *
     * Copyright (c) 2013 pkgconf authors (see AUTHORS).
     *
     * Permission to use, copy, modify, and/or distribute this software for any
     * purpose with or without fee is hereby granted, provided that the above
     * copyright notice and this permission notice appear in all copies.
     *
     * This software is provided 'as is' and without any warranty, express or
     * implied.  In no event shall the authors be liable for any damages arising
     * from the use of this software.
     */
    
    #include <libpkgconf/libpkgconf.h>
    
    /*
     * !doc
     *
     * libpkgconf `cache` module
     * =========================
     *
     * The libpkgconf `cache` module manages a package/module object cache, allowing it to
     * avoid loading duplicate copies of a package/module.
     *
     * A cache is tied to a specific pkgconf client object, so package objects should not
     * be shared across threads.
     */
    
    /*
     * !doc
     *
     * .. c:function:: pkgconf_pkg_t *pkgconf_cache_lookup(const pkgconf_client_t *client, const char *id)
     *
     *    Looks up a package in the cache given an `id` atom,
     *    such as ``gtk+-3.0`` and returns the already loaded version
     *    if present.
     *
     *    :param pkgconf_client_t* client: The client object to access.
     *    :param char* id: The package atom to look up in the client object's cache.
     *    :return: A package object if present, else ``NULL``.
     *    :rtype: pkgconf_pkg_t *
     */
    pkgconf_pkg_t *
    pkgconf_cache_lookup(const pkgconf_client_t *client, const char *id)
    {
    	pkgconf_node_t *node;
    
    	PKGCONF_FOREACH_LIST_ENTRY(client->pkg_cache.head, node)
    	{
    		pkgconf_pkg_t *pkg = node->data;
    
    		if (!strcmp(pkg->id, id))
    		{
    			PKGCONF_TRACE(client, "found: %s @%p", id, pkg);
    			return pkgconf_pkg_ref(client, pkg);
    		}
    	}
    
    	PKGCONF_TRACE(client, "miss: %s", id);
    	return NULL;
    }
    
    /*
     * !doc
     *
     * .. c:function:: void pkgconf_cache_add(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
     *
     *    Adds an entry for the package to the package cache.
     *    The cache entry must be removed if the package is freed.
     *
     *    :param pkgconf_client_t* client: The client object to modify.
     *    :param pkgconf_pkg_t* pkg: The package object to add to the client object's cache.
     *    :return: nothing
     */
    void
    pkgconf_cache_add(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
    {
    	if (pkg == NULL)
    		return;
    
    	pkgconf_pkg_ref(client, pkg);
    	pkgconf_node_insert(&pkg->cache_iter, pkg, &client->pkg_cache);
    
    	PKGCONF_TRACE(client, "added @%p to cache", pkg);
    }
    
    /*
     * !doc
     *
     * .. c:function:: void pkgconf_cache_remove(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
     *
     *    Deletes a package from the client object's package cache.
     *
     *    :param pkgconf_client_t* client: The client object to modify.
     *    :param pkgconf_pkg_t* pkg: The package object to remove from the client object's cache.
     *    :return: nothing
     */
    void
    pkgconf_cache_remove(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
    {
    	if (pkg == NULL)
    		return;
    
    	PKGCONF_TRACE(client, "removed @%p from cache", pkg);
    
    	pkgconf_node_delete(&pkg->cache_iter, &client->pkg_cache);
    }
    
    /*
     * !doc
     *
     * .. c:function:: void pkgconf_cache_free(pkgconf_client_t *client)
     *
     *    Releases all resources related to a client object's package cache.
     *    This function should only be called to clear a client object's package cache,
     *    as it may release any package in the cache.
     *
     *    :param pkgconf_client_t* client: The client object to modify.
     */
    void
    pkgconf_cache_free(pkgconf_client_t *client)
    {
    	pkgconf_node_t *iter, *iter2;
    
    	PKGCONF_FOREACH_LIST_ENTRY_SAFE(client->pkg_cache.head, iter2, iter)
    	{
    		pkgconf_pkg_t *pkg = iter->data;
    		pkgconf_pkg_free(client, pkg);
    	}
    
    	memset(&client->pkg_cache, 0, sizeof client->pkg_cache);
    
    	PKGCONF_TRACE(client, "cleared package cache");
    }