Index: src/liblogger/TAsyncMultiLogger.cpp =================================================================== diff -u -N -ra08ca9e12d93e9a036a5cf739348ff3ef2a58be8 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12 --- src/liblogger/TAsyncMultiLogger.cpp (.../TAsyncMultiLogger.cpp) (revision a08ca9e12d93e9a036a5cf739348ff3ef2a58be8) +++ src/liblogger/TAsyncMultiLogger.cpp (.../TAsyncMultiLogger.cpp) (revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12) @@ -32,32 +32,33 @@ TAsyncMultiLogger::TAsyncMultiLogger() : m_spStopEvent(CreateEvent(nullptr, TRUE, FALSE, nullptr), CloseHandle), + m_spStoppedEvent(CreateEvent(nullptr, TRUE, TRUE, nullptr), CloseHandle), m_spGlobalRotationInfo(std::make_shared()) { if (!m_spStopEvent) throw std::runtime_error("Cannot create stop event"); } - void TAsyncMultiLogger::FinishLogging() + TAsyncMultiLogger::~TAsyncMultiLogger() { - std::unique_ptr spThread; + FinishLogging(); + } + void TAsyncMultiLogger::FinishLogging() + { + SetEvent(m_spStopEvent.get()); + if(m_hThread) { - boost::unique_lock lock(m_mutex); - SetEvent(m_spStopEvent.get()); - std::swap(m_spThread, spThread); - } + WaitForSingleObject(m_spStoppedEvent.get(), INFINITE); - if(spThread) - { - if(spThread->joinable()) - spThread->join(); + // NOTE: for some unknown reason we can't wait for the thread event in shell extension even when the thread + // exited successfully. For that reason we're synchronizing thread exit with m_spStoppedEvent. + //WaitForSingleObject(m_hThread, INFINITE); + CloseHandle(m_hThread); + m_hThread = nullptr; } - { - boost::unique_lock lock(m_mutex); - m_setLoggerData.clear(); - } + m_setLoggerData.clear(); } TLogFileDataPtr TAsyncMultiLogger::CreateLoggerData(PCTSTR pszLogPath, const TMultiLoggerConfigPtr& spLoggerConfig) @@ -67,8 +68,8 @@ boost::unique_lock lock(m_mutex); m_setLoggerData.insert(spLogFileData); - if(!m_spThread) - m_spThread.reset(new std::thread(&TAsyncMultiLogger::LoggingThread, this)); + if(!m_hThread) + m_hThread = CreateThread(nullptr, 0, &LoggingThread, this, 0, nullptr); return spLogFileData; } @@ -88,19 +89,23 @@ m_spGlobalRotationInfo->SetRotatedCount(uiMaxRotatedCount); } - void TAsyncMultiLogger::LoggingThread() + DWORD TAsyncMultiLogger::LoggingThread(void* pParam) { + TAsyncMultiLogger* pAsyncLogger = (TAsyncMultiLogger*)pParam; + + ResetEvent(pAsyncLogger->m_spStoppedEvent.get()); + std::vector vHandles; bool bStopProcessing = false; do { { - boost::unique_lock lock(m_mutex); + boost::unique_lock lock(pAsyncLogger->m_mutex); vHandles.clear(); - vHandles.push_back(m_spStopEvent.get()); + vHandles.push_back(pAsyncLogger->m_spStopEvent.get()); - std::transform(m_setLoggerData.begin(), m_setLoggerData.end(), std::back_inserter(vHandles), [](const TLogFileDataPtr& rData) { return rData->GetEntriesEvent().get(); }); + std::transform(pAsyncLogger->m_setLoggerData.begin(), pAsyncLogger->m_setLoggerData.end(), std::back_inserter(vHandles), [](const TLogFileDataPtr& rData) { return rData->GetEntriesEvent().get(); }); } DWORD dwWaitResult = WaitForMultipleObjectsEx(boost::numeric_cast(vHandles.size()), &vHandles[ 0 ], FALSE, 500, FALSE); @@ -112,8 +117,8 @@ std::vector vLogs; { - boost::shared_lock lock(m_mutex); - vLogs.insert(vLogs.begin(), m_setLoggerData.begin(), m_setLoggerData.end()); + boost::shared_lock lock(pAsyncLogger->m_mutex); + vLogs.insert(vLogs.begin(), pAsyncLogger->m_setLoggerData.begin(), pAsyncLogger->m_setLoggerData.end()); } for (const TLogFileDataPtr& spLogData : vLogs) @@ -131,5 +136,8 @@ } } while(!bStopProcessing); + + SetEvent(pAsyncLogger->m_spStoppedEvent.get()); + return 0; } }