Consider we have virtual/abstract C++ class that's fully implemented in Python. And for some sake of necessity we have a callback method (e.g. as some sort of event) that is being triggered from different thread on C++ side. In such case corresponding callback methods have to manage GIL state via PyGILState_STATE. So the resulting C++ callback class definition will look like follows (notice that Python method calls are wrapped up with GIL state handling code).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | class SessionStatusListenerCallback : public SessionStatusListener
{
public:
SessionStatusListenerCallback(PyObject *pyObject)
: self(pyObject) {}
SessionStatusListenerCallback(PyObject* pyObject, const SessionStatusListener& listener)
: self(pyObject), SessionStatusListener(listener) {}
void onSessionStatusChanged(O2GSessionStatus status)
{
// GIL state handler
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
// Python callback
call_method<void>(self, "onSessionStatusChanged", status);
// GIL handler release
PyGILState_Release(gstate);
}
void onLoginFailed(const char* error)
{
// GIL state handler
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
// Python callback
call_method<void>(self, "onLoginFailed", error);
// GIL handler release
PyGILState_Release(gstate);
}
private:
PyObject* const self;
};
|