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 <array>
 #include "TWorkerThreadController.h"
+#include <atltrace.h>
 
 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<HANDLE, eHandleCount> arrHandles = {
+		TEvent unsignaledEvent(true, false);
+
+		std::vector<HANDLE> 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<DWORD>(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;