/** * The unsynchronized version of FlushThreadedLogs. * Assumes that the caller holds a lock on SynchronizationObject. */ void FOutputDeviceRedirector::UnsynchronizedFlushThreadedLogs( bool bUseAllDevices ) { for(int32 LineIndex = 0;LineIndex < BufferedLines.Num();LineIndex++) { FBufferedLine BufferedLine = BufferedLines[LineIndex]; for( int32 OutputDeviceIndex=0; OutputDeviceIndex<OutputDevices.Num(); OutputDeviceIndex++ ) { FOutputDevice* OutputDevice = OutputDevices[OutputDeviceIndex]; if( OutputDevice->CanBeUsedOnAnyThread() || bUseAllDevices ) { OutputDevice->Serialize( *BufferedLine.Data, BufferedLine.Verbosity, BufferedLine.Category, BufferedLine.Time ); } } } BufferedLines.Empty(); }
void FOutputDeviceRedirector::PanicFlushThreadedLogs() { SCOPE_CYCLE_COUNTER(STAT_FlushThreadedLogs); // Acquire a lock on SynchronizationObject and call the unsynchronized worker function. FScopeLock ScopeLock( &SynchronizationObject ); // Flush threaded logs, but use the safe version. UnsynchronizedFlushThreadedLogs( false ); // Flush devices. for (int32 OutputDeviceIndex = 0; OutputDeviceIndex<OutputDevices.Num(); OutputDeviceIndex++) { FOutputDevice* OutputDevice = OutputDevices[OutputDeviceIndex]; if (OutputDevice->CanBeUsedOnAnyThread()) { OutputDevice->Flush(); } } BufferedLines.Empty(); }