]> git.ipfire.org Git - pakfire.git/commitdiff
pakfire: Go back on callbacks
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 9 May 2022 09:33:50 +0000 (09:33 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 9 May 2022 09:33:50 +0000 (09:33 +0000)
Instead of passing a giant struct will all sorts of callbacks, it is
probably more flexible if we would pass them individually.

However, the log callback should be initialized at the very beginning to
allow Pakfire to properly log from the very start.

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 108fa45114c8efb9c2c11754a75f14dac2e7f492..dac3e3ab7301ae9347c25746f5f64840165a0cd0 100644 (file)
@@ -59,10 +59,10 @@ static PyObject* Pakfire_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
 
 static void Pakfire_log_callback(void* data, int priority, const char* file, int line,
                const char* fn, const char* format, va_list args) {
-       struct callbacks* callbacks = (struct callbacks*)data;
+       PyObject* callback = (PyObject*)data;
 
        // Do nothing if callback isn't set
-       if (!callbacks->log)
+       if (!callback)
                return;
 
        // Translate priority to Python logging priorities
@@ -99,7 +99,7 @@ static void Pakfire_log_callback(void* data, int priority, const char* file, int
                goto ERROR;
 
        // Call the callback
-       result = PyObject_CallObject(callbacks->log, tuple);
+       result = PyObject_CallObject(callback, tuple);
 
 ERROR:
        if (buffer)
@@ -155,8 +155,18 @@ ERROR:
 }
 
 static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) {
-       char* kwlist[] = { "path", "arch", "logger", "interactive", "offline", "conf", "build",
-               "enable_ccache", "enable_snapshot", "status_callback", "progress_callback", NULL };
+       char* kwlist[] = {
+               "path",
+               "arch",
+               "logger",
+               "interactive",
+               "offline",
+               "conf",
+               "build",
+               "enable_ccache",
+               "enable_snapshot",
+               NULL,
+       };
        const char* path = NULL;
        const char* arch = NULL;
        const char* conf = NULL;
@@ -166,10 +176,9 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) {
        int enable_ccache = 1;
        int enable_snapshot = 1;
 
-       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzOppzpppOO", kwlist,
+       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzOppzppp", kwlist,
                        &path, &arch, &self->callbacks.log, &interactive, &offline, &conf, &build,
-                       &enable_ccache, &enable_snapshot, &self->callbacks.status,
-                       &self->callbacks.progress))
+                       &enable_ccache, &enable_snapshot))
                return -1;
 
        // Check if log callback is callable
@@ -178,18 +187,6 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) {
                return -1;
        }
 
-       // Check if status callback is callable
-       if (self->callbacks.status && !PyCallable_Check(self->callbacks.status)) {
-               PyErr_SetString(PyExc_TypeError, "status callback must be callable\n");
-               return -1;
-       }
-
-       // Check if progress callback is callable
-       if (self->callbacks.progress && !PyCallable_Check(self->callbacks.progress)) {
-               PyErr_SetString(PyExc_TypeError, "progress callback must be callable\n");
-               return -1;
-       }
-
        int flags = 0;
 
        // Enable interactive mode
@@ -212,27 +209,12 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) {
        }
 
        // Configure callbacks
-       struct pakfire_callbacks callbacks = {
-               .data = &self->callbacks,
-       };
-
-       if (self->callbacks.log) {
-               callbacks.log = Pakfire_log_callback;
+       if (self->callbacks.log)
                Py_INCREF(self->callbacks.log);
-       }
-
-       if (self->callbacks.status) {
-               callbacks.status = Pakfire_status_callback;
-               Py_INCREF(self->callbacks.status);
-       }
-
-       if (self->callbacks.progress) {
-               callbacks.progress = Pakfire_progress_callback;
-               Py_INCREF(self->callbacks.progress);
-       }
 
        // Create a new Pakfire instance
-       int r = pakfire_create(&self->pakfire, path, arch, conf, flags, &callbacks);
+       int r = pakfire_create(&self->pakfire, path, arch, conf, flags,
+               Pakfire_log_callback, self->callbacks.log);
        if (r) {
                switch (errno) {
                        // Invalid architecture or path
@@ -253,8 +235,8 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) {
 
 static void Pakfire_dealloc(PakfireObject* self) {
        if (self->pakfire) {
-               // Drop references to all callbacks
-               pakfire_reset_all_callbacks(self->pakfire);
+               // Reset log callback
+               pakfire_set_log_callback(self->pakfire, NULL, NULL);
 
                pakfire_unref(self->pakfire);
        }
index 2261d9f420ab34d7da88716c228977b867a9ff27..9f50ec62f2a89c71c934f8b532e1c79f7a4b7d99 100644 (file)
@@ -52,26 +52,16 @@ enum pakfire_flags {
 };
 
 // Callbacks
-
-struct pakfire_callbacks {
-       void* data;
-
-       // Logging
-       void (*log)(void* data, int priority, const char* file,
-               int line, const char* fn, const char* format, va_list args);
-
-       // Status, Progress & Speed
-       void (*status)(void* data, const char* message);
-       void (*progress)(void* data, int progress);
-       void (*speed)(void* data, const char* speed);
-};
+typedef void (*pakfire_log_callback)(void* data, int priority, const char* file,
+        int line, const char* fn, const char* format, va_list args);
+void pakfire_set_log_callback(struct pakfire* pakfire,
+       pakfire_log_callback callback, void* data);
 
 int pakfire_create(struct pakfire** pakfire, const char* path, const char* arch,
-       const char* conf, int flags, const struct pakfire_callbacks* callbacks);
+       const char* conf, int flags, pakfire_log_callback log_callback, void* log_data);
 
 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 174821203ea5310a5ce23188d2a76793e36d8338..3feed459dc16042ae0660337d52e3b059b0092ca 100644 (file)
@@ -39,8 +39,8 @@ global:
        pakfire_list_keys;
        pakfire_ref;
        pakfire_refresh;
-       pakfire_reset_all_callbacks;
        pakfire_search;
+       pakfire_set_log_callback;
        pakfire_sync;
        pakfire_unref;
        pakfire_update;
index 7aea6526071b65ef8f63d4e0f2b7bbc92ba04920..43054935a832f9169f126954f97ff97bec973618 100644 (file)
@@ -89,7 +89,23 @@ struct pakfire {
        Pool* pool;
 
        // Callbacks
-       struct pakfire_callbacks callbacks;
+       struct pakfire_callbacks {
+               // Logging
+               pakfire_log_callback log;
+               void* log_data;
+
+               // Status
+               void (*status)(void* data, const char* message);
+               void* status_data;
+
+               // Progress
+               void (*progress)(void* data, int progress);
+               void* progress_data;
+
+               // Speed
+               void (*speed)(void* data, const char* speed);
+               void* speed_data;
+       } callbacks;
 
        // Logging
        int log_priority;
@@ -842,7 +858,7 @@ ERROR:
 
 PAKFIRE_EXPORT int pakfire_create(struct pakfire** pakfire, const char* path,
                const char* arch, const char* conf, int flags,
-               const struct pakfire_callbacks* callbacks) {
+               pakfire_log_callback log_callback, void* log_data) {
        char tempdir[PATH_MAX] = PAKFIRE_TMP_DIR "/XXXXXX";
        int r = 1;
 
@@ -879,28 +895,15 @@ 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)
-                       p->callbacks.data = callbacks->data;
-
-               if (callbacks->log)
-                       p->callbacks.log = callbacks->log;
-
-               if (callbacks->status)
-                       p->callbacks.status = callbacks->status;
-
-               if (callbacks->progress)
-                       p->callbacks.progress = callbacks->progress;
-       }
-
        // Set architecture
        pakfire_string_set(p->arch, arch);
 
        // Setup logging
+       if (log_callback)
+               pakfire_set_log_callback(p, log_callback, log_data);
+       else
+               pakfire_set_log_callback(p, pakfire_log_syslog, NULL);
+
        const char* env = secure_getenv("PAKFIRE_LOG");
        if (env)
                pakfire_log_set_priority(p, log_priority(env));
@@ -1064,24 +1067,6 @@ 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;
 }
@@ -1170,7 +1155,7 @@ void pakfire_call_status_callback(struct pakfire* pakfire, const char* message,
                return;
 
        // Call the callback
-       pakfire->callbacks.status(pakfire->callbacks.data, buffer);
+       pakfire->callbacks.status(pakfire->callbacks.status_data, buffer);
 
        // Cleanup
        if (buffer)
@@ -1182,7 +1167,7 @@ void pakfire_call_progress_callback(struct pakfire* pakfire, int progress) {
        if (!pakfire->callbacks.progress)
                return;
 
-       pakfire->callbacks.progress(pakfire->callbacks.data, progress);
+       pakfire->callbacks.progress(pakfire->callbacks.progress_data, progress);
 }
 
 const char* pakfire_get_keystore_path(struct pakfire* pakfire) {
@@ -1692,6 +1677,8 @@ int __pakfire_make_cache_path(struct pakfire* pakfire, char* path, size_t length
        return 0;
 }
 
+// Logging
+
 PAKFIRE_EXPORT int pakfire_log_get_priority(struct pakfire* pakfire) {
        return pakfire->log_priority;
 }
@@ -1700,6 +1687,12 @@ PAKFIRE_EXPORT void pakfire_log_set_priority(struct pakfire* pakfire, int priori
        pakfire->log_priority = priority;
 }
 
+PAKFIRE_EXPORT void pakfire_set_log_callback(struct pakfire* pakfire,
+               pakfire_log_callback callback, void* data) {
+       pakfire->callbacks.log = callback;
+       pakfire->callbacks.log_data = data;
+}
+
 void pakfire_log(struct pakfire* pakfire, int priority, const char* file, int line,
                const char* fn, const char* format, ...) {
        va_list args;
@@ -1708,7 +1701,8 @@ void pakfire_log(struct pakfire* pakfire, int priority, const char* file, int li
        int saved_errno = errno;
 
        va_start(args, format);
-       pakfire->callbacks.log(pakfire->callbacks.data, priority, file, line, fn, format, args);
+       pakfire->callbacks.log(pakfire->callbacks.log_data,
+               priority, file, line, fn, format, args);
        va_end(args);
 
        // Restore errno