i've embedded python into our product and i'm not sure how to handle this situation. the following code is a
simplification of a function that calls a python function. i've removed all error checking to furthur simplify the
problem. the following code works correctly:
void foo(context_t ctx) {
PyObject py_interp = NULL;
PyObject py_mod = NULL;
PyObject py_call_foo = NULL;
const char *mod;
PyEval_AcquireLock();
py_interp = get_interpreter(ctx);
PyThreadState_Swap(py_interp);
mod = get_module(ctx);
py_mod = PyImport_ImportModule(mod);
py_call_foo = PyObject_GetAttrString(py_mod, "py_foo");
PyObject_CallFunction(py_call_foo, NULL);
Py_XDECREF(py_interp);
Py_XDECREF(py_mod);
Py_XDECREF(py_call_foo);
PyThreadState_Swap(NULL);
PyEval_ReleaseLock();
}
now i have a situation where foo may be called at the same time in different c threads. furthermore, the call py_foo
might take forever to execute and foo is then required to return immediately. so i modified the code to something like
this where foo starts a threaded function foo_threaded in a new thread so foo can return immediately.
void foo_threaded(void *args) {
PyObject py_interp = NULL;
PyObject py_mod = NULL;
PyObject py_call_foo = NULL;
const char *mod;
PyEval_AcquireLock();
py_interp = get_interpreter(ctx);
PyThreadState_Swap(py_interp);
mod = get_module(ctx);
py_mod = PyImport_ImportModule(mod);
py_call_foo = PyObject_GetAttrString(py_mod, "py_foo");
PyObject_CallFunction(py_call_foo, NULL);
Py_XDECREF(py_interp);
Py_XDECREF(py_mod);
Py_XDECREF(py_call_foo);
PyThreadState_Swap(NULL);
PyEval_ReleaseLock();
}
void foo(context_t ctx) {
Thread thread;
thread = new_thread(call_py_foo);
thread.start()
}
this seems like the wrong approach to me. if foo gets called a second time but the call to py_foo hasn't returned yet,
the interpreter is still locked. so how can another py_foo be called? the 2nd time foo is called the call to
get_interpreter may or may not return the same interpreter. what am i missing?
thanks for any help.
bryan