]> git.ipfire.org Git - pakfire.git/commitdiff
python: ctx: Ensure we are holding the GIL
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 14 Mar 2025 17:57:39 +0000 (17:57 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 14 Mar 2025 17:57:39 +0000 (17:57 +0000)
This is required because we usally return the GIL when we are jumping
into Pakfire functions as these tend to take some time when running.

When we are jumping back into the Python code, we need to acquire the
GIL again.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/python/ctx.c

index 204dc7056adbc2b95da10f5e3f2236b795b97727..6b7c30b07ea4800e5e162f9374e3e052aed76e23 100644 (file)
@@ -224,19 +224,25 @@ static int Ctx_confirm_callback(struct pakfire_ctx* ctx, struct pakfire* pakfire
                void* data, const char* message, const char* question) {
        PyObject* callback = data;
        PyObject* ret = NULL;
-       int r = 0;
+       int r = -1;
+
+       // Acquire the GIL
+       PyGILState_STATE state = PyGILState_Ensure();
 
        // Call the callback function
        ret = PyObject_CallFunction(callback, "ss", message, question);
        if (!ret)
-               return -1;
+               goto ERROR;
 
        // Return if the result is True
        if (PyObject_IsTrue(ret))
                r = 1;
 
-       // Cleanup
-       Py_DECREF(ret);
+ERROR:
+       Py_XDECREF(ret);
+
+       // Release the GIL
+       PyGILState_Release(state);
 
        return r;
 }
@@ -272,6 +278,9 @@ static int Ctx_progress_start(struct pakfire_ctx* ctx,
        PyObject* p = data;
        int r = -1;
 
+       // Acquire the GIL
+       PyGILState_STATE state = PyGILState_Ensure();
+
        // Fetch the start method
        PyObject* start = PyObject_GetAttrString(p, "start");
        if (!start)
@@ -289,6 +298,9 @@ ERROR:
        Py_XDECREF(start);
        Py_XDECREF(ret);
 
+       // Release the GIL
+       PyGILState_Release(state);
+
        return r;
 }
 
@@ -298,6 +310,9 @@ static int Ctx_progress_finish(struct pakfire_ctx* ctx,
        PyObject* p = data;
        int r = -1;
 
+       // Acquire the GIL
+       PyGILState_STATE state = PyGILState_Ensure();
+
        // Fetch the finish method
        PyObject* finish = PyObject_GetAttrString(p, "finish");
        if (!finish)
@@ -315,6 +330,9 @@ ERROR:
        Py_XDECREF(finish);
        Py_XDECREF(ret);
 
+       // Release the GIL
+       PyGILState_Release(state);
+
        return r;
 }
 
@@ -324,6 +342,9 @@ static int Ctx_progress_update(struct pakfire_ctx* ctx,
        PyObject* p = data;
        int r = -1;
 
+       // Acquire the GIL
+       PyGILState_STATE state = PyGILState_Ensure();
+
        // Fetch the update method
        PyObject* update = PyObject_GetAttrString(p, "update");
        if (!update)
@@ -341,6 +362,9 @@ ERROR:
        Py_XDECREF(update);
        Py_XDECREF(ret);
 
+       // Release the GIL
+       PyGILState_Release(state);
+
        return r;
 }
 
@@ -348,14 +372,24 @@ static void Ctx_progress_free(
                struct pakfire_ctx* ctx, struct pakfire_progress* progress, void* data) {
        PyObject* p = data;
 
+       // Acquire the GIL
+       PyGILState_STATE state = PyGILState_Ensure();
+
        // Free the object
        Py_XDECREF(p);
+
+       // Release the GIL
+       PyGILState_Release(state);
 }
 
 static int Ctx_progress_callback(
                struct pakfire_ctx* ctx, void* data, struct pakfire_progress* progress) {
        PyObject* callback = data;
        PyObject* p = NULL;
+       int r = -1;
+
+       // Acquire the GIL
+       PyGILState_STATE state = PyGILState_Ensure();
 
        // Fetch the title
        const char* title = pakfire_progress_get_title(progress);
@@ -363,7 +397,7 @@ static int Ctx_progress_callback(
        // Call the callback to create a new progress object
        p = PyObject_CallFunction(callback, "z", title);
        if (!p)
-               return -1;
+               goto ERROR;
 
        // Set callback data
        pakfire_progress_set_callback_data(progress, p);
@@ -382,7 +416,14 @@ static int Ctx_progress_callback(
        // Set free callback
        pakfire_progress_set_free_callback(progress, Ctx_progress_free);
 
-       return 0;
+       // Success
+       r = 0;
+
+ERROR:
+       // Release the GIL
+       PyGILState_Release(state);
+
+       return r;
 }
 
 static PyObject* Ctx_set_progress_callback(CtxObject* self, PyObject* args) {