From: Michael Tremer Date: Mon, 9 May 2022 08:42:02 +0000 (+0000) Subject: pakfire: Add function to reset all callbacks X-Git-Tag: 0.9.28~813 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d122626c91aa93488bc47b94d6d6ec7ec8fb4d95;p=pakfire.git pakfire: Add function to reset all callbacks When we call pakfire from Python, we will pass some callbacks which we will hold a reference to. If those are being freed but Pakfire isn't we might call the freed callback. Signed-off-by: Michael Tremer --- diff --git a/src/_pakfire/pakfire.c b/src/_pakfire/pakfire.c index bb6ab635f..108fa4511 100644 --- a/src/_pakfire/pakfire.c +++ b/src/_pakfire/pakfire.c @@ -252,22 +252,17 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) { } static void Pakfire_dealloc(PakfireObject* self) { - if (self->pakfire) - pakfire_unref(self->pakfire); + if (self->pakfire) { + // Drop references to all callbacks + pakfire_reset_all_callbacks(self->pakfire); -#if 0 - /* - It might happen, that the Pakfire python object is deallocated but the - actual struct pakfire object isn't yet. However, it might still happen - that the logging function is called which will try to call the logging - callback which has already been deallocated. + pakfire_unref(self->pakfire); + } - TODO This has to move into struct pakfire or something similar. - */ + // Free callbacks Py_XDECREF(self->callbacks.log); Py_XDECREF(self->callbacks.status); Py_XDECREF(self->callbacks.progress); -#endif Py_TYPE(self)->tp_free((PyObject *)self); } diff --git a/src/libpakfire/include/pakfire/pakfire.h b/src/libpakfire/include/pakfire/pakfire.h index 0f33b7084..2261d9f42 100644 --- a/src/libpakfire/include/pakfire/pakfire.h +++ b/src/libpakfire/include/pakfire/pakfire.h @@ -71,6 +71,7 @@ int pakfire_create(struct pakfire** pakfire, const char* path, const char* arch, struct pakfire* pakfire_ref(struct pakfire* pakfire); struct pakfire* pakfire_unref(struct pakfire* pakfire); +void pakfire_reset_all_callbacks(struct pakfire* pakfire); const char* pakfire_get_path(struct pakfire* pakfire); diff --git a/src/libpakfire/libpakfire.sym b/src/libpakfire/libpakfire.sym index c87b7b539..174821203 100644 --- a/src/libpakfire/libpakfire.sym +++ b/src/libpakfire/libpakfire.sym @@ -39,6 +39,7 @@ global: pakfire_list_keys; pakfire_ref; pakfire_refresh; + pakfire_reset_all_callbacks; pakfire_search; pakfire_sync; pakfire_unref; diff --git a/src/libpakfire/pakfire.c b/src/libpakfire/pakfire.c index 576f2adda..7aea65260 100644 --- a/src/libpakfire/pakfire.c +++ b/src/libpakfire/pakfire.c @@ -879,6 +879,9 @@ PAKFIRE_EXPORT int pakfire_create(struct pakfire** pakfire, const char* path, p->nrefs = 1; p->flags = flags; + // Initialize callbacks + pakfire_reset_all_callbacks(p); + // Copy callbacks if (callbacks) { if (callbacks->data) @@ -894,10 +897,6 @@ PAKFIRE_EXPORT int pakfire_create(struct pakfire** pakfire, const char* path, p->callbacks.progress = callbacks->progress; } - // Log to syslog by default - if (!p->callbacks.log) - p->callbacks.log = pakfire_log_syslog; - // Set architecture pakfire_string_set(p->arch, arch); @@ -1065,6 +1064,24 @@ PAKFIRE_EXPORT struct pakfire* pakfire_unref(struct pakfire* pakfire) { return NULL; } +/* + Drops all callbacks. + + This is useful when Pakfire is being called from Python and we cannot + determine the order when things are being freed. +*/ +PAKFIRE_EXPORT void pakfire_reset_all_callbacks(struct pakfire* pakfire) { + pakfire->callbacks.data = NULL; + + // Reset callbacks + pakfire->callbacks.status = NULL; + pakfire->callbacks.progress = NULL; + pakfire->callbacks.speed = NULL; + + // Log to syslog by default + pakfire->callbacks.log = pakfire_log_syslog; +} + int pakfire_has_flag(struct pakfire* pakfire, int flag) { return pakfire->flags & flag; }