Skip to content

Commit 7bd61c5

Browse files
committed
fixed deadlock when call PyDestroyPushConsumer
1 parent 98b4b27 commit 7bd61c5

1 file changed

Lines changed: 22 additions & 13 deletions

File tree

src/PythonWrapper.cpp

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,33 @@ map<CPushConsumer *, PyObject *> g_CallBackMap;
3434

3535
class PyThreadStateLock {
3636
public:
37-
PyThreadStateLock(void) {
37+
PyThreadStateLock() {
3838
state = PyGILState_Ensure();
3939
}
4040

41-
~PyThreadStateLock(void) {
42-
if (state == PyGILState_LOCKED) {
43-
PyGILState_Release(state);
44-
}
41+
~PyThreadStateLock() {
42+
// NOTE: must paired with PyGILState_Ensure, otherwise it will cause deadlock!!!
43+
PyGILState_Release(state);
4544
}
4645

4746
private:
4847
PyGILState_STATE state;
4948
};
5049

50+
class PyThreadStateUnlock {
51+
public:
52+
PyThreadStateUnlock() : _save(NULL) {
53+
Py_UNBLOCK_THREADS
54+
}
55+
56+
~PyThreadStateUnlock() {
57+
Py_BLOCK_THREADS
58+
}
59+
60+
private:
61+
PyThreadState *_save;
62+
};
63+
5164
#ifdef __cplusplus
5265
extern "C" {
5366
#endif
@@ -146,9 +159,7 @@ const char *PyGetSendResultMsgID(CSendResult &sendResult) {
146159
}
147160
//consumer
148161
void *PyCreatePushConsumer(const char *groupId) {
149-
//Py_Initialize();
150-
PyEval_InitThreads();
151-
// PyEval_ReleaseThread(PyThreadState_Get());
162+
PyEval_InitThreads(); // ensure create GIL, for call Python callback from C.
152163
return (void *) CreatePushConsumer(groupId);
153164
}
154165
int PyDestroyPushConsumer(void *consumer) {
@@ -158,10 +169,8 @@ int PyStartPushConsumer(void *consumer) {
158169
return StartPushConsumer((CPushConsumer *) consumer);
159170
}
160171
int PyShutdownPushConsumer(void *consumer) {
161-
int ret = ShutdownPushConsumer((CPushConsumer *) consumer);
162-
//PyGILState_Ensure();
163-
//Py_Finalize();
164-
return ret;
172+
PyThreadStateUnlock PyThreadUnlock; // ShutdownPushConsumer is a block call, ensure thread don't hold GIL.
173+
return ShutdownPushConsumer((CPushConsumer *) consumer);
165174
}
166175
int PySetPushConsumerNameServerAddress(void *consumer, const char *namesrv) {
167176
return SetPushConsumerNameServerAddress((CPushConsumer *) consumer, namesrv);
@@ -212,7 +221,7 @@ int PySetPushConsumerSessionCredentials(void *consumer, const char *accessKey, c
212221
}
213222

214223
//push consumer
215-
int PySetPullConsumerNameServerDomain(void *consumer, const char *domain){
224+
int PySetPullConsumerNameServerDomain(void *consumer, const char *domain) {
216225
return SetPullConsumerNameServerDomain((CPullConsumer *) consumer, domain);
217226
}
218227
//version

0 commit comments

Comments
 (0)