Index: src/libchcore/TSubTaskCopyMove.cpp =================================================================== diff -u -N -re0588f4598dea526e0869360a0f5ee278e7902a0 -r3ccbdb8d3eac3427e6d3354854476e57fdc7ceb9 --- src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision e0588f4598dea526e0869360a0f5ee278e7902a0) +++ src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision 3ccbdb8d3eac3427e6d3354854476e57fdc7ceb9) @@ -384,11 +384,13 @@ // that also means that we don't want to queue reads or writes anymore - all the data that were read until now, will be lost // - write possible - we're prioritizing write queuing here to empty buffers as soon as possible // - read possible - lowest priority - if we don't have anything to write or finalize , then read another part of source data - enum { eWriteFinished, eKillThread, eWritePossible, eReadPossible, eHandleCount }; + enum { eWriteFinished, eKillThread, eWriteFailed, eWritePossible, eReadFailed, eReadPossible, eHandleCount }; std::array arrHandles = { - tReaderWriter.GetEventWriteFinishedHandle(), rThreadController.GetKillThreadHandle(), + tReaderWriter.GetEventWriteFinishedHandle(), + tReaderWriter.GetEventWriteFailedHandle(), tReaderWriter.GetEventWritePossibleHandle(), + tReaderWriter.GetEventReadFailedHandle(), tReaderWriter.GetEventReadPossibleHandle() }; @@ -424,12 +426,12 @@ eResult = tFileFBWrapper.ReadFileFB(fileSrc, *pBuffer, pData->spSrcFile->GetFullFilePath(), bSkip); if(eResult != TSubTaskBase::eSubResult_Continue) { - tReaderWriter.AddEmptyBuffer(pBuffer); + tReaderWriter.AddEmptyBuffer(pBuffer, false); bStopProcessing = true; } else if(bSkip) { - tReaderWriter.AddEmptyBuffer(pBuffer); + tReaderWriter.AddEmptyBuffer(pBuffer, false); AdjustProcessedSizeForSkip(pData->spSrcFile); @@ -438,122 +440,129 @@ } break; } + case WAIT_OBJECT_0 + eReadFailed: + { + TOverlappedDataBuffer* pBuffer = tReaderWriter.GetFailedReadBuffer(); + if (!pBuffer) + throw TCoreException(eErr_InternalProblem, L"Cannot retrieve failed read buffer", LOCATION); + + // read error encountered - handle it + eResult = HandleReadError(spFeedbackHandler, *pBuffer, pData->spSrcFile->GetFullFilePath(), bSkip); + if(eResult == TSubTaskBase::eSubResult_Retry) + tReaderWriter.AddEmptyBuffer(pBuffer, true); + else if(eResult != TSubTaskBase::eSubResult_Continue) + { + tReaderWriter.AddEmptyBuffer(pBuffer, false); + bStopProcessing = true; + } + else if(bSkip) + { + tReaderWriter.AddEmptyBuffer(pBuffer, false); + + AdjustProcessedSizeForSkip(pData->spSrcFile); + + pData->bProcessed = false; + bStopProcessing = true; + } + + break; + } case WAIT_OBJECT_0 + eWritePossible: { - TOverlappedDataBuffer* pBuffer = tReaderWriter.GetFullBuffer(); + TOverlappedDataBuffer* pBuffer = tReaderWriter.GetFinishedReadBuffer(); if (!pBuffer) throw TCoreException(eErr_InternalProblem, L"Write was possible, but no buffer is available", LOCATION); // was there an error reported? - if(pBuffer->HasError()) + pBuffer->InitForWrite(); + + eResult = tFileFBWrapper.WriteFileFB(fileDst, *pBuffer, pData->pathDstFile, bSkip); + if(eResult != TSubTaskBase::eSubResult_Continue) { - // read error encountered - handle it - eResult = HandleReadError(spFeedbackHandler, *pBuffer, pData->spSrcFile->GetFullFilePath(), bSkip); - if(eResult == TSubTaskBase::eSubResult_Retry) - tReaderWriter.AddFailedReadBuffer(pBuffer); - else if(eResult != TSubTaskBase::eSubResult_Continue) - { - tReaderWriter.AddEmptyBuffer(pBuffer); - bStopProcessing = true; - } - else if(bSkip) - { - tReaderWriter.AddEmptyBuffer(pBuffer); + tReaderWriter.AddEmptyBuffer(pBuffer, false); + bStopProcessing = true; + } + else if(bSkip) + { + tReaderWriter.AddEmptyBuffer(pBuffer, false); - AdjustProcessedSizeForSkip(pData->spSrcFile); + AdjustProcessedSizeForSkip(pData->spSrcFile); - pData->bProcessed = false; - bStopProcessing = true; - } + pData->bProcessed = false; + bStopProcessing = true; } - else - { - pBuffer->InitForWrite(); - eResult = tFileFBWrapper.WriteFileFB(fileDst, *pBuffer, pData->pathDstFile, bSkip); - if(eResult != TSubTaskBase::eSubResult_Continue) - { - tReaderWriter.AddEmptyBuffer(pBuffer); - bStopProcessing = true; - } - else if(bSkip) - { - tReaderWriter.AddEmptyBuffer(pBuffer); + break; + } - AdjustProcessedSizeForSkip(pData->spSrcFile); + case WAIT_OBJECT_0 + eWriteFailed: + { + TOverlappedDataBuffer* pBuffer = tReaderWriter.GetFailedWriteBuffer(); + if (!pBuffer) + throw TCoreException(eErr_InternalProblem, L"Failed to retrieve write failed buffer", LOCATION); - pData->bProcessed = false; - bStopProcessing = true; - } + eResult = HandleWriteError(spFeedbackHandler, *pBuffer, pData->pathDstFile, bSkip); + if(eResult == TSubTaskBase::eSubResult_Retry) + tReaderWriter.AddFailedWriteBuffer(pBuffer); + else if(eResult != TSubTaskBase::eSubResult_Continue) + { + tReaderWriter.AddEmptyBuffer(pBuffer, false); + bStopProcessing = true; } + else if(bSkip) + { + tReaderWriter.AddEmptyBuffer(pBuffer, false); + AdjustProcessedSizeForSkip(pData->spSrcFile); + + pData->bProcessed = false; + bStopProcessing = true; + } + break; } case WAIT_OBJECT_0 + eWriteFinished: { - TOverlappedDataBuffer* pBuffer = tReaderWriter.GetFinishedBuffer(); + TOverlappedDataBuffer* pBuffer = tReaderWriter.GetFinishedWriteBuffer(); if (!pBuffer) throw TCoreException(eErr_InternalProblem, L"Write finished was possible, but no buffer is available", LOCATION); - if(pBuffer->HasError()) + eResult = tFileFBWrapper.FinalizeFileFB(fileDst, *pBuffer, pData->pathDstFile, bSkip); + if (eResult != TSubTaskBase::eSubResult_Continue) { - eResult = HandleWriteError(spFeedbackHandler, *pBuffer, pData->pathDstFile, bSkip); - if(eResult == TSubTaskBase::eSubResult_Retry) - tReaderWriter.AddFailedFullBuffer(pBuffer); - else if(eResult != TSubTaskBase::eSubResult_Continue) - { - tReaderWriter.AddEmptyBuffer(pBuffer); - bStopProcessing = true; - } - else if(bSkip) - { - tReaderWriter.AddEmptyBuffer(pBuffer); + tReaderWriter.AddEmptyBuffer(pBuffer, false); + bStopProcessing = true; + } + else if (bSkip) + { + tReaderWriter.AddEmptyBuffer(pBuffer, false); - AdjustProcessedSizeForSkip(pData->spSrcFile); + AdjustProcessedSizeForSkip(pData->spSrcFile); - pData->bProcessed = false; - bStopProcessing = true; - } + pData->bProcessed = false; + bStopProcessing = true; } else { - eResult = tFileFBWrapper.FinalizeFileFB(fileDst, *pBuffer, pData->pathDstFile, bSkip); - if (eResult != TSubTaskBase::eSubResult_Continue) - { - tReaderWriter.AddEmptyBuffer(pBuffer); - bStopProcessing = true; - } - else if (bSkip) - { - tReaderWriter.AddEmptyBuffer(pBuffer); + file_size_t fsWritten = pBuffer->GetRealDataSize(); - AdjustProcessedSizeForSkip(pData->spSrcFile); + // in case we read past the original eof, try to get new file size from filesystem + AdjustProcessedSize(fsWritten, pData->spSrcFile, fileSrc); - pData->bProcessed = false; - bStopProcessing = true; - } - else - { - file_size_t fsWritten = pBuffer->GetRealDataSize(); + // stop iterating through file + bStopProcessing = pBuffer->IsLastPart(); - // in case we read past the original eof, try to get new file size from filesystem - AdjustProcessedSize(fsWritten, pData->spSrcFile, fileSrc); + tReaderWriter.MarkFinishedBufferAsComplete(pBuffer); + tReaderWriter.AddEmptyBuffer(pBuffer, false); - // stop iterating through file - bStopProcessing = pBuffer->IsLastPart(); + 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); - tReaderWriter.MarkFinishedBufferAsComplete(pBuffer); - tReaderWriter.AddEmptyBuffer(pBuffer); - - 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(); - } + pData->bProcessed = true; + m_tSubTaskStats.ResetCurrentItemProcessedSize(); } }