Index: src/libchcore/TOverlappedReaderWriter.cpp =================================================================== diff -u -N -r1506d51ff1c0a5d156dab398051efc0c87473e81 -re0588f4598dea526e0869360a0f5ee278e7902a0 --- src/libchcore/TOverlappedReaderWriter.cpp (.../TOverlappedReaderWriter.cpp) (revision 1506d51ff1c0a5d156dab398051efc0c87473e81) +++ src/libchcore/TOverlappedReaderWriter.cpp (.../TOverlappedReaderWriter.cpp) (revision e0588f4598dea526e0869360a0f5ee278e7902a0) @@ -37,8 +37,8 @@ m_bDataWritingFinished(false), m_dwDataChunkSize(dwChunkSize), m_ullNextReadBufferOrder(ullFilePos), - m_ullNextWriteBufferOrder(0), - m_ullNextFinishedBufferOrder(0) + m_ullNextWriteBufferOrder(ullFilePos), + m_ullNextFinishedBufferOrder(ullFilePos) { if(!spMemoryPool) throw TCoreException(eErr_InvalidArgument, L"spMemoryPool", LOCATION); @@ -121,7 +121,7 @@ m_setFullBuffers.erase(m_setFullBuffers.begin()); - if(pBuffer->GetErrorCode() == ERROR_SUCCESS) + if(!pBuffer->HasError()) { // if this is the last part - mark that writing is finished, so that no other buffer will be written if(pBuffer->IsLastPart()) @@ -144,6 +144,42 @@ if (!pBuffer) throw TCoreException(eErr_InvalidPointer, L"pBuffer", LOCATION); + if(pBuffer->HasError()) + { + if(pBuffer->GetFilePosition() < m_ullReadErrorOrder) + { + // case: new buffer failed at even earlier position in file than the one that failed previously (should also work for numeric_limits::max()) + // - move existing buffers with errors to failed read buffers, add current one to full queue + m_ullReadErrorOrder = pBuffer->GetFilePosition(); + + TOrderedBufferQueue newQueue; + + for(TOverlappedDataBuffer* pBuf : m_setFullBuffers) + { + if(pBuf->HasError()) + AddFailedReadBuffer(pBuf); + else + newQueue.insert(pBuf); + } + + if(newQueue.size() != m_setFullBuffers.size()) + std::swap(m_setFullBuffers, newQueue); + } + else if(pBuffer->GetFilePosition() > m_ullReadErrorOrder) + { + // case: new buffer failed at position later than the one that failed before - add to failed buffers + // for retry + AddFailedReadBuffer(pBuffer); + return; + } + //else -> case: we've received the same buffer that failed before; add to normal full queue for user to handle that + } + else if(m_ullReadErrorOrder == pBuffer->GetFilePosition()) + { + // case: adding correctly read buffer that previously failed to read; clear the error flag and add full buffer + m_ullReadErrorOrder = NoIoError; + } + LOG_TRACE(m_spLog) << L"Queuing buffer as full; buffer-order: " << pBuffer->GetFilePosition() << L", requested-data-size: " << pBuffer->GetRequestedDataSize() << L", real-data-size: " << pBuffer->GetRealDataSize() <<