cleanup threadstate so that it removes the thread-local storage and cleans up django database connections which are stored in thread-local. fixes bug where it was leaking connections.

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@8193 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Traun Leyden 2008-04-24 17:58:38 +00:00
parent 9e5e1e7c9a
commit 7de99aa9dc
1 changed files with 36 additions and 33 deletions

View File

@ -169,28 +169,31 @@ static void eval_some_python(char *uuid, char *args, switch_core_session_t *sess
// swap out thread state // swap out thread state
if (session) { if (session) {
// record the fact that thread state is swapped in // record the fact that thread state is swapped in
switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_t *channel = switch_core_session_get_channel(session);
PyThreadState *swapin_tstate = (PyThreadState *) switch_channel_get_private(channel, "SwapInThreadState"); PyThreadState *swapin_tstate = (PyThreadState *) switch_channel_get_private(channel, "SwapInThreadState");
// so lets assume nothing in the python script swapped any thread state in // so lets assume nothing in the python script swapped any thread state in
// or out .. thread state will currently be swapped in, and the SwapInThreadState // or out .. thread state will currently be swapped in, and the SwapInThreadState
// will be null // will be null
if (swapin_tstate == NULL) { if (swapin_tstate == NULL) {
// swap it out // clear out threadstate
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Threadstate mod_python.c swap-out! \n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "clear threadstate \n");
// PyEval_ReleaseThread(cur_tstate); // we know we are swapped in because swapin_tstate is NULL, and therefore we have the GIL, so
swapin_tstate = (void *) PyEval_SaveThread(); // it is safe to call PyThreadState_Get.
switch_channel_set_private(channel, "SwapInThreadState", (void *) swapin_tstate); PyThreadState *cur_tstate = PyThreadState_Get();
} PyThreadState_Clear(cur_tstate);
else { PyEval_ReleaseThread(cur_tstate);
// thread state is already swapped out, so, nothing for us to do PyThreadState_Delete(cur_tstate);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "according to chan priv data, already swapped out \n"); }
} else {
} // thread state is already swapped out, so, nothing for us to do
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "according to chan priv data, already swapped out \n");
}
}
else { else {
// they ran python script from cmd line, behave a bit differently (untested) // they ran python script from cmd line, behave a bit differently (untested)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Threadstate mod_python.c swap-out! \n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No session: Threadstate mod_python.c swap-out! \n");
PyEval_ReleaseThread(tstate); PyEval_ReleaseThread(tstate);
} }
switch_safe_free(dupargs); switch_safe_free(dupargs);
@ -290,22 +293,22 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_python_load)
if (!Py_IsInitialized()) { if (!Py_IsInitialized()) {
// initialize python system // initialize python system
Py_Initialize(); Py_Initialize();
// create GIL and a threadstate // create GIL and a threadstate
PyEval_InitThreads(); PyEval_InitThreads();
// save threadstate since it's interp field will be needed // save threadstate since it's interp field will be needed
// to create new threadstates, and will be needed for shutdown // to create new threadstates, and will be needed for shutdown
mainThreadState = PyThreadState_Get(); mainThreadState = PyThreadState_Get();
// swap out threadstate since the call threads will create // swap out threadstate since the call threads will create
// their own and swap in their threadstate // their own and swap in their threadstate
PyThreadState_Swap(NULL); PyThreadState_Swap(NULL);
// release GIL // release GIL
PyEval_ReleaseLock(); PyEval_ReleaseLock();
} }
/* indicate that the module should continue to be loaded */ /* indicate that the module should continue to be loaded */