diff --git a/pcsx2/gui/ConsoleLogger.cpp b/pcsx2/gui/ConsoleLogger.cpp index 5b24b0d063..2874cf70bb 100644 --- a/pcsx2/gui/ConsoleLogger.cpp +++ b/pcsx2/gui/ConsoleLogger.cpp @@ -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!) - lock.Acquire(); - if( m_WaitingThreadsForFlush != 0 ) --m_WaitingThreadsForFlush; - } - else - { - // give gui thread time to repaint and handle other pending messages. + // 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; - wxGetApp().Ping(); - } + // 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; } } + + 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(); - ScopedLogLock locker; - if( locker.WindowPtr ) locker.WindowPtr->Newline(); + + bool needsSleep = false; + { + ScopedLogLock locker; + 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 ); - ScopedLogLock locker; - if( locker.WindowPtr ) locker.WindowPtr->Write( Console.GetColor(), fmt ); + bool needsSleep = false; + { + ScopedLogLock locker; + 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 ); - ScopedLogLock locker; - if( locker.WindowPtr ) locker.WindowPtr->Write( Console.GetColor(), fmt + L'\n' ); + bool needsSleep = false; + { + ScopedLogLock locker; + if( locker.WindowPtr ) needsSleep = locker.WindowPtr->Write( Console.GetColor(), fmt + L'\n' ); + } + if( needsSleep ) wxGetApp().Ping(); } typedef void __concall DoWriteFn(const wxString&); diff --git a/pcsx2/gui/ConsoleLogger.h b/pcsx2/gui/ConsoleLogger.h index 0aa5a1e6e8..df65093e11 100644 --- a/pcsx2/gui/ConsoleLogger.h +++ b/pcsx2/gui/ConsoleLogger.h @@ -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