Index: src/ch/MainWnd.cpp =================================================================== diff -u -r8422e5787e56453d78c7270066c3e8d1743ca757 -rd0bc3c187684f54894c7280a936d5507a5e49f35 --- src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision 8422e5787e56453d78c7270066c3e8d1743ca757) +++ src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision d0bc3c187684f54894c7280a936d5507a5e49f35) @@ -244,7 +244,7 @@ try { - m_spTasks.reset(new chcore::TTaskManager(spSerializerFactory, spFeedbackFactory)); + m_spTasks.reset(new chcore::TTaskManager(spSerializerFactory, spFeedbackFactory, PathFromString(strTasksDir))); } catch(const std::exception& e) { @@ -255,7 +255,7 @@ { if(MsgBox(IDS_TASKMANAGER_LOAD_FAILED, MB_ICONERROR | MB_OKCANCEL) == IDOK) { - m_spTasks.reset(new chcore::TTaskManager(spSerializerFactory, spFeedbackFactory, true)); + m_spTasks.reset(new chcore::TTaskManager(spSerializerFactory, spFeedbackFactory, PathFromString(strTasksDir), true)); } else return false; Index: src/libchcore/TSQLiteTaskSchema.cpp =================================================================== diff -u -rff16e23b043c1c3f3ea883372b6f81d7ad4adca3 -rd0bc3c187684f54894c7280a936d5507a5e49f35 --- src/libchcore/TSQLiteTaskSchema.cpp (.../TSQLiteTaskSchema.cpp) (revision ff16e23b043c1c3f3ea883372b6f81d7ad4adca3) +++ src/libchcore/TSQLiteTaskSchema.cpp (.../TSQLiteTaskSchema.cpp) (revision d0bc3c187684f54894c7280a936d5507a5e49f35) @@ -75,17 +75,17 @@ tStatement.Prepare(_T("CREATE TABLE subtasks_info(id BIGINT UNIQUE, operation INT NOT NULL)")); tStatement.Step(); - tStatement.Prepare(_T("CREATE TABLE subtask_fastmove(id BIGINT UNIQUE, current_index INT NOT NULL, is_running boolean NOT NULL, total_size BIGINT NOT NULL, processed_size BIGINT NOT NULL, size_speed varchar(1024) NOT NULL, ") + tStatement.Prepare(_T("CREATE TABLE subtask_fastmove(id BIGINT UNIQUE, current_index INT NOT NULL, is_running boolean NOT NULL, is_initialized boolean NOT NULL, total_size BIGINT NOT NULL, processed_size BIGINT NOT NULL, size_speed varchar(1024) NOT NULL, ") _T("total_count BIGINT NOT NULL, processed_count BIGINT NOT NULL, count_speed varchar(1024) NOT NULL, ci_processed_size BIGINT NOT NULL, ci_total_size BIGINT NOT NULL, timer BIGINT NOT NULL, ") _T("buffer_index INT NOT NULL, current_path varchar(32768) NOT NULL, suboperation_type INT NOT NULL)")); tStatement.Step(); - tStatement.Prepare(_T("CREATE TABLE subtask_delete(id BIGINT UNIQUE, current_index INT NOT NULL, is_running boolean NOT NULL, total_size BIGINT NOT NULL, processed_size BIGINT NOT NULL, size_speed varchar(1024) NOT NULL, ") + tStatement.Prepare(_T("CREATE TABLE subtask_delete(id BIGINT UNIQUE, current_index INT NOT NULL, is_running boolean NOT NULL, is_initialized boolean NOT NULL, total_size BIGINT NOT NULL, processed_size BIGINT NOT NULL, size_speed varchar(1024) NOT NULL, ") _T("total_count BIGINT NOT NULL, processed_count BIGINT NOT NULL, count_speed varchar(1024) NOT NULL, ci_processed_size BIGINT NOT NULL, ci_total_size BIGINT NOT NULL, timer BIGINT NOT NULL, ") _T("buffer_index INT NOT NULL, current_path varchar(32768) NOT NULL, suboperation_type INT NOT NULL)")); tStatement.Step(); - tStatement.Prepare(_T("CREATE TABLE subtask_copymove(id BIGINT UNIQUE, current_index INT NOT NULL, cf_processed_size BIGINT NOT NULL, is_running boolean NOT NULL, total_size BIGINT NOT NULL, processed_size BIGINT NOT NULL, size_speed varchar(1024) NOT NULL, ") + tStatement.Prepare(_T("CREATE TABLE subtask_copymove(id BIGINT UNIQUE, current_index INT NOT NULL, cf_processed_size BIGINT NOT NULL, is_running boolean NOT NULL, is_initialized boolean NOT NULL, total_size BIGINT NOT NULL, processed_size BIGINT NOT NULL, size_speed varchar(1024) NOT NULL, ") _T("total_count BIGINT NOT NULL, processed_count BIGINT NOT NULL, count_speed varchar(1024) NOT NULL, ci_processed_size BIGINT NOT NULL, ci_total_size BIGINT NOT NULL, timer BIGINT NOT NULL, ") _T("buffer_index INT NOT NULL, current_path varchar(32768) NOT NULL, suboperation_type INT NOT NULL)")); tStatement.Step(); Index: src/libchcore/TSubTaskArray.cpp =================================================================== diff -u -rff16e23b043c1c3f3ea883372b6f81d7ad4adca3 -rd0bc3c187684f54894c7280a936d5507a5e49f35 --- src/libchcore/TSubTaskArray.cpp (.../TSubTaskArray.cpp) (revision ff16e23b043c1c3f3ea883372b6f81d7ad4adca3) +++ src/libchcore/TSubTaskArray.cpp (.../TSubTaskArray.cpp) (revision d0bc3c187684f54894c7280a936d5507a5e49f35) @@ -120,7 +120,7 @@ size_t stSize = m_vSubTasks.size(); long lIndex = m_lSubOperationIndex.load(boost::memory_order_acquire); - while(lIndex < stSize && eResult == TSubTaskBase::eSubResult_Continue) + while(boost::numeric_cast(lIndex) < stSize) { std::pair& rCurrentSubTask = m_vSubTasks.at(lIndex); TSubTaskBasePtr spCurrentSubTask = rCurrentSubTask.first; @@ -133,6 +133,8 @@ } eResult = spCurrentSubTask->Exec(); + if(eResult != TSubTaskBase::eSubResult_Continue) + break; lIndex = m_lSubOperationIndex.fetch_add(1, boost::memory_order_release) + 1; } @@ -222,7 +224,7 @@ if(bAdded || lCurrentIndex != m_lLastStoredIndex) { // mark subtask at current index as "current"; don't do that if we just finished. - if(lCurrentIndex != m_vSubTasks.size()) + if(boost::numeric_cast(lCurrentIndex) != m_vSubTasks.size()) { spRow = spContainer->GetRow(lCurrentIndex); *spRow % TRowData(_T("is_current"), true); @@ -298,7 +300,7 @@ TSubTaskBasePtr spSubTask = CreateSubtask((ESubOperationType)iType, m_rSubTaskContext); spSubTask->Load(spSerializer); - if(lID != m_vSubTasks.size()) + if(boost::numeric_cast(lID) != m_vSubTasks.size()) THROW_CORE_EXCEPTION(eErr_InvalidData); m_vSubTasks.push_back(std::make_pair(spSubTask, bIsEstimation)); Index: src/libchcore/TSubTaskCopyMove.cpp =================================================================== diff -u -r19925be73ffcadd9f345f10e03e55aadb3f0eeac -rd0bc3c187684f54894c7280a936d5507a5e49f35 --- src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision 19925be73ffcadd9f345f10e03e55aadb3f0eeac) +++ src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision d0bc3c187684f54894c7280a936d5507a5e49f35) @@ -102,6 +102,12 @@ m_ullCurrentFileProcessedSize.Modify() += ullSizeToAdd; } + void TCopyMoveProgressInfo::DecreaseCurrentFileProcessedSize(unsigned long long ullSizeToSubtract) + { + boost::unique_lock lock(m_lock); + m_ullCurrentFileProcessedSize.Modify() -= ullSizeToSubtract; + } + void TCopyMoveProgressInfo::Store(const ISerializerRowDataPtr& spRowData) const { boost::shared_lock lock(m_lock); @@ -182,13 +188,13 @@ // log rLog.logi(_T("Processing files/folders (ProcessFiles)")); - // new stats - m_tSubTaskStats.SetCurrentBufferIndex(TBufferSizes::eBuffer_Default); - m_tSubTaskStats.SetTotalCount(rFilesCache.GetSize()); - m_tSubTaskStats.SetProcessedCount(rFilesCache.GetSize()); - m_tSubTaskStats.SetTotalSize(rFilesCache.CalculateTotalSize()); - m_tSubTaskStats.SetProcessedSize(rFilesCache.CalculatePartialSize(m_tProgressInfo.GetCurrentIndex())); - m_tSubTaskStats.SetCurrentPath(TString()); + // initialize stats if not resuming (when resuming we have already initialized + // the stats once - it is being restored in Load() too). + if(!m_tSubTaskStats.IsInitialized()) + { + m_tSubTaskStats.Init(TBufferSizes::eBuffer_Default, rFilesCache.GetSize(), 0/*rFilesCache.GetSize()*/, + rFilesCache.CalculateTotalSize(), rFilesCache.CalculatePartialSize(m_tProgressInfo.GetCurrentIndex()), TString()); + } // now it's time to check if there is enough space on destination device TSubTaskBase::ESubOperationResult eResult = CheckForFreeSpaceFB(); @@ -503,10 +509,11 @@ else if(!fileSrc.IsOpen()) { // invalid handle = operation skipped by user - // new stats - m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); - m_tSubTaskStats.IncreaseCurrentItemProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + unsigned long long ullDiff = pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize(); + m_tSubTaskStats.IncreaseProcessedSize(ullDiff); + m_tSubTaskStats.IncreaseCurrentItemProcessedSize(ullDiff); + pData->bProcessed = false; bSkip = true; return TSubTaskBase::eSubResult_Continue; @@ -519,7 +526,7 @@ SetFileAttributes(pData->pathDstFile.ToString(), FILE_ATTRIBUTE_NORMAL); // open destination file, handle the failures and possibly existence of the destination file - unsigned long long ullSeekTo = 0; + unsigned long long ullSeekTo = m_tProgressInfo.GetCurrentFileProcessedSize(); bool bDstFileFreshlyCreated = false; if(m_tProgressInfo.GetCurrentFileProcessedSize() == 0) @@ -531,10 +538,11 @@ return eResult; else if(!fileDst.IsOpen()) { - // new stats - m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); - m_tSubTaskStats.IncreaseCurrentItemProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + unsigned long long ullDiff = pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize(); + m_tSubTaskStats.IncreaseProcessedSize(ullDiff); + m_tSubTaskStats.IncreaseCurrentItemProcessedSize(ullDiff); + pData->bProcessed = false; bSkip = true; return TSubTaskBase::eSubResult_Continue; @@ -548,24 +556,25 @@ return eResult; else if(!fileDst.IsOpen()) { - // new stats - m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); - m_tSubTaskStats.IncreaseCurrentItemProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + unsigned long long ullDiff = pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize(); + m_tSubTaskStats.IncreaseProcessedSize(ullDiff); + m_tSubTaskStats.IncreaseCurrentItemProcessedSize(ullDiff); + pData->bProcessed = false; bSkip = true; return TSubTaskBase::eSubResult_Continue; } - - ullSeekTo = m_tProgressInfo.GetCurrentFileProcessedSize(); } if(pData->bOnlyCreate) { // we don't copy contents, but need to increase processed size - // new stats - m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); - m_tSubTaskStats.IncreaseCurrentItemProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + unsigned long long ullDiff = pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize(); + + m_tSubTaskStats.IncreaseProcessedSize(ullDiff); + m_tSubTaskStats.IncreaseCurrentItemProcessedSize(ullDiff); + return TSubTaskBase::eSubResult_Continue; } @@ -580,10 +589,11 @@ return eResult; else if(bSkip) { - // new stats - m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); - m_tSubTaskStats.IncreaseCurrentItemProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + unsigned long long ullDiff = pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize(); + m_tSubTaskStats.IncreaseProcessedSize(ullDiff); + m_tSubTaskStats.IncreaseCurrentItemProcessedSize(ullDiff); + pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } @@ -594,18 +604,29 @@ else if(bSkip) { // with either first or second seek we got 'skip' answer... - // new stats - m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); - m_tSubTaskStats.IncreaseCurrentItemProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + unsigned long long ullDiff = pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize(); + m_tSubTaskStats.IncreaseProcessedSize(ullDiff); + m_tSubTaskStats.IncreaseCurrentItemProcessedSize(ullDiff); + pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } - m_tProgressInfo.IncreaseCurrentFileProcessedSize(ullMove); - // new stats - m_tSubTaskStats.IncreaseProcessedSize(ullMove); - m_tSubTaskStats.IncreaseCurrentItemProcessedSize(ullMove); + // ullSeekTo (== m_tProgressInfo.GetCurrentFileProcessedSize()) is already a part of stats + // so the only correction that might need to be done is subtracting the difference + // between stored last file position (aka ullSeekTo) and the real position + // to which the file pos was set to. + m_tSubTaskStats.SetCurrentItemProcessedSize(ullMove); + if(ullMove < ullSeekTo) + { + unsigned long long ullDiff = ullSeekTo - ullMove; + + m_tProgressInfo.DecreaseCurrentFileProcessedSize(ullDiff); + // new stats + m_tSubTaskStats.IncreaseProcessedSize(ullMove); + m_tSubTaskStats.IncreaseCurrentItemProcessedSize(ullMove); + } } // if the destination file already exists - truncate it to the current file position Index: src/libchcore/TSubTaskCopyMove.h =================================================================== diff -u -r19925be73ffcadd9f345f10e03e55aadb3f0eeac -rd0bc3c187684f54894c7280a936d5507a5e49f35 --- src/libchcore/TSubTaskCopyMove.h (.../TSubTaskCopyMove.h) (revision 19925be73ffcadd9f345f10e03e55aadb3f0eeac) +++ src/libchcore/TSubTaskCopyMove.h (.../TSubTaskCopyMove.h) (revision d0bc3c187684f54894c7280a936d5507a5e49f35) @@ -61,6 +61,7 @@ void SetCurrentFileProcessedSize(unsigned long long ullSize); unsigned long long GetCurrentFileProcessedSize() const; void IncreaseCurrentFileProcessedSize(unsigned long long ullSizeToAdd); + void DecreaseCurrentFileProcessedSize(unsigned long long ullSizeToSubtract); void Store(const ISerializerRowDataPtr& spRowData) const; static void InitLoader(const IColumnsDefinitionPtr& spColumns); Index: src/libchcore/TSubTaskStatsInfo.cpp =================================================================== diff -u -r19925be73ffcadd9f345f10e03e55aadb3f0eeac -rd0bc3c187684f54894c7280a936d5507a5e49f35 --- src/libchcore/TSubTaskStatsInfo.cpp (.../TSubTaskStatsInfo.cpp) (revision 19925be73ffcadd9f345f10e03e55aadb3f0eeac) +++ src/libchcore/TSubTaskStatsInfo.cpp (.../TSubTaskStatsInfo.cpp) (revision d0bc3c187684f54894c7280a936d5507a5e49f35) @@ -61,7 +61,8 @@ m_ullCurrentItemProcessedSize(m_setModifications, 0), m_ullCurrentItemTotalSize(m_setModifications, 0), m_eSubOperationType(m_setModifications, eSubOperation_None), - m_tTimer(m_setModifications) + m_tTimer(m_setModifications), + m_bIsInitialized(m_setModifications, false) { } @@ -80,6 +81,7 @@ m_ullCurrentItemProcessedSize = 0; m_ullCurrentItemTotalSize = 0; m_eSubOperationType = eSubOperation_None; + m_bIsInitialized = false; } void TSubTaskStatsInfo::GetSnapshot(TSubTaskStatsSnapshotPtr& spStatsSnapshot) const @@ -137,7 +139,7 @@ { boost::unique_lock lock(m_lock); - m_tCountSpeed.Modify().AddSample(stProcessedCount - m_stProcessedCount, m_tTimer.Modify().Tick()); + m_tCountSpeed.Modify().AddSample(0/*stProcessedCount - m_stProcessedCount*/, m_tTimer.Modify().Tick()); m_stProcessedCount = stProcessedCount; @@ -167,11 +169,24 @@ THROW_CORE_EXCEPTION(eErr_InternalProblem); } +void TSubTaskStatsInfo::DecreaseProcessedSize(unsigned long long ullDecreaseBy) +{ + boost::unique_lock lock(m_lock); + m_ullProcessedSize.Modify() -= ullDecreaseBy; + + // we didn't process anything here - hence the 0-sized sample + m_tSizeSpeed.Modify().AddSample(0, m_tTimer.Modify().Tick()); + + _ASSERTE(m_ullProcessedSize <= m_ullTotalSize); + if(m_ullProcessedSize > m_ullTotalSize) + THROW_CORE_EXCEPTION(eErr_InternalProblem); +} + void TSubTaskStatsInfo::SetProcessedSize(unsigned long long ullProcessedSize) { boost::unique_lock lock(m_lock); - m_tSizeSpeed.Modify().AddSample(ullProcessedSize - m_ullProcessedSize, m_tTimer.Modify().Tick()); + m_tSizeSpeed.Modify().AddSample(0/*ullProcessedSize - m_ullProcessedSize*/, m_tTimer.Modify().Tick()); m_ullProcessedSize = ullProcessedSize; _ASSERTE(m_ullProcessedSize <= m_ullTotalSize); @@ -199,6 +214,16 @@ THROW_CORE_EXCEPTION(eErr_InternalProblem); } +void TSubTaskStatsInfo::DecreaseCurrentItemProcessedSize(unsigned long long ullDecreaseBy) +{ + boost::unique_lock lock(m_lock); + m_ullCurrentItemProcessedSize.Modify() -= ullDecreaseBy; + + _ASSERTE(m_ullCurrentItemProcessedSize <= m_ullCurrentItemTotalSize); + if(m_ullCurrentItemProcessedSize > m_ullCurrentItemTotalSize) + THROW_CORE_EXCEPTION(eErr_InternalProblem); +} + void TSubTaskStatsInfo::SetCurrentItemProcessedSize(unsigned long long ullProcessedSize) { boost::unique_lock lock(m_lock); @@ -258,6 +283,8 @@ if(m_bSubTaskIsRunning.IsModified()) *spRowData % TRowData(_T("is_running"), m_bSubTaskIsRunning); + if(m_bIsInitialized.IsModified()) + *spRowData % TRowData(_T("is_initialized"), m_bIsInitialized); if(m_ullTotalSize.IsModified()) *spRowData % TRowData(_T("total_size"), m_ullTotalSize); @@ -300,6 +327,7 @@ *spColumnDefs % _T("is_running") + % _T("is_initialized") % _T("total_size") % _T("processed_size") % _T("size_speed") @@ -319,6 +347,7 @@ boost::unique_lock lock(m_lock); spRowReader->GetValue(_T("is_running"), m_bSubTaskIsRunning.Modify()); + spRowReader->GetValue(_T("is_initialized"), m_bIsInitialized.Modify()); spRowReader->GetValue(_T("total_size"), m_ullTotalSize.Modify()); @@ -349,4 +378,39 @@ m_setModifications.reset(); } +void TSubTaskStatsInfo::Init(int iCurrentBufferIndex, size_t stTotalCount, size_t stProcessedCount, unsigned long long ullTotalSize, unsigned long long ullProcessedSize, const TString& strCurrentPath) +{ + boost::unique_lock lock(m_lock); + + if(m_bIsInitialized) + THROW_CORE_EXCEPTION(eErr_InvalidData); + + m_iCurrentBufferIndex = iCurrentBufferIndex; + + m_stTotalCount = stTotalCount; + m_stProcessedCount = stProcessedCount; + + _ASSERTE(m_stProcessedCount <= m_stTotalCount); + if(m_stProcessedCount > m_stTotalCount) + THROW_CORE_EXCEPTION(eErr_InternalProblem); + + m_ullTotalSize = ullTotalSize; + m_ullProcessedSize = ullProcessedSize; + _ASSERTE(m_ullProcessedSize <= m_ullTotalSize); + if(m_ullProcessedSize > m_ullTotalSize) + THROW_CORE_EXCEPTION(eErr_InternalProblem); + + m_strCurrentPath = strCurrentPath; + + m_bIsInitialized = true; +} + +bool TSubTaskStatsInfo::IsInitialized() const +{ + boost::shared_lock lock(m_lock); + bool bInitialized = m_bIsInitialized; + + return bInitialized; +} + END_CHCORE_NAMESPACE Index: src/libchcore/TSubTaskStatsInfo.h =================================================================== diff -u -r19925be73ffcadd9f345f10e03e55aadb3f0eeac -rd0bc3c187684f54894c7280a936d5507a5e49f35 --- src/libchcore/TSubTaskStatsInfo.h (.../TSubTaskStatsInfo.h) (revision 19925be73ffcadd9f345f10e03e55aadb3f0eeac) +++ src/libchcore/TSubTaskStatsInfo.h (.../TSubTaskStatsInfo.h) (revision d0bc3c187684f54894c7280a936d5507a5e49f35) @@ -63,8 +63,11 @@ public: TSubTaskStatsInfo(); + void Init(int iCurrentBufferIndex, size_t stTotalCount, size_t stProcessedCount, unsigned long long ullTotalSize, unsigned long long ullProcessedSize, const TString& strCurrentPath); void Clear(); + bool IsInitialized() const; + void GetSnapshot(TSubTaskStatsSnapshotPtr& spStatsSnapshot) const; void IncreaseProcessedCount(size_t stIncreaseBy); @@ -74,12 +77,14 @@ // size stats void IncreaseProcessedSize(unsigned long long ullIncreaseBy); + void DecreaseProcessedSize(unsigned long long ullDecreaseBy); void SetProcessedSize(unsigned long long ullProcessedSize); void SetTotalSize(unsigned long long ullTotalSize); // current item void IncreaseCurrentItemProcessedSize(unsigned long long ullIncreaseBy); + void DecreaseCurrentItemProcessedSize(unsigned long long ullDecreaseBy); void SetCurrentItemProcessedSize(unsigned long long ullProcessedSize); void SetCurrentItemTotalSize(unsigned long long ullTotalSize); @@ -128,6 +133,7 @@ eMod_CurrentBufferIndex, eMod_CurrentPath, eMod_SubOperationType, + eMod_IsInitialized, // last item eMod_Last @@ -157,6 +163,8 @@ TSharedModificationTracker m_eSubOperationType; + TSharedModificationTracker m_bIsInitialized; + #pragma warning(push) #pragma warning(disable: 4251) mutable boost::shared_mutex m_lock; Index: src/libchcore/TTask.cpp =================================================================== diff -u -r19925be73ffcadd9f345f10e03e55aadb3f0eeac -rd0bc3c187684f54894c7280a936d5507a5e49f35 --- src/libchcore/TTask.cpp (.../TTask.cpp) (revision 19925be73ffcadd9f345f10e03e55aadb3f0eeac) +++ src/libchcore/TTask.cpp (.../TTask.cpp) (revision d0bc3c187684f54894c7280a936d5507a5e49f35) @@ -153,6 +153,10 @@ m_tLocalStats.Load(spContainer); m_tSubTasksArray.Load(m_spSerializer); + + // ensure copy-based context entries are properly updated after loading + m_tSubTaskContext.SetDestinationPath(m_tBaseData.GetDestinationPath()); + m_tSubTaskContext.SetOperationType(m_tSubTasksArray.GetOperationType()); } } Index: src/libchcore/TTaskManager.cpp =================================================================== diff -u -r1f438ded9f2d8e972ed7c6840793b2faf8e3b9c8 -rd0bc3c187684f54894c7280a936d5507a5e49f35 --- src/libchcore/TTaskManager.cpp (.../TTaskManager.cpp) (revision 1f438ded9f2d8e972ed7c6840793b2faf8e3b9c8) +++ src/libchcore/TTaskManager.cpp (.../TTaskManager.cpp) (revision d0bc3c187684f54894c7280a936d5507a5e49f35) @@ -33,9 +33,11 @@ // TTaskManager members TTaskManager::TTaskManager(const ISerializerFactoryPtr& spSerializerFactory, const IFeedbackHandlerFactoryPtr& spFeedbackHandlerFactory, + const TSmartPath& pathLogDir, bool bForceRecreateSerializer) : m_spSerializerFactory(spSerializerFactory), - m_spFeedbackFactory(spFeedbackHandlerFactory) + m_spFeedbackFactory(spFeedbackHandlerFactory), + m_pathLogDir(pathLogDir) { if(!spFeedbackHandlerFactory || !spSerializerFactory) THROW_CORE_EXCEPTION(eErr_InvalidPointer); Index: src/libchcore/TTaskManager.h =================================================================== diff -u -r293e52b38d46653068006262172018a0f0d0a31c -rd0bc3c187684f54894c7280a936d5507a5e49f35 --- src/libchcore/TTaskManager.h (.../TTaskManager.h) (revision 293e52b38d46653068006262172018a0f0d0a31c) +++ src/libchcore/TTaskManager.h (.../TTaskManager.h) (revision d0bc3c187684f54894c7280a936d5507a5e49f35) @@ -40,6 +40,7 @@ public: TTaskManager(const ISerializerFactoryPtr& spSerializerFactory, const IFeedbackHandlerFactoryPtr& spFeedbackHandlerFactory, + const TSmartPath& pathLogDir, bool bForceRecreateSerializer = false); ~TTaskManager();