Ensure that wxThread::Pause() suspends the thread immediately
Surprisingly, ::SuspendThread() doesn't actually do it, but only schedules the thread for suspension in some undetermined near future. This could result in problems as Pause() could exit, releasing the CS protecting wxThread internal data in the main thread, and allowing the worker thread to enter it (e.g. in its TestDestroy()) before being actually suspended, meaning that the thread got suspended inside a CS, which resulted in later deadlocks. Fix this by calling ::GetThreadContext() which is supposed to ensure that the scheduler does really suspend the thread before it returns (as it's impossible to get the context of a thread while it's running). Closes #18137.
This commit is contained in:
@@ -875,6 +875,20 @@ bool wxThreadInternal::Suspend()
|
||||
return false;
|
||||
}
|
||||
|
||||
// Calling GetThreadContext() forces the thread to actually be suspended:
|
||||
// just calling SuspendThread() is not enough, it just asks the scheduler
|
||||
// to suspend the thread at the next opportunity and by then we may already
|
||||
// exit wxThread::Pause() and leave m_critsect, meaning that the thread
|
||||
// could enter it and end up suspended inside a CS, which will inevitably
|
||||
// result in a deadlock later.
|
||||
CONTEXT ctx;
|
||||
// We don't really need the context, but we still must initialize it.
|
||||
ctx.ContextFlags = CONTEXT_FULL;
|
||||
if ( !::GetThreadContext(m_hThread, &ctx) )
|
||||
{
|
||||
wxLogLastError(wxS("GetThreadContext"));
|
||||
}
|
||||
|
||||
m_state = STATE_PAUSED;
|
||||
|
||||
return true;
|
||||
|
Reference in New Issue
Block a user