aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Carroll <thecarrolls@jiminger.com>2013-10-19 14:06:21 -0400
committerJim Carroll <thecarrolls@jiminger.com>2013-10-19 14:06:21 -0400
commit697065d89ae8f4ac9721fe03af31c5d8549d341a (patch)
treef79727090ed14b91ce9152884e53f8af23af4920
parent43b17485b10b5d3964dad3b8a53c762823dabd9e (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.cpp13
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;
}