mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-04 21:05:44 +00:00
Try to break potential deadlock between UI and replay threads
* During capture shutdown on Python < 3.13 the replay thread will try to remove itself as a debuggable thread which requires being able to run python (holding the GIL). If the UI thread is the one triggering the capture shutdown and is running a call from a python script it may hold the GIL while waiting for the replay thread to close, deadlocking. * To alleviate this, while the UI thread is about to block on the replay thread we try to release the python state if we are holding it so that the replay thread can run python code if needed. * We already do this in a manual wrapper around BlockInvoke.
This commit is contained in:
@@ -294,8 +294,12 @@ void ReplayManager::BlockInvoke(ReplayManager::ReplayInvokeCallback m)
|
||||
|
||||
PushInvoke(cmd);
|
||||
|
||||
void *ctx = PythonContext::PausePythonThreading();
|
||||
|
||||
cmd->processed.acquire();
|
||||
|
||||
PythonContext::ResumePythonThreading(ctx);
|
||||
|
||||
delete cmd;
|
||||
}
|
||||
|
||||
@@ -315,6 +319,8 @@ void ReplayManager::CloseThread()
|
||||
if(m_Thread == NULL)
|
||||
return;
|
||||
|
||||
void *ctx = PythonContext::PausePythonThreading();
|
||||
|
||||
// wait for the thread to close and clean up
|
||||
while(m_Thread->isRunning())
|
||||
{
|
||||
@@ -322,6 +328,8 @@ void ReplayManager::CloseThread()
|
||||
|
||||
m_Thread->deleteLater();
|
||||
m_Thread = NULL;
|
||||
|
||||
PythonContext::ResumePythonThreading(ctx);
|
||||
}
|
||||
|
||||
ResultDetails ReplayManager::ConnectToRemoteServer(RemoteHost host)
|
||||
|
||||
@@ -1146,12 +1146,13 @@ void PythonContext::Finish()
|
||||
|
||||
void *PythonContext::PausePythonThreading()
|
||||
{
|
||||
return PyEval_SaveThread();
|
||||
return PyGILState_Check() == 0 ? NULL : PyEval_SaveThread();
|
||||
}
|
||||
|
||||
void PythonContext::ResumePythonThreading(void *ctx)
|
||||
{
|
||||
PyEval_RestoreThread((PyThreadState *)ctx);
|
||||
if(ctx)
|
||||
PyEval_RestoreThread((PyThreadState *)ctx);
|
||||
}
|
||||
|
||||
void PythonContext::GlobalShutdown()
|
||||
|
||||
Reference in New Issue
Block a user