pkg: implement refcounting and a deeper cache
parent
e3d8475c36
commit
dd53cd57f4
15
cache.c
15
cache.c
|
@ -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
2
main.c
|
@ -899,5 +899,7 @@ out_println:
|
|||
|
||||
out:
|
||||
pkg_tuple_free_global();
|
||||
pkg_cache_free();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
35
pkg.c
35
pkg.c
|
@ -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
5
pkg.h
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue