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) PKG_FOREACH_LIST_ENTRY(pkg_cache, pkg)
{ {
if (!strcmp(pkg->id, id)) if (!strcmp(pkg->id, id))
return pkg; return pkg_ref(pkg);
} }
return NULL; return NULL;
@ -47,6 +47,8 @@ pkg_cache_lookup(const char *id)
void void
pkg_cache_add(pkg_t *pkg) pkg_cache_add(pkg_t *pkg)
{ {
pkg_ref(pkg);
pkg->next = pkg_cache; pkg->next = pkg_cache;
pkg_cache = pkg; pkg_cache = pkg;
@ -76,3 +78,14 @@ pkg_cache_remove(pkg_t *pkg)
pkg_cache = pkg->next; 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: out:
pkg_tuple_free_global(); pkg_tuple_free_global();
pkg_cache_free();
return ret; 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); fclose(f);
return pkg; return pkg_ref(pkg);
} }
void void
@ -283,6 +283,21 @@ pkg_free(pkg_t *pkg)
free(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 * static inline pkg_t *
pkg_try_specific_path(const char *path, const char *name, unsigned int flags) 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) if (pkg != NULL)
{ {
func(pkg); 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) if (pkg != NULL)
pkg_free(pkg); pkg_unref(pkg);
return eflags; return eflags;
} }
@ -834,11 +849,16 @@ pkg_walk_list(pkg_dependency_t *deplist,
pkgdep = pkg_verify_dependency(node, flags, &eflags); pkgdep = pkg_verify_dependency(node, flags, &eflags);
if (eflags != PKG_ERRF_OK) if (eflags != PKG_ERRF_OK)
return pkg_report_graph_error(pkgdep, node, eflags); return pkg_report_graph_error(pkgdep, node, eflags);
if (pkgdep->flags & PKG_PROPF_CACHED) if (pkgdep->flags & PKG_PROPF_SEEN)
{
pkg_unref(pkgdep);
continue; continue;
}
pkgdep->flags |= PKG_PROPF_SEEN;
eflags = pkg_traverse(pkgdep, func, data, depth - 1, flags); 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 */ /* optimization: if a break has been found in the depgraph, quit walking it */
if (eflags != PKG_ERRF_OK) 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, "It may be possible to ignore this conflict and continue, try the\n");
fprintf(error_msgout, "PKG_CONFIG_IGNORE_CONFLICTS environment variable.\n"); fprintf(error_msgout, "PKG_CONFIG_IGNORE_CONFLICTS environment variable.\n");
pkg_free(pkgdep); pkg_unref(pkgdep);
return PKG_ERRF_PACKAGE_CONFLICT; 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; int eflag;
eflag = pkg_traverse(root, pkg_cflags_collect, list, maxdepth, flags); eflag = pkg_traverse(root, pkg_cflags_collect, list, maxdepth, flags);
if (eflag != PKG_ERRF_OK) if (eflag != PKG_ERRF_OK)
{ {
pkg_fragment_free(*list); 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_NONE 0x0
#define PKG_PROPF_VIRTUAL 0x1 #define PKG_PROPF_VIRTUAL 0x1
#define PKG_PROPF_CACHED 0x2 #define PKG_PROPF_CACHED 0x2
#define PKG_PROPF_SEEN 0x4
struct pkg_ { struct pkg_ {
pkg_t *prev, *next; /* for pkg_cache */ pkg_t *prev, *next; /* for pkg_cache */
int refcount;
char *id; char *id;
char *filename; char *filename;
char *realname; 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); typedef bool (*pkg_queue_apply_func_t)(pkg_t *world, void *data, int maxdepth, unsigned int flags);
/* pkg.c */ /* pkg.c */
pkg_t *pkg_ref(pkg_t *pkg);
void pkg_unref(pkg_t *pkg);
void pkg_free(pkg_t *pkg); void pkg_free(pkg_t *pkg);
pkg_t *pkg_find(const char *name, unsigned int flags); pkg_t *pkg_find(const char *name, unsigned int flags);
void pkg_scan(const char *search_path, pkg_iteration_func_t func); 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); pkg_t *pkg_cache_lookup(const char *id);
void pkg_cache_add(pkg_t *pkg); void pkg_cache_add(pkg_t *pkg);
void pkg_cache_remove(pkg_t *pkg); void pkg_cache_remove(pkg_t *pkg);
void pkg_cache_free(void);
#endif #endif