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<HANDLE, eHandleCount> 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)