UI: Fix a possible deadlock in the console (was introduced sometime after r3119).

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3425 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2010-07-08 14:02:50 +00:00
parent 2ffebed9de
commit 972cb2b891
2 changed files with 39 additions and 25 deletions

View File

@ -372,7 +372,7 @@ ConsoleLogFrame::~ConsoleLogFrame()
// Implementation note: Calls SetColor and Write( text ). Override those virtuals
// and this one will magically follow suite. :)
void ConsoleLogFrame::Write( ConsoleColors color, const wxString& text )
bool ConsoleLogFrame::Write( ConsoleColors color, const wxString& text )
{
pthread_testcancel();
@ -415,7 +415,7 @@ void ConsoleLogFrame::Write( ConsoleColors color, const wxString& text )
if( wxThread::IsMain() )
{
OnFlushEvent( evt );
return;
return false;
}
else
GetEventHandler()->AddPendingEvent( evt );
@ -426,33 +426,34 @@ void ConsoleLogFrame::Write( ConsoleColors color, const wxString& text )
if( !wxThread::IsMain() )
{
// Too many color changes causes huge slowdowns when decorating the rich textview, so
// include a secodary check to avoid having a colorful log spam from killing gui responsiveness.
// include a secondary check to avoid having a colorful log spam killing gui responsiveness.
if( m_CurQueuePos > 0x100000 || m_QueueColorSection.GetLength() > 256 )
{
++m_WaitingThreadsForFlush;
lock.Release();
if( !m_sem_QueueFlushed.Wait( wxTimeSpan( 0,0,0,250 ) ) )
{
// Necessary since the main thread could grab the lock and process before
// the above function actually returns (gotta love threading!)
// Note: if the queue flushes, we need to return TRUE, so that our thread sleeps
// until the main thread has had a chance to repaint the console window contents.
// [TODO] : It'd be a lot better if the console window repaint released the lock
// once its task were complete, but thats been problematic, so for now this hack is
// what we get.
if( m_sem_QueueFlushed.Wait( wxTimeSpan( 0,0,0,250 ) ) ) return true;
// If we're here it means QueueFlush wait timed out, so remove us from the waiting
// threads count. This way no thread permanently deadlocks against the console
// logger. They just run quite slow, but should remain responsive to user input.
lock.Acquire();
if( m_WaitingThreadsForFlush != 0 ) --m_WaitingThreadsForFlush;
}
else
{
// give gui thread time to repaint and handle other pending messages.
}
wxGetApp().Ping();
}
}
}
return false;
}
void ConsoleLogFrame::Newline()
bool ConsoleLogFrame::Newline()
{
Write( Color_Current, L"\n" );
return Write( Color_Current, L"\n" );
}
void ConsoleLogFrame::DockedMove()
@ -839,8 +840,13 @@ template< const IConsoleWriter& secondary >
static void __concall ConsoleToWindow_Newline()
{
secondary.Newline();
bool needsSleep = false;
{
ScopedLogLock locker;
if( locker.WindowPtr ) locker.WindowPtr->Newline();
if( locker.WindowPtr ) needsSleep = locker.WindowPtr->Newline();
}
if( needsSleep ) wxGetApp().Ping();
}
template< const IConsoleWriter& secondary >
@ -849,8 +855,12 @@ static void __concall ConsoleToWindow_DoWrite( const wxString& fmt )
if( secondary.DoWrite != NULL )
secondary.DoWrite( fmt );
bool needsSleep = false;
{
ScopedLogLock locker;
if( locker.WindowPtr ) locker.WindowPtr->Write( Console.GetColor(), fmt );
if( locker.WindowPtr ) needsSleep = locker.WindowPtr->Write( Console.GetColor(), fmt );
}
if( needsSleep ) wxGetApp().Ping();
}
template< const IConsoleWriter& secondary >
@ -859,8 +869,12 @@ static void __concall ConsoleToWindow_DoWriteLn( const wxString& fmt )
if( secondary.DoWriteLn != NULL )
secondary.DoWriteLn( fmt );
bool needsSleep = false;
{
ScopedLogLock locker;
if( locker.WindowPtr ) locker.WindowPtr->Write( Console.GetColor(), fmt + L'\n' );
if( locker.WindowPtr ) needsSleep = locker.WindowPtr->Write( Console.GetColor(), fmt + L'\n' );
}
if( needsSleep ) wxGetApp().Ping();
}
typedef void __concall DoWriteFn(const wxString&);

View File

@ -236,8 +236,8 @@ public:
// (settings change if the user moves the window or changes the font size)
const ConLogConfig& GetConfig() const { return m_conf; }
void Write( ConsoleColors color, const wxString& text );
void Newline();
bool Write( ConsoleColors color, const wxString& text );
bool Newline();
protected:
// menu callbacks