From: Michael Tremer Date: Fri, 14 Mar 2025 17:57:39 +0000 (+0000) Subject: python: ctx: Ensure we are holding the GIL X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2a7fb447b658a9f52703f96652919176aa24264b;p=pakfire.git python: ctx: Ensure we are holding the GIL 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 --- diff --git a/src/python/ctx.c b/src/python/ctx.c index 204dc705..6b7c30b0 100644 --- a/src/python/ctx.c +++ b/src/python/ctx.c @@ -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) {