From 020190d963bac07c80870b63fd881365a1116cdc Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sun, 14 Jan 2018 19:35:56 +0100 Subject: [PATCH] libpakfire: Implement refcounting for package lists Signed-off-by: Michael Tremer --- src/_pakfire/relation.c | 2 +- src/_pakfire/selector.c | 2 +- src/libpakfire/include/pakfire/packagelist.h | 12 ++---- src/libpakfire/libpakfire.sym | 3 +- src/libpakfire/packagelist.c | 43 ++++++++++++++++---- src/libpakfire/transaction.c | 2 +- 6 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/_pakfire/relation.c b/src/_pakfire/relation.c index 7a6487873..1b5b11ce0 100644 --- a/src/_pakfire/relation.c +++ b/src/_pakfire/relation.c @@ -122,7 +122,7 @@ static PyObject* Relation_get_providers(RelationObject* self) { Py_DECREF(obj); } - pakfire_packagelist_free(packagelist); + pakfire_packagelist_unref(packagelist); return list; } diff --git a/src/_pakfire/selector.c b/src/_pakfire/selector.c index f6634cb85..c0a85427c 100644 --- a/src/_pakfire/selector.c +++ b/src/_pakfire/selector.c @@ -96,7 +96,7 @@ static PyObject* Selector_get_providers(SelectorObject* self) { Py_DECREF(obj); } - pakfire_packagelist_free(packagelist); + pakfire_packagelist_unref(packagelist); return list; } diff --git a/src/libpakfire/include/pakfire/packagelist.h b/src/libpakfire/include/pakfire/packagelist.h index 3d00fd111..c6582c14c 100644 --- a/src/libpakfire/include/pakfire/packagelist.h +++ b/src/libpakfire/include/pakfire/packagelist.h @@ -26,23 +26,19 @@ #include PakfirePackageList pakfire_packagelist_create(void); -void pakfire_packagelist_free(PakfirePackageList list); +PakfirePackageList pakfire_packagelist_ref(PakfirePackageList list); +PakfirePackageList pakfire_packagelist_unref(PakfirePackageList list); -int pakfire_packagelist_count(PakfirePackageList list); +size_t pakfire_packagelist_count(PakfirePackageList list); void pakfire_packagelist_sort(PakfirePackageList list); int pakfire_packagelist_has(PakfirePackageList list, PakfirePackage pkg); -PakfirePackage pakfire_packagelist_get(PakfirePackageList list, int index); +PakfirePackage pakfire_packagelist_get(PakfirePackageList list, unsigned int index); void pakfire_packagelist_push(PakfirePackageList list, PakfirePackage pkg); void pakfire_packagelist_push_if_not_exists(PakfirePackageList list, PakfirePackage pkg); #ifdef PAKFIRE_PRIVATE -struct _PakfirePackageList { - PakfirePackage* elements; - int count; -}; - PakfirePackageList pakfire_packagelist_from_queue(PakfirePool _pool, Queue* q); #endif diff --git a/src/libpakfire/libpakfire.sym b/src/libpakfire/libpakfire.sym index 0a4e99ad1..1c62456dd 100644 --- a/src/libpakfire/libpakfire.sym +++ b/src/libpakfire/libpakfire.sym @@ -186,12 +186,13 @@ global: # packagelist pakfire_packagelist_count; pakfire_packagelist_create; - pakfire_packagelist_free; pakfire_packagelist_get; pakfire_packagelist_has; pakfire_packagelist_push; pakfire_packagelist_push_if_not_exists; + pakfire_packagelist_ref; pakfire_packagelist_sort; + pakfire_packagelist_unref; # pool pakfire_pool_count; diff --git a/src/libpakfire/packagelist.c b/src/libpakfire/packagelist.c index 42cc1777a..560e8ffdd 100644 --- a/src/libpakfire/packagelist.c +++ b/src/libpakfire/packagelist.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -33,23 +34,51 @@ #define BLOCK_SIZE 31 +struct _PakfirePackageList { + PakfirePackage* elements; + size_t count; + int nrefs; +}; + PAKFIRE_EXPORT PakfirePackageList pakfire_packagelist_create(void) { PakfirePackageList list = pakfire_calloc(1, sizeof(*list)); + if (list) { + DEBUG("Allocated PackageList at %p\n", list); + list->nrefs = 1; + } + + return list; +} + +PAKFIRE_EXPORT PakfirePackageList pakfire_packagelist_ref(PakfirePackageList list) { + list->nrefs++; return list; } -PAKFIRE_EXPORT void pakfire_packagelist_free(PakfirePackageList list) { - for (int i = 0; i < list->count; i++) { - PakfirePackage pkg = list->elements[i]; - pakfire_package_unref(pkg); +static void pakfire_packagelist_free(PakfirePackageList list) { + for (unsigned int i = 0; i < list->count; i++) { + pakfire_package_unref(list->elements[i]); } pakfire_free(list->elements); pakfire_free(list); + + DEBUG("Released PackageList at %p\n", list); +} + +PAKFIRE_EXPORT PakfirePackageList pakfire_packagelist_unref(PakfirePackageList list) { + if (!list) + return NULL; + + if (--list->nrefs > 0) + return list; + + pakfire_packagelist_free(list); + return NULL; } -PAKFIRE_EXPORT int pakfire_packagelist_count(PakfirePackageList list) { +PAKFIRE_EXPORT size_t pakfire_packagelist_count(PakfirePackageList list) { return list->count; } @@ -61,7 +90,7 @@ PAKFIRE_EXPORT void pakfire_packagelist_sort(PakfirePackageList list) { qsort(list->elements, list->count, sizeof(*list->elements), _packagelist_cmp); } -PAKFIRE_EXPORT PakfirePackage pakfire_packagelist_get(PakfirePackageList list, int index) { +PAKFIRE_EXPORT PakfirePackage pakfire_packagelist_get(PakfirePackageList list, unsigned int index) { if (index < list->count) return pakfire_package_ref(list->elements[index]); @@ -69,7 +98,7 @@ PAKFIRE_EXPORT PakfirePackage pakfire_packagelist_get(PakfirePackageList list, i } PAKFIRE_EXPORT int pakfire_packagelist_has(PakfirePackageList list, PakfirePackage pkg) { - for (int i = 0; i < list->count; i++) { + for (unsigned int i = 0; i < list->count; i++) { PakfirePackage _pkg = list->elements[i]; if (pakfire_package_identical(pkg, _pkg)) diff --git a/src/libpakfire/transaction.c b/src/libpakfire/transaction.c index bfbb8c53e..bdf307922 100644 --- a/src/libpakfire/transaction.c +++ b/src/libpakfire/transaction.c @@ -231,7 +231,7 @@ static size_t pakfire_transaction_add_section(char** str, size_t width, PakfireT pakfire_transaction_add_newline(str, width); END: - pakfire_packagelist_free(list); + pakfire_packagelist_unref(list); return c; } -- 2.39.5