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;
}