Index: src/libchcore/TOverlappedReaderWriterFB.cpp =================================================================== diff -u -N -rf1d25f23712f5de7459f690ab51b2640d0f81b91 -r10d42e85d810f6da082cb2ce4415dcb72903410e --- src/libchcore/TOverlappedReaderWriterFB.cpp (.../TOverlappedReaderWriterFB.cpp) (revision f1d25f23712f5de7459f690ab51b2640d0f81b91) +++ src/libchcore/TOverlappedReaderWriterFB.cpp (.../TOverlappedReaderWriterFB.cpp) (revision 10d42e85d810f6da082cb2ce4415dcb72903410e) @@ -22,6 +22,7 @@ #include "ErrorCodes.h" #include #include "TWorkerThreadController.h" +#include namespace chcore { @@ -126,6 +127,8 @@ if(eResult != TSubTaskBase::eSubResult_Continue) return eResult; + m_spReader->StartThreaded(); + // 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) @@ -135,70 +138,61 @@ // - read possible - lowest priority - if we don't have anything to write or finalize , then read another part of source data enum { - eKillThread, eWriteFinished, eWriteFailed, eWritePossible, eReadFailed, eReadPossible, eHandleCount + eKillThread, eDataSourceFinished, eWriteFinished, eWriteFailed, eWritePossible }; - std::array arrHandles = { + TEvent unsignaledEvent(true, false); + + std::vector vHandles = { m_rThreadController.GetKillThreadHandle(), + m_spReader->GetReader()->GetEventDataSourceFinishedHandle(), m_spWriter->GetWriter()->GetEventWriteFinishedHandle(), m_spWriter->GetWriter()->GetEventWriteFailedHandle(), - m_spWriter->GetWriter()->GetEventWritePossibleHandle(), - m_spReader->GetReader()->GetEventReadFailedHandle(), - m_spReader->GetReader()->GetEventReadPossibleHandle() + m_spWriter->GetWriter()->GetEventWritePossibleHandle() }; bool bStopProcessing = false; while(!bStopProcessing && eResult == TSubTaskBase::eSubResult_Continue) { - DWORD dwResult = WaitForMultipleObjectsEx(eHandleCount, arrHandles.data(), false, INFINITE, true); + DWORD dwResult = WaitForMultipleObjectsEx(boost::numeric_cast(vHandles.size()), vHandles.data(), false, INFINITE, true); switch(dwResult) { case STATUS_USER_APC: break; case WAIT_OBJECT_0 + eKillThread: - { // log LOG_INFO(m_spLog) << L"Received kill request while copying file"; eResult = TSubTaskBase::eSubResult_KillRequest; bStopProcessing = true; break; - } - case WAIT_OBJECT_0 + eReadPossible: - { - eResult = m_spReader->OnReadPossible(); - break; - } - case WAIT_OBJECT_0 + eReadFailed: - { - eResult = m_spReader->OnReadFailed(); - break; - } case WAIT_OBJECT_0 + eWritePossible: - { eResult = m_spWriter->OnWritePossible(); break; - } case WAIT_OBJECT_0 + eWriteFailed: - { eResult = m_spWriter->OnWriteFailed(); break; - } case WAIT_OBJECT_0 + eWriteFinished: - { eResult = m_spWriter->OnWriteFinished(bStopProcessing); break; - } + case WAIT_OBJECT_0 + eDataSourceFinished: + eResult = m_spReader->StopThreaded(); + vHandles[eDataSourceFinished] = unsignaledEvent.Handle(); + break; + default: throw TCoreException(eErr_UnhandledCase, 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;