]> git.ipfire.org Git - pakfire.git/commitdiff
pakfire: Add function to reset all callbacks
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 9 May 2022 08:42:02 +0000 (08:42 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 9 May 2022 08:42:02 +0000 (08:42 +0000)
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 <michael.tremer@ipfire.org>
src/_pakfire/pakfire.c
src/libpakfire/include/pakfire/pakfire.h
src/libpakfire/libpakfire.sym
src/libpakfire/pakfire.c

index bb6ab635f5a2464f1154a4159e56630b5202a9a8..108fa45114c8efb9c2c11754a75f14dac2e7f492 100644 (file)
@@ -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);
 }
index 0f33b70845307e673ac19c380b59f5fefcd22a48..2261d9f420ab34d7da88716c228977b867a9ff27 100644 (file)
@@ -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);
 
index c87b7b539b25ff8b544f8e3bc9c86e5a375d5b8b..174821203ea5310a5ce23188d2a76793e36d8338 100644 (file)
@@ -39,6 +39,7 @@ global:
        pakfire_list_keys;
        pakfire_ref;
        pakfire_refresh;
+       pakfire_reset_all_callbacks;
        pakfire_search;
        pakfire_sync;
        pakfire_unref;
index 576f2adda0f6a61f4919ecae84c9d1dab54b3ea0..7aea6526071b65ef8f63d4e0f2b7bbc92ba04920 100644 (file)
@@ -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;
 }