Index: src/libchcore/IOverlappedDataBufferQueue.h =================================================================== diff -u -re96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3 -r861eb97e5f43584f9537b4aff0558f6689bd0e38 --- src/libchcore/IOverlappedDataBufferQueue.h (.../IOverlappedDataBufferQueue.h) (revision e96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3) +++ src/libchcore/IOverlappedDataBufferQueue.h (.../IOverlappedDataBufferQueue.h) (revision 861eb97e5f43584f9537b4aff0558f6689bd0e38) @@ -39,6 +39,7 @@ virtual void AddFinishedBuffer(TOverlappedDataBuffer* pBuffer) = 0; virtual TOverlappedDataBuffer* GetFinishedBuffer() = 0; + virtual void MarkFinishedBufferAsComplete(TOverlappedDataBuffer* pBuffer) = 0; }; } Index: src/libchcore/TOverlappedDataBufferQueue.cpp =================================================================== diff -u -re8f31b0f922b402878356e130c866c4f3682a7f5 -r861eb97e5f43584f9537b4aff0558f6689bd0e38 --- src/libchcore/TOverlappedDataBufferQueue.cpp (.../TOverlappedDataBufferQueue.cpp) (revision e8f31b0f922b402878356e130c866c4f3682a7f5) +++ src/libchcore/TOverlappedDataBufferQueue.cpp (.../TOverlappedDataBufferQueue.cpp) (revision 861eb97e5f43584f9537b4aff0558f6689bd0e38) @@ -163,9 +163,7 @@ m_setFinishedBuffers.erase(m_setFinishedBuffers.begin()); - ++m_ullNextFinishedBufferOrder; - - UpdateWriteFinishedEvent(); + m_eventWriteFinished.ResetEvent(); // faster than UpdateWriteFinishedEvent() and the final effect should be the same m_eventAllBuffersAccountedFor.ResetEvent(); return pBuffer; @@ -174,6 +172,16 @@ return nullptr; } + void TOverlappedDataBufferQueue::MarkFinishedBufferAsComplete(TOverlappedDataBuffer* pBuffer) + { + if(!pBuffer) + throw TCoreException(eErr_InvalidPointer, L"pBuffer", LOCATION); + + // allow next finished buffer to be processed + ++m_ullNextFinishedBufferOrder; + UpdateWriteFinishedEvent(); + } + void TOverlappedDataBufferQueue::AddFinishedBuffer(TOverlappedDataBuffer* pBuffer) { if (!pBuffer) @@ -309,7 +317,7 @@ } } - void TOverlappedDataBufferQueue::WaitForMissingBuffers(HANDLE hKillEvent) + void TOverlappedDataBufferQueue::WaitForMissingBuffersAndResetState(HANDLE hKillEvent) { enum { eKillThread = 0, eAllBuffersReturned, eHandleCount }; std::array arrHandles = { hKillEvent, m_eventAllBuffersAccountedFor.Handle() }; @@ -333,5 +341,11 @@ break; } } + + std::copy(m_setFullBuffers.begin(), m_setFullBuffers.end(), std::back_inserter(m_listEmptyBuffers)); + std::copy(m_setFinishedBuffers.begin(), m_setFinishedBuffers.end(), std::back_inserter(m_listEmptyBuffers)); + + m_setFinishedBuffers.clear(); + m_setFullBuffers.clear(); } } Index: src/libchcore/TOverlappedDataBufferQueue.h =================================================================== diff -u -re96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3 -r861eb97e5f43584f9537b4aff0558f6689bd0e38 --- src/libchcore/TOverlappedDataBufferQueue.h (.../TOverlappedDataBufferQueue.h) (revision e96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3) +++ src/libchcore/TOverlappedDataBufferQueue.h (.../TOverlappedDataBufferQueue.h) (revision 861eb97e5f43584f9537b4aff0558f6689bd0e38) @@ -53,6 +53,7 @@ virtual void AddFinishedBuffer(TOverlappedDataBuffer* pBuffer) override; virtual TOverlappedDataBuffer* GetFinishedBuffer() override; + virtual void MarkFinishedBufferAsComplete(TOverlappedDataBuffer* pBuffer) override; // data source change void DataSourceChanged(); @@ -67,7 +68,7 @@ HANDLE GetEventWriteFinishedHandle() const { return m_eventWriteFinished.Handle(); } HANDLE GetEventAllBuffersAccountedFor() const { return m_eventAllBuffersAccountedFor.Handle(); } - void WaitForMissingBuffers(HANDLE hKillEvent); + void WaitForMissingBuffersAndResetState(HANDLE hKillEvent); private: void CleanupBuffers(); Index: src/libchcore/TSubTaskCopyMove.cpp =================================================================== diff -u -r011ceadef0413975974fa61983d903bf1a900ab6 -r861eb97e5f43584f9537b4aff0558f6689bd0e38 --- src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision 011ceadef0413975974fa61983d903bf1a900ab6) +++ src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision 861eb97e5f43584f9537b4aff0558f6689bd0e38) @@ -377,7 +377,10 @@ strFormat.Replace(_T("%srcpath"), pData->spSrcFile->GetFullFilePath().ToString()); strFormat.Replace(_T("%dstpath"), pData->pathDstFile.ToString()); rLog.logi(strFormat.c_str()); - return TSubTaskBase::eSubResult_KillRequest; + + eResult = TSubTaskBase::eSubResult_KillRequest; + bStopProcessing = true; + break; } case WAIT_OBJECT_0 + eReadPossible: @@ -391,14 +394,18 @@ eResult = tFileFBWrapper.ReadFileFB(fileSrc, *pBuffer, pData->spSrcFile->GetFullFilePath(), bSkip); if(eResult != TSubTaskBase::eSubResult_Continue) - return eResult; + { + pBuffer->RequeueAsEmpty(); + bStopProcessing = true; + } else if(bSkip) { - // new stats + pBuffer->RequeueAsEmpty(); + AdjustProcessedSizeForSkip(pData->spSrcFile); pData->bProcessed = false; - return TSubTaskBase::eSubResult_Continue; + bStopProcessing = true; } break; } @@ -418,23 +425,33 @@ // re-request read of the same data eResult = tFileFBWrapper.ReadFileFB(fileSrc, *pBuffer, pData->spSrcFile->GetFullFilePath(), bSkip); if(eResult != TSubTaskBase::eSubResult_Continue) - return eResult; + { + pBuffer->RequeueAsEmpty(); + bStopProcessing = true; + } else if(bSkip) { + pBuffer->RequeueAsEmpty(); + AdjustProcessedSizeForSkip(pData->spSrcFile); pData->bProcessed = false; - return TSubTaskBase::eSubResult_Continue; + bStopProcessing = true; } } else if(eResult != TSubTaskBase::eSubResult_Continue) - return eResult; + { + pBuffer->RequeueAsEmpty(); + bStopProcessing = true; + } else if(bSkip) { + pBuffer->RequeueAsEmpty(); + AdjustProcessedSizeForSkip(pData->spSrcFile); pData->bProcessed = false; - return TSubTaskBase::eSubResult_Continue; + bStopProcessing = true; } } else @@ -443,13 +460,18 @@ eResult = tFileFBWrapper.WriteFileFB(fileDst, *pBuffer, pData->pathDstFile, bSkip); if(eResult != TSubTaskBase::eSubResult_Continue) - return eResult; + { + pBuffer->RequeueAsEmpty(); + bStopProcessing = true; + } else if(bSkip) { + pBuffer->RequeueAsEmpty(); + AdjustProcessedSizeForSkip(pData->spSrcFile); pData->bProcessed = false; - return TSubTaskBase::eSubResult_Continue; + bStopProcessing = true; } } @@ -469,46 +491,74 @@ { eResult = tFileFBWrapper.WriteFileFB(fileDst, *pBuffer, pData->pathDstFile, bSkip); if(eResult != TSubTaskBase::eSubResult_Continue) - return eResult; + { + pBuffer->RequeueAsEmpty(); + bStopProcessing = true; + } else if(bSkip) { + pBuffer->RequeueAsEmpty(); + AdjustProcessedSizeForSkip(pData->spSrcFile); pData->bProcessed = false; - return TSubTaskBase::eSubResult_Continue; + bStopProcessing = true; } } else if(eResult != TSubTaskBase::eSubResult_Continue) - return eResult; + { + pBuffer->RequeueAsEmpty(); + bStopProcessing = true; + } else if(bSkip) { + pBuffer->RequeueAsEmpty(); + AdjustProcessedSizeForSkip(pData->spSrcFile); pData->bProcessed = false; - return TSubTaskBase::eSubResult_Continue; + bStopProcessing = true; } } else { eResult = tFileFBWrapper.FinalizeFileFB(fileDst, *pBuffer, pData->pathDstFile, bSkip); if (eResult != TSubTaskBase::eSubResult_Continue) - return eResult; + { + pBuffer->RequeueAsEmpty(); + bStopProcessing = true; + } else if (bSkip) { + pBuffer->RequeueAsEmpty(); + AdjustProcessedSizeForSkip(pData->spSrcFile); pData->bProcessed = false; - return TSubTaskBase::eSubResult_Continue; + bStopProcessing = true; } + else + { + file_size_t fsWritten = pBuffer->GetRealDataSize(); - file_size_t fsWritten = pBuffer->GetRealDataSize(); + // in case we read past the original eof, try to get new file size from filesystem + AdjustProcessedSize(fsWritten, pData->spSrcFile, fileSrc); - // in case we read past the original eof, try to get new file size from filesystem - AdjustProcessedSize(fsWritten, pData->spSrcFile, fileSrc); + // stop iterating through file + bStopProcessing = pBuffer->IsLastPart(); - // stop iterating through file - bStopProcessing = pBuffer->IsLastPart(); - pBuffer->RequeueAsEmpty(); + pData->dbBuffer.MarkFinishedBufferAsComplete(pBuffer); + pBuffer->RequeueAsEmpty(); + + if(bStopProcessing) + { + // this is the end of copying of src file - in case it is smaller than expected fix the stats so that difference is accounted for + AdjustFinalSize(pData->spSrcFile, fileSrc); + + pData->bProcessed = true; + m_tSubTaskStats.ResetCurrentItemProcessedSize(); + } + } } break; @@ -519,15 +569,9 @@ } } - // this is the end of copying of src file - in case it is smaller than expected fix the stats so that difference is accounted for - AdjustFinalSize(pData->spSrcFile, fileSrc); + pData->dbBuffer.WaitForMissingBuffersAndResetState(rThreadController.GetKillThreadHandle()); - pData->bProcessed = true; - m_tSubTaskStats.ResetCurrentItemProcessedSize(); - - pData->dbBuffer.WaitForMissingBuffers(rThreadController.GetKillThreadHandle()); - - return TSubTaskBase::eSubResult_Continue; + return eResult; } void TSubTaskCopyMove::AdjustProcessedSize(file_size_t fsWritten, const TFileInfoPtr& spSrcFileInfo, const IFilesystemFilePtr& spSrcFile)