pkg: implement refcounting and a deeper cache

pull/48/head
William Pitcock 2013-02-25 23:29:57 -06:00
parent e3d8475c36
commit dd53cd57f4
4 changed files with 48 additions and 9 deletions

15
cache.c
View File

@ -32,7 +32,7 @@ pkg_cache_lookup(const char *id)
PKG_FOREACH_LIST_ENTRY(pkg_cache, pkg)
{
if (!strcmp(pkg->id, id))
return pkg;
return pkg_ref(pkg);
}
return NULL;
@ -47,6 +47,8 @@ pkg_cache_lookup(const char *id)
void
pkg_cache_add(pkg_t *pkg)
{
pkg_ref(pkg);
pkg->next = pkg_cache;
pkg_cache = pkg;
@ -76,3 +78,14 @@ pkg_cache_remove(pkg_t *pkg)
pkg_cache = pkg->next;
}
}
void
pkg_cache_free(void)
{
pkg_t *iter, *iter2;
PKG_FOREACH_LIST_ENTRY_SAFE(pkg_cache, iter2, iter)
{
pkg_free(iter);
}
}

2
main.c
View File

@ -899,5 +899,7 @@ out_println:
out:
pkg_tuple_free_global();
pkg_cache_free();
return ret;
}

35
pkg.c
View File

@ -238,7 +238,7 @@ pkg_new_from_file(const char *filename, FILE *f, unsigned int flags)
}
fclose(f);
return pkg;
return pkg_ref(pkg);
}
void
@ -283,6 +283,21 @@ pkg_free(pkg_t *pkg)
free(pkg);
}
pkg_t *
pkg_ref(pkg_t *pkg)
{
pkg->refcount++;
return pkg;
}
void
pkg_unref(pkg_t *pkg)
{
pkg->refcount--;
if (pkg->refcount <= 0)
pkg_free(pkg);
}
static inline pkg_t *
pkg_try_specific_path(const char *path, const char *name, unsigned int flags)
{
@ -338,7 +353,7 @@ pkg_scan_dir(const char *path, pkg_iteration_func_t func)
if (pkg != NULL)
{
func(pkg);
pkg_free(pkg);
pkg_unref(pkg);
}
}
@ -809,7 +824,7 @@ pkg_report_graph_error(pkg_t *pkg, pkg_dependency_t *node, unsigned int eflags)
}
if (pkg != NULL)
pkg_free(pkg);
pkg_unref(pkg);
return eflags;
}
@ -834,11 +849,16 @@ pkg_walk_list(pkg_dependency_t *deplist,
pkgdep = pkg_verify_dependency(node, flags, &eflags);
if (eflags != PKG_ERRF_OK)
return pkg_report_graph_error(pkgdep, node, eflags);
if (pkgdep->flags & PKG_PROPF_CACHED)
if (pkgdep->flags & PKG_PROPF_SEEN)
{
pkg_unref(pkgdep);
continue;
}
pkgdep->flags |= PKG_PROPF_SEEN;
eflags = pkg_traverse(pkgdep, func, data, depth - 1, flags);
pkg_free(pkgdep);
pkgdep->flags &= ~PKG_PROPF_SEEN;
pkg_unref(pkgdep);
/* optimization: if a break has been found in the depgraph, quit walking it */
if (eflags != PKG_ERRF_OK)
@ -875,12 +895,12 @@ pkg_walk_conflicts_list(pkg_t *root, pkg_dependency_t *deplist, unsigned int fla
fprintf(error_msgout, "It may be possible to ignore this conflict and continue, try the\n");
fprintf(error_msgout, "PKG_CONFIG_IGNORE_CONFLICTS environment variable.\n");
pkg_free(pkgdep);
pkg_unref(pkgdep);
return PKG_ERRF_PACKAGE_CONFLICT;
}
pkg_free(pkgdep);
pkg_unref(pkgdep);
}
}
@ -949,7 +969,6 @@ pkg_cflags(pkg_t *root, pkg_fragment_t **list, int maxdepth, unsigned int flags)
int eflag;
eflag = pkg_traverse(root, pkg_cflags_collect, list, maxdepth, flags);
if (eflag != PKG_ERRF_OK)
{
pkg_fragment_free(*list);

5
pkg.h
View File

@ -81,10 +81,12 @@ typedef struct pkg_queue_ {
#define PKG_PROPF_NONE 0x0
#define PKG_PROPF_VIRTUAL 0x1
#define PKG_PROPF_CACHED 0x2
#define PKG_PROPF_SEEN 0x4
struct pkg_ {
pkg_t *prev, *next; /* for pkg_cache */
int refcount;
char *id;
char *filename;
char *realname;
@ -131,6 +133,8 @@ typedef void (*pkg_traverse_func_t)(pkg_t *pkg, void *data, unsigned int flags);
typedef bool (*pkg_queue_apply_func_t)(pkg_t *world, void *data, int maxdepth, unsigned int flags);
/* pkg.c */
pkg_t *pkg_ref(pkg_t *pkg);
void pkg_unref(pkg_t *pkg);
void pkg_free(pkg_t *pkg);
pkg_t *pkg_find(const char *name, unsigned int flags);
void pkg_scan(const char *search_path, pkg_iteration_func_t func);
@ -191,5 +195,6 @@ bool pkg_queue_validate(pkg_queue_t *head, int maxdepth, unsigned int flags);
pkg_t *pkg_cache_lookup(const char *id);
void pkg_cache_add(pkg_t *pkg);
void pkg_cache_remove(pkg_t *pkg);
void pkg_cache_free(void);
#endif