void CLogger::DoInitialiseThread() { _stopped = false; _logThread = std::thread( [this]() { while ( !_stopped ) { DoFlushQueue( true ); std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); } DoFlushQueue( false ); { std::unique_lock< std::mutex > l_lock( _mutexThreadEnded ); _threadEnded.notify_one(); } } ); }
void ConsoleLogFrame::DoFlushEvent( bool isPending ) { // recursion guard needed due to Mutex lock/acquire code below, which can end up yielding // to the gui and attempting to process more messages (which in turn would result in re- // entering this handler). static int recursion_counter = 0; RecursionGuard recguard( recursion_counter ); if( recguard.IsReentrant() ) return; ScopedLock locker( m_mtx_Queue ); if( m_CurQueuePos != 0 ) { DoFlushQueue(); } // Implementation note: I tried desperately to move this into wxEVT_IDLE, on the theory that // we don't actually want to wake up pending threads until after the GUI's finished all its // paperwork. But wxEVT_IDLE doesn't work when you click menus or the title bar of a window, // making it pretty well annoyingly useless for just about anything. >_< if( m_WaitingThreadsForFlush > 0 ) { do { m_sem_QueueFlushed.Post(); } while( --m_WaitingThreadsForFlush > 0 ); int count = m_sem_QueueFlushed.Count(); while( count < 0 ) { m_sem_QueueFlushed.Post(); count = m_sem_QueueFlushed.Count(); } } m_pendingFlushMsg = isPending; }