diff options
author | Jim Carroll <thecarrolls@jiminger.com> | 2013-10-19 14:06:21 -0400 |
---|---|---|
committer | Jim Carroll <thecarrolls@jiminger.com> | 2013-10-19 14:06:21 -0400 |
commit | 697065d89ae8f4ac9721fe03af31c5d8549d341a (patch) | |
tree | f79727090ed14b91ce9152884e53f8af23af4920 | |
parent | 43b17485b10b5d3964dad3b8a53c762823dabd9e (diff) |
[potential-fix] I ran into a few hangs-on-exit that this MAY help address. This allows the thread that's waiting for python threads to exit to raise python system exceptions within the threads it's trying to get to exit.
-rw-r--r-- | xbmc/interfaces/python/PythonInvoker.cpp | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/xbmc/interfaces/python/PythonInvoker.cpp b/xbmc/interfaces/python/PythonInvoker.cpp index dc9dae0e3f..d42140b484 100644 --- a/xbmc/interfaces/python/PythonInvoker.cpp +++ b/xbmc/interfaces/python/PythonInvoker.cpp @@ -65,6 +65,8 @@ extern "C" FILE *fopen_utf8(const char *_Filename, const char *_Mode); // Time before ill-behaved scripts are terminated #define PYTHON_SCRIPT_TIMEOUT 5000 // ms +#define THREAD_STOP_TIMEOUT_MILLIS 5000 + using namespace std; using namespace XFILE; @@ -322,6 +324,7 @@ bool CPythonInvoker::execute(const std::string &script, const std::vector<std::s CLog::Log(LOGERROR, "CPythonInvoker(%d, %s): failed to set abortRequested", GetId(), m_source); // make sure all sub threads have finished + XbmcThreads::EndTime waitTime(THREAD_STOP_TIMEOUT_MILLIS); // we will wait THREAD_STOP_TIMEOUT_MILLIS for any given thread to end for (PyThreadState* s = state->interp->tstate_head, *old = NULL; s;) { if (s == state) @@ -332,6 +335,7 @@ bool CPythonInvoker::execute(const std::string &script, const std::vector<std::s if (old != s) { CLog::Log(LOGINFO, "CPythonInvoker(%d, %s): waiting on thread %"PRIu64, GetId(), m_source, (uint64_t)s->thread_id); + waitTime.Set(THREAD_STOP_TIMEOUT_MILLIS); // reset the wait time old = s; } @@ -339,6 +343,15 @@ bool CPythonInvoker::execute(const std::string &script, const std::vector<std::s Sleep(100); pyState.Restore(); + if (waitTime.IsTimePast()) + { + // let's kick this and see if it helps + // Raise a SystemExit exception in python threads + Py_XDECREF(s->async_exc); + s->async_exc = PyExc_SystemExit; + Py_XINCREF(s->async_exc); + } + s = state->interp->tstate_head; } |