I am wrapping library that uses global defined function as callback.
void library_callback(size_t id, char *buf, size_t len);
This library_callback
function is called internally by library but I can set this function via public API.
I want to create list of listeners (Python callable objects) that are called on every callback execution.
static PyObject *listeners = NULL; // initialize later as PyList_New(...)
void library_callback(size_t id, char *buf, size_t len) {
for (size_t i = 0, count = PyList_Size(listeners); i < count; i++) {
PyObject *listener = PyList_GetItem(listeners, i);
// call listener with id and buf
}
}
It works very well till I wrap library_callback
with Py_BEGIN_ALLOW_THREADS
and Py_END_ALLOW_THREADS
.
But without Py_*_ALLOW_THREADS
library is working in blocking mode (even when I try to execute Thread(target=myfunc)
).
I created simple method to check whether problem is with static variable or not.
PyObject *TestObject_Test(PyObject *self, PyObject *noargs) {
static PyObject *variable = NULL;
if (variable == NULL) {
variable = PyUnicode_FromString("variable");
}
Py_BEGIN_ALLOW_THREADS
printf("variable\t%s\n", PyUnicode_AsUTF8(PyUnicode_FromFormat("%R", variable)));
Py_END_ALLOW_THREADS
return Py_INCREF(variable), variable;
}
Then after code below I got fish: 'python3' terminated by signal SIGSEGV (Address boundary error)
obj = TestObject()
obj.test()
How can I write this code properly and get feature to run callbacks in background?