Index: src/libchcore/TOverlappedReaderFB.cpp =================================================================== diff -u -r10d42e85d810f6da082cb2ce4415dcb72903410e -rb0a003dc39e6d21e34779cf1cf5d8a07318c1f5f --- src/libchcore/TOverlappedReaderFB.cpp (.../TOverlappedReaderFB.cpp) (revision 10d42e85d810f6da082cb2ce4415dcb72903410e) +++ src/libchcore/TOverlappedReaderFB.cpp (.../TOverlappedReaderFB.cpp) (revision b0a003dc39e6d21e34779cf1cf5d8a07318c1f5f) @@ -40,7 +40,8 @@ m_spSrcFile(), m_spStats(spStats), m_spSrcFileInfo(spSrcFileInfo), - m_rThreadController(rThreadController) + m_rThreadController(rThreadController), + m_eventDataSourceFinished(true, false) { if(!spFeedbackHandler) throw TCoreException(eErr_InvalidArgument, L"spFeedbackHandler is NULL", LOCATION); @@ -67,52 +68,18 @@ TSubTaskBase::ESubOperationResult TOverlappedReaderFB::StopThreaded() { - if(m_spReadThread) - { - if(m_spReadThread->joinable()) - m_spReadThread->join(); - m_spReadThread.reset(); - } - return m_eThreadResult; } - void TOverlappedReaderFB::StartThreaded() + TOrderedBufferQueuePtr TOverlappedReaderFB::GetFinishedQueue() const { - m_eThreadResult = TSubTaskBase::eSubResult_Continue; - m_spReadThread = std::make_unique(&TOverlappedReaderFB::ThreadProc, this); + return m_spReader->GetFinishedQueue(); } - TOverlappedReaderPtr TOverlappedReaderFB::GetReader() const + void TOverlappedReaderFB::StartThreaded() { - return m_spReader; - } + m_eThreadResult = TSubTaskBase::eSubResult_Continue; - TSubTaskBase::ESubOperationResult TOverlappedReaderFB::UpdateFileStats() - { - // update the source file size (it might differ from the time this file was originally scanned). - // NOTE: this kind of update could be also done when copying chunks of data beyond the original end-of-file, - // but it would require frequent total size updates and thus - serializations). - // NOTE2: the by-chunk corrections of stats are still applied when copying to ensure even further size - // matching; this update however still allows for better serialization management. - file_size_t fsOldSize = m_spSrcFileInfo->GetLength64(); - file_size_t fsNewSize = 0; - - TSubTaskBase::ESubOperationResult eResult = m_spSrcFile->GetFileSize(fsNewSize); - if(eResult != TSubTaskBase::eSubResult_Continue) - return eResult; - - if(fsNewSize != fsOldSize) - { - m_spStats->AdjustTotalSize(fsOldSize, fsNewSize); - m_spSrcFileInfo->SetLength64(fsNewSize); - } - - return eResult; - } - - void TOverlappedReaderFB::ThreadProc() - { // read data from file to buffer // NOTE: order is critical here: // - write finished is first, so that all the data that were already queued to be written, will be written and accounted for (in stats) @@ -154,6 +121,7 @@ case WAIT_OBJECT_0 + eDataSourceFinished: m_eThreadResult = TSubTaskBase::eSubResult_Continue; + m_eventDataSourceFinished.SetEvent(); return; default: @@ -162,11 +130,44 @@ } } + TOverlappedReaderPtr TOverlappedReaderFB::GetReader() const + { + return m_spReader; + } + + TSubTaskBase::ESubOperationResult TOverlappedReaderFB::UpdateFileStats() + { + // update the source file size (it might differ from the time this file was originally scanned). + // NOTE: this kind of update could be also done when copying chunks of data beyond the original end-of-file, + // but it would require frequent total size updates and thus - serializations). + // NOTE2: the by-chunk corrections of stats are still applied when copying to ensure even further size + // matching; this update however still allows for better serialization management. + file_size_t fsOldSize = m_spSrcFileInfo->GetLength64(); + file_size_t fsNewSize = 0; + + TSubTaskBase::ESubOperationResult eResult = m_spSrcFile->GetFileSize(fsNewSize); + if(eResult != TSubTaskBase::eSubResult_Continue) + return eResult; + + if(fsNewSize != fsOldSize) + { + m_spStats->AdjustTotalSize(fsOldSize, fsNewSize); + m_spSrcFileInfo->SetLength64(fsNewSize); + } + + return eResult; + } + void TOverlappedReaderFB::SetReleaseMode() { m_spReader->ReleaseBuffers(); } + HANDLE TOverlappedReaderFB::GetEventDataSourceFinishedHandle() const + { + return m_eventDataSourceFinished.Handle(); + } + TSubTaskBase::ESubOperationResult TOverlappedReaderFB::OnReadPossible() { TOverlappedDataBuffer* pBuffer = m_spReader->GetEmptyBuffer(); Index: src/libchcore/TOverlappedReaderFB.h =================================================================== diff -u -r10d42e85d810f6da082cb2ce4415dcb72903410e -rb0a003dc39e6d21e34779cf1cf5d8a07318c1f5f --- src/libchcore/TOverlappedReaderFB.h (.../TOverlappedReaderFB.h) (revision 10d42e85d810f6da082cb2ce4415dcb72903410e) +++ src/libchcore/TOverlappedReaderFB.h (.../TOverlappedReaderFB.h) (revision b0a003dc39e6d21e34779cf1cf5d8a07318c1f5f) @@ -23,6 +23,7 @@ #include "TFilesystemFileFeedbackWrapper.h" #include "TOverlappedProcessorRange.h" #include +#include "TThreadedQueueRunner.h" namespace chcore { @@ -42,33 +43,40 @@ DWORD dwChunkSize, bool bNoBuffering, bool bProtectReadOnlyFiles); + TOverlappedReaderFB(const TOverlappedReaderFB& rSrc) = delete; + ~TOverlappedReaderFB(); + TOverlappedReaderFB& operator=(const TOverlappedReaderFB& rSrc) = delete; + TSubTaskBase::ESubOperationResult Start(); void StartThreaded(); TSubTaskBase::ESubOperationResult StopThreaded(); - TOverlappedReaderPtr GetReader() const; + TOrderedBufferQueuePtr GetFinishedQueue() const; void SetReleaseMode(); - TSubTaskBase::ESubOperationResult OnReadPossible(); - TSubTaskBase::ESubOperationResult OnReadFailed(); + HANDLE GetEventDataSourceFinishedHandle() const; private: TSubTaskBase::ESubOperationResult UpdateFileStats(); - void ThreadProc(); + TSubTaskBase::ESubOperationResult OnReadPossible(); + TSubTaskBase::ESubOperationResult OnReadFailed(); + + TOverlappedReaderPtr GetReader() const; + private: TOverlappedReaderPtr m_spReader; + TEvent m_eventDataSourceFinished; IFilesystemPtr m_spFilesystem; TFilesystemFileFeedbackWrapperPtr m_spSrcFile; TSubTaskStatsInfoPtr m_spStats; TFileInfoPtr m_spSrcFileInfo; TWorkerThreadController& m_rThreadController; - std::unique_ptr m_spReadThread; TSubTaskBase::ESubOperationResult m_eThreadResult = TSubTaskBase::eSubResult_Continue; }; Index: src/libchcore/TOverlappedReaderWriterFB.cpp =================================================================== diff -u -r10d42e85d810f6da082cb2ce4415dcb72903410e -rb0a003dc39e6d21e34779cf1cf5d8a07318c1f5f --- src/libchcore/TOverlappedReaderWriterFB.cpp (.../TOverlappedReaderWriterFB.cpp) (revision 10d42e85d810f6da082cb2ce4415dcb72903410e) +++ src/libchcore/TOverlappedReaderWriterFB.cpp (.../TOverlappedReaderWriterFB.cpp) (revision b0a003dc39e6d21e34779cf1cf5d8a07318c1f5f) @@ -22,13 +22,15 @@ #include "ErrorCodes.h" #include #include "TWorkerThreadController.h" -#include +#include "TOverlappedThreadPool.h" +#include "TCoreWin32Exception.h" namespace chcore { TOverlappedReaderWriterFB::TOverlappedReaderWriterFB(const IFilesystemPtr& spFilesystem, const IFeedbackHandlerPtr& spFeedbackHandler, TWorkerThreadController& rThreadController, + TOverlappedThreadPool& rThreadPool, const TFileInfoPtr& spSrcFileInfo, const TSmartPath& pathDst, const TSubTaskStatsInfoPtr& spStats, @@ -41,11 +43,12 @@ bool bOnlyCreate) : m_spLog(logger::MakeLogger(spLogFileData, L"DataBuffer")), + m_rThreadPool(rThreadPool), m_rThreadController(rThreadController), m_spRange(std::make_shared(ullResumePosition)), m_spMemoryPool(spMemoryPool), m_spReader(std::make_shared(spFilesystem, spFeedbackHandler, rThreadController, spStats, spSrcFileInfo, spLogFileData, spMemoryPool->GetBufferList(), m_spRange, dwChunkSize, bNoBuffering, bProtectReadOnlyFiles)), - m_spWriter(std::make_shared(spFilesystem, spFeedbackHandler, rThreadController, spStats, spSrcFileInfo, pathDst, spLogFileData, m_spReader->GetReader()->GetFinishedQueue(), m_spRange, spMemoryPool->GetBufferList(), bOnlyCreate, bNoBuffering, bProtectReadOnlyFiles)) + m_spWriter(std::make_shared(spFilesystem, spFeedbackHandler, rThreadController, spStats, spSrcFileInfo, pathDst, spLogFileData, m_spReader->GetFinishedQueue(), m_spRange, spMemoryPool->GetBufferList(), bOnlyCreate, bNoBuffering, bProtectReadOnlyFiles)) { if(!spMemoryPool) throw TCoreException(eErr_InvalidArgument, L"spMemoryPool", LOCATION); @@ -127,7 +130,7 @@ if(eResult != TSubTaskBase::eSubResult_Continue) return eResult; - m_spReader->StartThreaded(); + m_rThreadPool.QueueRead(m_spReader); // read data from file to buffer // NOTE: order is critical here: @@ -145,7 +148,7 @@ std::vector vHandles = { m_rThreadController.GetKillThreadHandle(), - m_spReader->GetReader()->GetEventDataSourceFinishedHandle(), + m_spReader->GetEventDataSourceFinishedHandle(), m_spWriter->GetWriter()->GetEventWriteFinishedHandle(), m_spWriter->GetWriter()->GetEventWriteFailedHandle(), m_spWriter->GetWriter()->GetEventWritePossibleHandle() @@ -186,13 +189,11 @@ break; default: - throw TCoreException(eErr_UnhandledCase, L"Unknown result from async waiting function", LOCATION); + DWORD dwLastError = GetLastError(); + throw TCoreWin32Exception(eErr_UnhandledCase, dwLastError, L"Unknown result from async waiting function", LOCATION); } } - // ensure the reading thread is stopped (in case the switch version won't be called) - m_spReader->StopThreaded(); - WaitForMissingBuffersAndResetState(); return eResult; Index: src/libchcore/TOverlappedReaderWriterFB.h =================================================================== diff -u -rf1d25f23712f5de7459f690ab51b2640d0f81b91 -rb0a003dc39e6d21e34779cf1cf5d8a07318c1f5f --- src/libchcore/TOverlappedReaderWriterFB.h (.../TOverlappedReaderWriterFB.h) (revision f1d25f23712f5de7459f690ab51b2640d0f81b91) +++ src/libchcore/TOverlappedReaderWriterFB.h (.../TOverlappedReaderWriterFB.h) (revision b0a003dc39e6d21e34779cf1cf5d8a07318c1f5f) @@ -27,12 +27,15 @@ namespace chcore { + class TOverlappedThreadPool; + class TOverlappedReaderWriterFB { public: explicit TOverlappedReaderWriterFB(const IFilesystemPtr& spFilesystem, const IFeedbackHandlerPtr& spFeedbackHandler, TWorkerThreadController& rThreadController, + TOverlappedThreadPool& rThreadPool, const TFileInfoPtr& spSrcFileInfo, const TSmartPath& pathDst, const TSubTaskStatsInfoPtr& spStats, @@ -59,6 +62,7 @@ private: logger::TLoggerPtr m_spLog; + TOverlappedThreadPool& m_rThreadPool; TWorkerThreadController& m_rThreadController; TOverlappedProcessorRangePtr m_spRange; Index: src/libchcore/TOverlappedThreadPool.cpp =================================================================== diff -u --- src/libchcore/TOverlappedThreadPool.cpp (revision 0) +++ src/libchcore/TOverlappedThreadPool.cpp (revision b0a003dc39e6d21e34779cf1cf5d8a07318c1f5f) @@ -0,0 +1,44 @@ +// ============================================================================ +// 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 "TOverlappedThreadPool.h" + +namespace chcore +{ + TOverlappedThreadPool::TOverlappedThreadPool(HANDLE hKill) : + m_threadReader(hKill), + m_threadWriter(hKill) + { + } + + TReaderThread& TOverlappedThreadPool::ReaderThread() + { + return m_threadReader; + } + + TWriterThread& TOverlappedThreadPool::WriterThread() + { + return m_threadWriter; + } + + void TOverlappedThreadPool::QueueRead(const TOverlappedReaderFBPtr& spReader) + { + ReaderThread().PushTask(std::function(std::bind(&TOverlappedReaderFB::StartThreaded, std::ref(*spReader.get())))); + } +} Index: src/libchcore/TOverlappedThreadPool.h =================================================================== diff -u --- src/libchcore/TOverlappedThreadPool.h (revision 0) +++ src/libchcore/TOverlappedThreadPool.h (revision b0a003dc39e6d21e34779cf1cf5d8a07318c1f5f) @@ -0,0 +1,47 @@ +// ============================================================================ +// 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. +// ============================================================================ +#ifndef __TOVERLAPPEDTHREADPOOL_H__ +#define __TOVERLAPPEDTHREADPOOL_H__ + +#include +#include "TThreadedQueueRunner.h" +#include "TOverlappedReaderFB.h" + +namespace chcore +{ + using TReaderThread = TThreadedQueueRunner>; + using TWriterThread = TThreadedQueueRunner>; + + class TOverlappedThreadPool + { + public: + TOverlappedThreadPool(HANDLE hKill); + + TReaderThread& ReaderThread(); + TWriterThread& WriterThread(); + + void QueueRead(const TOverlappedReaderFBPtr& spReader); + + private: + TReaderThread m_threadReader; + TWriterThread m_threadWriter; + }; +} + +#endif Index: src/libchcore/TOverlappedWriterFB.h =================================================================== diff -u -rf1d25f23712f5de7459f690ab51b2640d0f81b91 -rb0a003dc39e6d21e34779cf1cf5d8a07318c1f5f --- src/libchcore/TOverlappedWriterFB.h (.../TOverlappedWriterFB.h) (revision f1d25f23712f5de7459f690ab51b2640d0f81b91) +++ src/libchcore/TOverlappedWriterFB.h (.../TOverlappedWriterFB.h) (revision b0a003dc39e6d21e34779cf1cf5d8a07318c1f5f) @@ -22,6 +22,7 @@ #include "TOverlappedWriter.h" #include "TFilesystemFileFeedbackWrapper.h" #include "TOverlappedProcessorRange.h" +#include "TThreadedQueueRunner.h" namespace chcore { @@ -41,8 +42,13 @@ bool bOnlyCreate, bool bNoBuffering, bool bProtectReadOnlyFiles); + + TOverlappedWriterFB(const TOverlappedWriterFB& rSrc) = delete; + ~TOverlappedWriterFB(); + TOverlappedWriterFB& operator=(const TOverlappedWriterFB& rSrc) = delete; + TSubTaskBase::ESubOperationResult Start(); TOverlappedWriterPtr GetWriter() const; Index: src/libchcore/TSubTaskCopyMove.cpp =================================================================== diff -u -rf1d25f23712f5de7459f690ab51b2640d0f81b91 -rb0a003dc39e6d21e34779cf1cf5d8a07318c1f5f --- src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision f1d25f23712f5de7459f690ab51b2640d0f81b91) +++ src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision b0a003dc39e6d21e34779cf1cf5d8a07318c1f5f) @@ -45,6 +45,8 @@ #include "TFilesystemFileFeedbackWrapper.h" #include "TDestinationPathProvider.h" #include "TOverlappedReaderWriterFB.h" +#include "TThreadedQueueRunner.h" +#include "TOverlappedThreadPool.h" namespace chcore { @@ -167,6 +169,8 @@ LOG_INFO(m_spLog) << strFormat.c_str(); + TOverlappedThreadPool threadPool(rThreadController.GetKillThreadHandle()); + for(; fcIndex < fcSize; fcIndex++) { // should we kill ? @@ -225,7 +229,7 @@ ccp.spSrcFile = spFileInfo; // copy data - eResult = CustomCopyFileFB(spFeedbackHandler, &ccp); + eResult = CustomCopyFileFB(spFeedbackHandler, threadPool, &ccp); if (eResult == eSubResult_SkipFile) { spFileInfo->MarkAsProcessed(false); @@ -337,7 +341,9 @@ } } - TSubTaskBase::ESubOperationResult TSubTaskCopyMove::CustomCopyFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, CUSTOM_COPY_PARAMS* pData) + TSubTaskBase::ESubOperationResult TSubTaskCopyMove::CustomCopyFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, + TOverlappedThreadPool& rThreadPool, + CUSTOM_COPY_PARAMS* pData) { TWorkerThreadController& rThreadController = GetContext().GetThreadController(); const TConfig& rConfig = GetContext().GetConfig(); @@ -364,8 +370,20 @@ // by OpenSrcAndDstFilesFB() - that includes the no-buffering setting if required. unsigned long long ullNextReadPos = m_spSubTaskStats->GetCurrentItemProcessedSize(); - TOverlappedReaderWriterFB tReaderWriter(spFilesystem, spFeedbackHandler, rThreadController, pData->spSrcFile, pData->pathDstFile, m_spSubTaskStats, m_spLog->GetLogFileData(), - pData->spMemoryPool, ullNextReadPos, dwCurrentBufferSize, bNoBuffer, GetTaskPropValue(rConfig), pData->bOnlyCreate); + TOverlappedReaderWriterFB tReaderWriter(spFilesystem, + spFeedbackHandler, + rThreadController, + rThreadPool, + pData->spSrcFile, + pData->pathDstFile, + m_spSubTaskStats, + m_spLog->GetLogFileData(), + pData->spMemoryPool, + ullNextReadPos, + dwCurrentBufferSize, + bNoBuffer, + GetTaskPropValue(rConfig), + pData->bOnlyCreate); ESubOperationResult eResult = tReaderWriter.Start(); Index: src/libchcore/TSubTaskCopyMove.h =================================================================== diff -u -r8aa9ecb7ccb06d721b9717a4bb664651b0b8b10e -rb0a003dc39e6d21e34779cf1cf5d8a07318c1f5f --- src/libchcore/TSubTaskCopyMove.h (.../TSubTaskCopyMove.h) (revision 8aa9ecb7ccb06d721b9717a4bb664651b0b8b10e) +++ src/libchcore/TSubTaskCopyMove.h (.../TSubTaskCopyMove.h) (revision b0a003dc39e6d21e34779cf1cf5d8a07318c1f5f) @@ -28,9 +28,12 @@ #include "TBufferSizes.h" #include "../liblogger/TLogger.h" #include "TOverlappedMemoryPool.h" +#include "TOverlappedReaderFB.h" +#include "TOverlappedWriterFB.h" namespace chcore { + class TOverlappedThreadPool; typedef std::shared_ptr TFileInfoPtr; struct CUSTOM_COPY_PARAMS; @@ -61,7 +64,9 @@ TBufferSizes::EBufferType GetBufferIndex(const TBufferSizes& rBufferSizes, const TFileInfoPtr& spFileInfo); bool AdjustBufferIfNeeded(const TOverlappedMemoryPoolPtr& spBuffer, TBufferSizes& rBufferSizes, bool bForce = false); - ESubOperationResult CustomCopyFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, CUSTOM_COPY_PARAMS* pData); + ESubOperationResult CustomCopyFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, + TOverlappedThreadPool& rThreadPool, + CUSTOM_COPY_PARAMS* pData); void AdjustProcessedSizeForSkip(const TFileInfoPtr& spSrcFileInfo); Index: src/libchcore/TThreadedQueueRunner.h =================================================================== diff -u --- src/libchcore/TThreadedQueueRunner.h (revision 0) +++ src/libchcore/TThreadedQueueRunner.h (revision b0a003dc39e6d21e34779cf1cf5d8a07318c1f5f) @@ -0,0 +1,113 @@ +// ============================================================================ +// 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. +// ============================================================================ +#ifndef __THREADEDQUEUERUNNER_H__ +#define __THREADEDQUEUERUNNER_H__ + +#include "WaitableQueue.h" +#include +#include + +namespace chcore +{ + template + class TThreadedQueueRunner + { + public: + TThreadedQueueRunner(HANDLE hKill) : + m_hKill(hKill), + m_eventLocalKill(true, false) + { + } + + TThreadedQueueRunner(const TThreadedQueueRunner& rSrc) = delete; + + ~TThreadedQueueRunner() + { + Stop(); + } + + TThreadedQueueRunner& operator=(const TThreadedQueueRunner& rSrc) = delete; + + void Start() + { + if(m_thread.joinable()) + return; + m_eventLocalKill.ResetEvent(); + + m_thread = std::thread(&TThreadedQueueRunner::ThreadProc, this); + } + + void Stop() + { + m_eventLocalKill.SetEvent(); + if(m_thread.joinable()) + m_thread.join(); + } + + void PushTask(T&& func) + { + if(!m_thread.joinable()) + Start(); + + m_queue.PushBack(std::forward(func)); + } + + private: + void ThreadProc() + { + enum { eKill, eLocalKill, eQueue, eCount }; + std::array arrHandles = { m_hKill, m_eventLocalKill.Handle(), m_queue.GetWaitHandle() }; + + bool bStop = false; + do + { + DWORD dwResult = WaitForMultipleObjectsEx(eCount, arrHandles.data(), FALSE, INFINITE, TRUE); + switch(dwResult) + { + case STATUS_USER_APC: + break; + + case WAIT_OBJECT_0 + eQueue: + { + T func = m_queue.PopFront(); + func(); + break; + } + + case WAIT_OBJECT_0 + eKill: + case WAIT_OBJECT_0 + eLocalKill: + default: + { + bStop = true; + break; + } + } + } + while(!bStop); + } + + private: + WaitableQueue m_queue; + std::thread m_thread; + HANDLE m_hKill = nullptr; + TEvent m_eventLocalKill; + }; +} + +#endif Index: src/libchcore/WaitableQueue.h =================================================================== diff -u --- src/libchcore/WaitableQueue.h (revision 0) +++ src/libchcore/WaitableQueue.h (revision b0a003dc39e6d21e34779cf1cf5d8a07318c1f5f) @@ -0,0 +1,69 @@ +// ============================================================================ +// 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. +// ============================================================================ +#ifndef __WAITABLEQUEUE_H__ +#define __WAITABLEQUEUE_H__ + +#include +#include +#include +#include "TEvent.h" + +namespace chcore +{ + template + class WaitableQueue + { + public: + WaitableQueue() : + m_eventHasEntries(true, false) + { + } + + void PushBack(T&& arg) + { + std::lock_guard lock(m_lock); + m_queue.push_back(std::forward(arg)); + m_eventHasEntries.SetEvent(); + } + + T PopFront() + { + std::lock_guard lock(m_lock); + + T value = std::move(m_queue.front()); + m_queue.pop_front(); + + m_eventHasEntries.SetEvent(!m_queue.empty()); + + return value; + } + + HANDLE GetWaitHandle() const + { + return m_eventHasEntries.Handle(); + } + + private: + std::deque m_queue; + TEvent m_eventHasEntries; + std::mutex m_lock; + }; +} + +#endif Index: src/libchcore/libchcore.vc140.vcxproj =================================================================== diff -u -rf1d25f23712f5de7459f690ab51b2640d0f81b91 -rb0a003dc39e6d21e34779cf1cf5d8a07318c1f5f --- src/libchcore/libchcore.vc140.vcxproj (.../libchcore.vc140.vcxproj) (revision f1d25f23712f5de7459f690ab51b2640d0f81b91) +++ src/libchcore/libchcore.vc140.vcxproj (.../libchcore.vc140.vcxproj) (revision b0a003dc39e6d21e34779cf1cf5d8a07318c1f5f) @@ -513,6 +513,8 @@ + + @@ -606,6 +608,7 @@ + @@ -835,6 +838,7 @@ + Index: src/libchcore/libchcore.vc140.vcxproj.filters =================================================================== diff -u -rf1d25f23712f5de7459f690ab51b2640d0f81b91 -rb0a003dc39e6d21e34779cf1cf5d8a07318c1f5f --- src/libchcore/libchcore.vc140.vcxproj.filters (.../libchcore.vc140.vcxproj.filters) (revision f1d25f23712f5de7459f690ab51b2640d0f81b91) +++ src/libchcore/libchcore.vc140.vcxproj.filters (.../libchcore.vc140.vcxproj.filters) (revision b0a003dc39e6d21e34779cf1cf5d8a07318c1f5f) @@ -66,9 +66,6 @@ {02c88ac8-15f7-4372-9f47-247ecbada7db} - - {202d13d3-126b-4811-8c1c-a14b4f0476b7} - {3de9b5f5-44fa-4e4b-9a63-f93d940d537a} @@ -81,30 +78,48 @@ {953a12ea-2aa5-4c7a-a310-a461ce8b962f} - - {94659973-1dd0-4e22-83c6-2fc26d3bf56e} - {64486dcc-0c2a-468c-9498-c4ff0c2183af} - - {2e089b8f-c085-4bce-a342-64c2611a717a} + + {076cbf8f-0110-48a9-9cbe-9929534ba1d1} - + + {70510fff-69c9-4ba7-beb1-55024077e6b5} + + + {4d6af45e-ee39-4520-830b-1eff232b8f0a} + + + {2bf8bd08-c6de-45fd-a047-8c90c07ac481} + + + {202d13d3-126b-4811-8c1c-a14b4f0476b7} + + {301c07b0-8112-4a01-9e47-9b32f6637be8} - + + {2e089b8f-c085-4bce-a342-64c2611a717a} + + + {94659973-1dd0-4e22-83c6-2fc26d3bf56e} + + {cc825cb7-bb97-45eb-86ed-ac031e1ca9e6} - + {712c0e1a-c6e3-4aab-8322-a9eea42e6d81} - - {076cbf8f-0110-48a9-9cbe-9929534ba1d1} + + {da2a09b3-c940-46ca-8161-a9f97fddf23e} - + {0015d34a-19cb-41da-a52d-1aedece5682c} + + {1412ea6d-b28c-4a96-b076-3094c476ce45} + @@ -467,41 +482,35 @@ Source Files\Tools - - Source Files\Tools\Data Buffer - Tests - Source Files\Tools\Data Buffer\ReaderWriter + Source Files\Filesystems\OverlappedIO\ReaderWriter - Source Files\Tools\Data Buffer\ReaderWriter + Source Files\Filesystems\OverlappedIO\ReaderWriter - Source Files\Tools\Data Buffer\Buffers + Source Files\Filesystems\OverlappedIO\Data Buffer\Buffers - - Source Files\Tools\Data Buffer\Buffers - - Source Files\Tools\Data Buffer\Buffers + Source Files\Filesystems\OverlappedIO\Data Buffer\Buffers - Source Files\Tools\Data Buffer\Queues\Simple + Source Files\Filesystems\OverlappedIO\ReaderWriter\Queues\Simple - Source Files\Tools\Data Buffer\Queues\Simple + Source Files\Filesystems\OverlappedIO\ReaderWriter\Queues\Simple - Source Files\Tools\Data Buffer\Queues\Simple + Source Files\Filesystems\OverlappedIO\ReaderWriter\Queues\Simple - Source Files\Tools\Data Buffer\Queues\Complex + Source Files\Filesystems\OverlappedIO\ReaderWriter\Queues\Complex - Source Files\Tools\Data Buffer\Queues\Complex + Source Files\Filesystems\OverlappedIO\ReaderWriter\Queues\Complex Source Files\Tools @@ -517,23 +526,38 @@ Source Files\Shared - Source Files\Feedback Wrappers + Source Files\Filesystems\OverlappedIO\Feedback Wrappers - Source Files\Feedback Wrappers + Source Files\Filesystems\OverlappedIO\Feedback Wrappers - Source Files\Feedback Wrappers + Source Files\Filesystems\OverlappedIO\Feedback Wrappers - Source Files\Feedback Wrappers + Source Files\Filesystems\OverlappedIO\Feedback Wrappers - Source Files\Feedback Wrappers + Source Files\Filesystems\OverlappedIO\Feedback Wrappers - Source Files\Tools\Data Buffer\ReaderWriter + Source Files\Filesystems\OverlappedIO\ReaderWriter + + Source Files\Tools\Queues + + + Source Files\Tools\Threading + + + Source Files\Filesystems\OverlappedIO\Data Buffer\BufferConfig + + + Source Files\Filesystems\OverlappedIO\ReaderWriter + + + Source Files\Filesystems\OverlappedIO\ThreadSupport + @@ -890,9 +914,6 @@ Source Files\Library files - - Source Files\Tools\Data Buffer - Tests\DataBuffer @@ -930,31 +951,28 @@ Tests\DataBuffer - Source Files\Tools\Data Buffer\ReaderWriter + Source Files\Filesystems\OverlappedIO\ReaderWriter - Source Files\Tools\Data Buffer\ReaderWriter + Source Files\Filesystems\OverlappedIO\ReaderWriter - Source Files\Tools\Data Buffer\Buffers + Source Files\Filesystems\OverlappedIO\Data Buffer\Buffers - - Source Files\Tools\Data Buffer\Buffers - - Source Files\Tools\Data Buffer\Buffers + Source Files\Filesystems\OverlappedIO\Data Buffer\Buffers - Source Files\Tools\Data Buffer\Queues\Simple + Source Files\Filesystems\OverlappedIO\ReaderWriter\Queues\Simple - Source Files\Tools\Data Buffer\Queues\Simple + Source Files\Filesystems\OverlappedIO\ReaderWriter\Queues\Simple - Source Files\Tools\Data Buffer\Queues\Complex + Source Files\Filesystems\OverlappedIO\ReaderWriter\Queues\Complex - Source Files\Tools\Data Buffer\Queues\Complex + Source Files\Filesystems\OverlappedIO\ReaderWriter\Queues\Complex Source Files\Tools @@ -966,23 +984,32 @@ Source Files\Tools - Source Files\Feedback Wrappers + Source Files\Filesystems\OverlappedIO\Feedback Wrappers - Source Files\Feedback Wrappers + Source Files\Filesystems\OverlappedIO\Feedback Wrappers - Source Files\Feedback Wrappers + Source Files\Filesystems\OverlappedIO\Feedback Wrappers - Source Files\Feedback Wrappers + Source Files\Filesystems\OverlappedIO\Feedback Wrappers - Source Files\Feedback Wrappers + Source Files\Filesystems\OverlappedIO\Feedback Wrappers - Source Files\Tools\Data Buffer\ReaderWriter + Source Files\Filesystems\OverlappedIO\ReaderWriter + + Source Files\Filesystems\OverlappedIO\Data Buffer\BufferConfig + + + Source Files\Filesystems\OverlappedIO\ReaderWriter + + + Source Files\Filesystems\OverlappedIO\ThreadSupport +