Index: src/liblogger/TAsyncMultiLogger.cpp =================================================================== diff -u -N -raa18f0444eecb7f31ecc142bf53509c48ac77b35 -ra4635addad389b9e117679437a3e1b64a739ea96 --- src/liblogger/TAsyncMultiLogger.cpp (.../TAsyncMultiLogger.cpp) (revision aa18f0444eecb7f31ecc142bf53509c48ac77b35) +++ src/liblogger/TAsyncMultiLogger.cpp (.../TAsyncMultiLogger.cpp) (revision a4635addad389b9e117679437a3e1b64a739ea96) @@ -1,149 +1,149 @@ -// ============================================================================ -// Copyright (C) 2001-2016 by Jozef Starosczyk -// ixen@copyhandler.com -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU Library General Public License -// (version 2) as published by the Free Software Foundation; -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this program; if not, write to the -// Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ============================================================================ -#include "stdafx.h" -#include "TAsyncMultiLogger.h" -#include -#include -#include - -namespace logger -{ - TAsyncMultiLoggerPtr TAsyncMultiLogger::GetInstance() - { - static TAsyncMultiLoggerPtr Logger(new TAsyncMultiLogger); - return Logger; - } - - 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"); - } - - TAsyncMultiLogger::~TAsyncMultiLogger() - { - FinishLogging(); - } - - void TAsyncMultiLogger::FinishLogging() - { - SetEvent(m_spStopEvent.get()); - if(m_hThread) - { - WaitForSingleObject(m_spStoppedEvent.get(), INFINITE); - - // 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; - } - - m_setLoggerData.clear(); - } - - TLogFileDataPtr TAsyncMultiLogger::CreateLoggerData(PCTSTR pszLogPath, const TMultiLoggerConfigPtr& spLoggerConfig) - { - TLogFileDataPtr spLogFileData = std::make_shared(pszLogPath, spLoggerConfig, m_spGlobalRotationInfo); - - boost::unique_lock lock(m_mutex); - m_setLoggerData.insert(spLogFileData); - - if(!m_hThread) - m_hThread = CreateThread(nullptr, 0, &LoggingThread, this, 0, nullptr); - - return spLogFileData; - } - - TLoggerRotationInfoPtr TAsyncMultiLogger::GetRotationInfo() const - { - return m_spGlobalRotationInfo; - } - - void TAsyncMultiLogger::SetMaxLogSize(unsigned int uiMaxLogSize) - { - m_spGlobalRotationInfo->SetMaxLogSize(uiMaxLogSize); - } - - void TAsyncMultiLogger::SetMaxRotatedCount(unsigned int uiMaxRotatedCount) - { - m_spGlobalRotationInfo->SetRotatedCount(uiMaxRotatedCount); - } - - DWORD TAsyncMultiLogger::LoggingThread(void* pParam) - { - TAsyncMultiLogger* pAsyncLogger = (TAsyncMultiLogger*)pParam; - - ResetEvent(pAsyncLogger->m_spStoppedEvent.get()); - - try - { - std::vector vHandles; - - bool bStopProcessing = false; - do - { - { - boost::unique_lock lock(pAsyncLogger->m_mutex); - vHandles.clear(); - vHandles.push_back(pAsyncLogger->m_spStopEvent.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); - if(dwWaitResult == WAIT_OBJECT_0) - { - bStopProcessing = true; - break; - } - - std::vector vLogs; - { - boost::shared_lock lock(pAsyncLogger->m_mutex); - vLogs.insert(vLogs.begin(), pAsyncLogger->m_setLoggerData.begin(), pAsyncLogger->m_setLoggerData.end()); - } - - for(const TLogFileDataPtr& spLogData : vLogs) - { - try - { - spLogData->StoreLogEntries(); - spLogData->CloseUnusedFile(); - } - catch(const std::exception& e) - { - e; - ATLTRACE(e.what()); - } - } - } - while(!bStopProcessing); - } - catch(const std::exception&) - { - } - - SetEvent(pAsyncLogger->m_spStoppedEvent.get()); - return 0; - } -} +// ============================================================================ +// Copyright (C) 2001-2016 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#include "stdafx.h" +#include "TAsyncMultiLogger.h" +#include +#include +#include + +namespace logger +{ + TAsyncMultiLoggerPtr TAsyncMultiLogger::GetInstance() + { + static TAsyncMultiLoggerPtr Logger(new TAsyncMultiLogger); + return Logger; + } + + 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"); + } + + TAsyncMultiLogger::~TAsyncMultiLogger() + { + FinishLogging(); + } + + void TAsyncMultiLogger::FinishLogging() + { + SetEvent(m_spStopEvent.get()); + if(m_hThread) + { + WaitForSingleObject(m_spStoppedEvent.get(), INFINITE); + + // 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; + } + + m_setLoggerData.clear(); + } + + TLogFileDataPtr TAsyncMultiLogger::CreateLoggerData(PCTSTR pszLogPath, const TMultiLoggerConfigPtr& spLoggerConfig) + { + TLogFileDataPtr spLogFileData = std::make_shared(pszLogPath, spLoggerConfig, m_spGlobalRotationInfo); + + boost::unique_lock lock(m_mutex); + m_setLoggerData.insert(spLogFileData); + + if(!m_hThread) + m_hThread = CreateThread(nullptr, 0, &LoggingThread, this, 0, nullptr); + + return spLogFileData; + } + + TLoggerRotationInfoPtr TAsyncMultiLogger::GetRotationInfo() const + { + return m_spGlobalRotationInfo; + } + + void TAsyncMultiLogger::SetMaxLogSize(unsigned int uiMaxLogSize) + { + m_spGlobalRotationInfo->SetMaxLogSize(uiMaxLogSize); + } + + void TAsyncMultiLogger::SetMaxRotatedCount(unsigned int uiMaxRotatedCount) + { + m_spGlobalRotationInfo->SetRotatedCount(uiMaxRotatedCount); + } + + DWORD TAsyncMultiLogger::LoggingThread(void* pParam) + { + TAsyncMultiLogger* pAsyncLogger = (TAsyncMultiLogger*)pParam; + + ResetEvent(pAsyncLogger->m_spStoppedEvent.get()); + + try + { + std::vector vHandles; + + bool bStopProcessing = false; + do + { + { + boost::unique_lock lock(pAsyncLogger->m_mutex); + vHandles.clear(); + vHandles.push_back(pAsyncLogger->m_spStopEvent.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); + if(dwWaitResult == WAIT_OBJECT_0) + { + bStopProcessing = true; + break; + } + + std::vector vLogs; + { + boost::shared_lock lock(pAsyncLogger->m_mutex); + vLogs.insert(vLogs.begin(), pAsyncLogger->m_setLoggerData.begin(), pAsyncLogger->m_setLoggerData.end()); + } + + for(const TLogFileDataPtr& spLogData : vLogs) + { + try + { + spLogData->StoreLogEntries(); + spLogData->CloseUnusedFile(); + } + catch(const std::exception& e) + { + e; + ATLTRACE(e.what()); + } + } + } + while(!bStopProcessing); + } + catch(const std::exception&) + { + } + + SetEvent(pAsyncLogger->m_spStoppedEvent.get()); + return 0; + } +}