]> git.ipfire.org Git - people/ms/pakfire.git/commitdiff
python: Make sure we hold the GIL when jumping into the logging callback
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 29 Jan 2024 10:54:19 +0000 (10:54 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 29 Jan 2024 10:54:19 +0000 (10:54 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/_pakfire/pakfire.c

index a5a45e54736c2b1fbe2091579f716879800a9555..b82f28a54250ce2aa4593077b253c7062714b938 100644 (file)
@@ -424,29 +424,39 @@ static PyObject* Pakfire_version_compare(PakfireObject* self, PyObject* args) {
 static int Pakfire_execute_output_callback(struct pakfire_ctx* ctx, struct pakfire_jail* jail,
                void* data, const char* line, size_t length) {
        PyObject* callback = (PyObject*)data;
-       int r = 0;
+       PyObject* args = NULL;
+       PyObject* result = NULL;
+       int r = 1;
 
        // Do nothing if callback isn't set
        if (!callback)
                return 0;
 
        // Remove the trailing newline
-       if (line && line[length - 1] == '\n')
+       if (line && length && line[length - 1] == '\n')
                length--;
 
+       // Get the GIL
+       PyGILState_STATE state = PyGILState_Ensure();
+
        // Create tuple with arguments for the callback function
-       PyObject* args = Py_BuildValue("(is#)", LOG_INFO, line, (Py_ssize_t)length);
+       args = Py_BuildValue("(is#)", LOG_INFO, line, (Py_ssize_t)length);
        if (!args)
-               return 1;
+               goto ERROR;
 
-       PyObject* result = PyObject_CallObject(callback, args);
+       // Call the callback method
+       result = PyObject_CallObject(callback, args);
     if (result && PyLong_Check(result)) {
         r = PyLong_AsLong(result);
     }
 
+ERROR:
        Py_XDECREF(args);
        Py_XDECREF(result);
 
+       // Release the GIL
+       PyGILState_Release(state);
+
        return r;
 }