Index: src/libchcore/TSQLiteTaskSchema.cpp =================================================================== diff -u -N -r320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41 -r0b8ae6ab8b538881b651126bf8e6de9c9912a782 --- src/libchcore/TSQLiteTaskSchema.cpp (.../TSQLiteTaskSchema.cpp) (revision 320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41) +++ src/libchcore/TSQLiteTaskSchema.cpp (.../TSQLiteTaskSchema.cpp) (revision 0b8ae6ab8b538881b651126bf8e6de9c9912a782) @@ -69,6 +69,9 @@ tStatement.Prepare(_T("CREATE TABLE local_stats(id BIGINT UNIQUE, elapsed_time BIGINT NOT NULL)")); tStatement.Step(); + tStatement.Prepare(_T("CREATE TABLE subtasks(id BIGINT UNIQUE, type INT NOT NULL, is_current boolean NOT NULL, is_estimation boolean NOT NULL)")); + tStatement.Step(); + // and finally set the database version to current one tVersion.SetVersion(1); } Index: src/libchcore/TSubTaskArray.cpp =================================================================== diff -u -N -rc6d96d4152aab0785a5f850b5ed9eb4a3584fd91 -r0b8ae6ab8b538881b651126bf8e6de9c9912a782 --- src/libchcore/TSubTaskArray.cpp (.../TSubTaskArray.cpp) (revision c6d96d4152aab0785a5f850b5ed9eb4a3584fd91) +++ src/libchcore/TSubTaskArray.cpp (.../TSubTaskArray.cpp) (revision 0b8ae6ab8b538881b651126bf8e6de9c9912a782) @@ -30,11 +30,10 @@ #include "TSubTaskContext.h" #include "TTaskLocalStats.h" #include "TSubTaskFastMove.h" -#include "SerializationHelpers.h" -#include "TBinarySerializer.h" #include "TTaskStatsSnapshot.h" #include "TCoreException.h" #include "ErrorCodes.h" +#include BEGIN_CHCORE_NAMESPACE @@ -44,14 +43,16 @@ TSubTasksArray::TSubTasksArray() : m_pSubTaskContext(NULL), m_eOperationType(eOperation_None), - m_lSubOperationIndex(0) + m_lSubOperationIndex(0), + m_lLastStoredIndex(-1) { } TSubTasksArray::TSubTasksArray(const TOperationPlan& rOperationPlan, TSubTaskContext& rSubTaskContext) : m_pSubTaskContext(NULL), m_eOperationType(eOperation_None), - m_lSubOperationIndex(0) + m_lSubOperationIndex(0), + m_lLastStoredIndex(-1) { Init(rOperationPlan, rSubTaskContext); } @@ -63,7 +64,7 @@ void TSubTasksArray::Init(const TOperationPlan& rOperationPlan, TSubTaskContext& rSubTaskContext) { m_vSubTasks.clear(); - m_lSubOperationIndex = 0; + m_lSubOperationIndex.store(0, boost::memory_order_release); m_pSubTaskContext = &rSubTaskContext; m_eOperationType = rOperationPlan.GetOperationType(); @@ -99,7 +100,7 @@ void TSubTasksArray::ResetProgressAndStats() { - InterlockedExchange(&m_lSubOperationIndex, 0); + m_lSubOperationIndex.store(0, boost::memory_order_release); std::pair tupleRow; BOOST_FOREACH(tupleRow, m_vSubTasks) @@ -119,7 +120,7 @@ TSubTaskBase::ESubOperationResult eResult = TSubTaskBase::eSubResult_Continue; size_t stSize = m_vSubTasks.size(); - long lIndex = InterlockedCompareExchange(&m_lSubOperationIndex, 0, 0); + long lIndex = m_lSubOperationIndex.load(boost::memory_order_acquire); while(lIndex < stSize && eResult == TSubTaskBase::eSubResult_Continue) { @@ -135,7 +136,7 @@ eResult = spCurrentSubTask->Exec(); - lIndex = InterlockedIncrement(&m_lSubOperationIndex); + lIndex = m_lSubOperationIndex.fetch_add(1, boost::memory_order_release); } return eResult; @@ -152,7 +153,7 @@ // current task // ugly const_cast - const method, non-const interlocked intrinsic and we're really not modifying the member... - long lIndex = InterlockedCompareExchange(const_cast(&m_lSubOperationIndex), 0L, 0L); + long lIndex = m_lSubOperationIndex.load(boost::memory_order_acquire); rSnapshot.SetCurrentSubtaskIndex(lIndex); // progress @@ -173,4 +174,128 @@ return m_eOperationType; } +void TSubTasksArray::Store(const ISerializerPtr& spSerializer) const +{ + ISerializerContainerPtr spContainer = spSerializer->GetContainer(_T("subtasks")); + ISerializerRowDataPtr spRow; + + // base data + long lCurrentIndex = m_lSubOperationIndex.load(boost::memory_order_acquire); + bool bAdded = (m_lLastStoredIndex == -1); + + // subtasks are stored only once when added as they don't change (at least in context of their order and type) + if(bAdded) + { + for(size_t stSubOperationIndex = 0; stSubOperationIndex < m_vSubTasks.size(); ++stSubOperationIndex) + { + if(bAdded) + spRow = spContainer->AddRow(stSubOperationIndex); + + const std::pair& rCurrentSubTask = m_vSubTasks[stSubOperationIndex]; + + *spRow + % TRowData(_T("type"), rCurrentSubTask.first->GetSubOperationType()) + % TRowData(_T("is_current"), false) + % TRowData(_T("is_estimation"), rCurrentSubTask.second); + } + } + + // serialize current index + 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()) + { + spRow = spContainer->GetRow(lCurrentIndex); + *spRow % TRowData(_T("is_current"), true); + } + + // unmark the old "current" subtask + if(m_lLastStoredIndex != -1) + { + spRow = spContainer->GetRow(m_lLastStoredIndex); + *spRow % TRowData(_T("is_current"), false); + } + } + + m_lLastStoredIndex = lCurrentIndex; + + // store all the subtasks + for(size_t stSubOperationIndex = 0; stSubOperationIndex < m_vSubTasks.size(); ++stSubOperationIndex) + { + const std::pair& rCurrentSubTask = m_vSubTasks[stSubOperationIndex]; + rCurrentSubTask.first->Store(spSerializer); + } +} + +void TSubTasksArray::Load(const ISerializerPtr& spSerializer) +{ + if(!m_pSubTaskContext) + THROW_CORE_EXCEPTION(eErr_InvalidData); + + m_lLastStoredIndex = -1; + + ISerializerContainerPtr spContainer = spSerializer->GetContainer(_T("subtasks")); + ISerializerRowReaderPtr spRowReader = spContainer->GetRowReader(); + + IColumnsDefinitionPtr spColumns = spRowReader->GetColumnsDefinitions(); + if(spColumns->IsEmpty()) + *spColumns % _T("id") % _T("type") % _T("is_current") % _T("is_estimation"); + + while(spRowReader->Next()) + { + long lID = 0; + int iType = 0; + bool bIsCurrent = false; + bool bIsEstimation = false; + + spRowReader->GetValue(_T("id"), lID); + spRowReader->GetValue(_T("type"), iType); + spRowReader->GetValue(_T("is_current"), bIsCurrent); + spRowReader->GetValue(_T("is_estimation"), bIsEstimation); + + if(bIsCurrent) + { + m_lSubOperationIndex.store(lID, boost::memory_order_release); + m_lLastStoredIndex = lID; + } + + // create subtask, load it and put into the array + TSubTaskBasePtr spSubTask = CreateSubtask((ESubOperationType)iType, *m_pSubTaskContext); + spSubTask->Load(spSerializer); + + if(lID != m_vSubTasks.size()) + THROW_CORE_EXCEPTION(eErr_InvalidData); + + m_vSubTasks.push_back(std::make_pair(spSubTask, bIsEstimation)); + } + + if(m_lLastStoredIndex == -1) + { + m_lSubOperationIndex.store(boost::numeric_cast(m_vSubTasks.size()), boost::memory_order_release); + m_lLastStoredIndex = boost::numeric_cast(m_vSubTasks.size()); + } +} + +TSubTaskBasePtr TSubTasksArray::CreateSubtask(ESubOperationType eType, TSubTaskContext& rContext) +{ + switch(eType) + { + case eSubOperation_FastMove: + return boost::make_shared(boost::ref(rContext)); + + case eSubOperation_Scanning: + return boost::make_shared(boost::ref(rContext)); + + case eSubOperation_Copying: + return boost::make_shared(boost::ref(rContext)); + + case eSubOperation_Deleting: + return boost::make_shared(boost::ref(rContext)); + + default: + THROW_CORE_EXCEPTION(eErr_UnhandledCase); + } +} + END_CHCORE_NAMESPACE Index: src/libchcore/TSubTaskArray.h =================================================================== diff -u -N -rc6d96d4152aab0785a5f850b5ed9eb4a3584fd91 -r0b8ae6ab8b538881b651126bf8e6de9c9912a782 --- src/libchcore/TSubTaskArray.h (.../TSubTaskArray.h) (revision c6d96d4152aab0785a5f850b5ed9eb4a3584fd91) +++ src/libchcore/TSubTaskArray.h (.../TSubTaskArray.h) (revision 0b8ae6ab8b538881b651126bf8e6de9c9912a782) @@ -28,6 +28,7 @@ #include "TSubTaskBase.h" #include "TTaskLocalStats.h" #include "TSubTaskArrayStatsSnapshot.h" +#include BEGIN_CHCORE_NAMESPACE @@ -51,8 +52,8 @@ void ResetProgressAndStats(); // progress handling - void SerializeProgress(TReadBinarySerializer& rSerializer); - void SerializeProgress(TWriteBinarySerializer& rSerializer) const; + void Store(const ISerializerPtr& spSerializer) const; + void Load(const ISerializerPtr& spSerializer); TSubTaskBase::ESubOperationResult Execute(bool bRunOnlyEstimationSubTasks); @@ -61,18 +62,20 @@ TSubTasksArray& operator=(const TSubTasksArray& rSrc); void AddSubTask(const TSubTaskBasePtr& spOperation, bool bIsPartOfEstimation); + static TSubTaskBasePtr CreateSubtask(ESubOperationType eType, TSubTaskContext& rContext); private: TSubTaskContext* m_pSubTaskContext; EOperationType m_eOperationType; #pragma warning(push) #pragma warning(disable: 4251) - std::vector > m_vSubTasks; // pointer to the subtask object / part of the whole process / is this the part of estimation? + std::vector > m_vSubTasks; // pointer to the subtask object / is this the part of estimation? + + mutable boost::atomic m_lSubOperationIndex; // index of sub-operation from TOperationDescription + mutable long m_lLastStoredIndex; #pragma warning(pop) - volatile long m_lSubOperationIndex; // index of sub-operation from TOperationDescription - friend class TTaskProcessingGuard; }; Index: src/libchcore/TSubTaskBase.h =================================================================== diff -u -N -rb1e03eb232a784d6e2d40f67cbbbb33be0972228 -r0b8ae6ab8b538881b651126bf8e6de9c9912a782 --- src/libchcore/TSubTaskBase.h (.../TSubTaskBase.h) (revision b1e03eb232a784d6e2d40f67cbbbb33be0972228) +++ src/libchcore/TSubTaskBase.h (.../TSubTaskBase.h) (revision 0b8ae6ab8b538881b651126bf8e6de9c9912a782) @@ -27,7 +27,7 @@ #include "TPath.h" #include "ESubTaskTypes.h" #include "TSubTaskStatsInfo.h" -#include "TBinarySerializer.h" +#include "ISerializer.h" BEGIN_CHCORE_NAMESPACE @@ -43,9 +43,6 @@ public: virtual ~TSubTaskProgressInfo() {} - virtual void Serialize(TReadBinarySerializer& rSerializer) = 0; - virtual void Serialize(TWriteBinarySerializer& rSerializer) const = 0; - virtual void ResetProgress() = 0; }; @@ -70,6 +67,10 @@ virtual ESubOperationResult Exec() = 0; virtual ESubOperationType GetSubOperationType() const = 0; + // serialization + virtual void Store(const ISerializerPtr& spSerializer) const = 0; + virtual void Load(const ISerializerPtr& spSerializer) = 0; + // progress virtual TSubTaskProgressInfo& GetProgressInfo() = 0; Index: src/libchcore/TSubTaskCopyMove.cpp =================================================================== diff -u -N -ra5aa3c3cb78f3767641de2627d1a49a1dc35b429 -r0b8ae6ab8b538881b651126bf8e6de9c9912a782 --- src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision a5aa3c3cb78f3767641de2627d1a49a1dc35b429) +++ src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision 0b8ae6ab8b538881b651126bf8e6de9c9912a782) @@ -36,8 +36,6 @@ #include #include "TFileInfo.h" #include "TFileInfoArray.h" -#include "SerializationHelpers.h" -#include "TBinarySerializer.h" #include "TDataBuffer.h" #include "ErrorCodes.h" #include "TCoreException.h" @@ -60,6 +58,7 @@ { } +/* void TCopyMoveProgressInfo::Serialize(TReadBinarySerializer& rSerializer) { size_t stIndex = 0; @@ -87,6 +86,7 @@ Serializers::Serialize(rSerializer, stIndex); Serializers::Serialize(rSerializer, ullFilePos); } +*/ void TCopyMoveProgressInfo::ResetProgress() { @@ -1286,4 +1286,14 @@ return TSubTaskBase::eSubResult_Continue; } +void TSubTaskCopyMove::Store(const ISerializerPtr& spSerializer) const +{ + spSerializer; +} + +void TSubTaskCopyMove::Load(const ISerializerPtr& spSerializer) +{ + spSerializer; +} + END_CHCORE_NAMESPACE Index: src/libchcore/TSubTaskCopyMove.h =================================================================== diff -u -N -ra5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8 -r0b8ae6ab8b538881b651126bf8e6de9c9912a782 --- src/libchcore/TSubTaskCopyMove.h (.../TSubTaskCopyMove.h) (revision a5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8) +++ src/libchcore/TSubTaskCopyMove.h (.../TSubTaskCopyMove.h) (revision 0b8ae6ab8b538881b651126bf8e6de9c9912a782) @@ -50,9 +50,6 @@ TCopyMoveProgressInfo(); virtual ~TCopyMoveProgressInfo(); - virtual void Serialize(TReadBinarySerializer& rSerializer); - virtual void Serialize(TWriteBinarySerializer& rSerializer) const; - virtual void ResetProgress(); // file being processed @@ -82,6 +79,9 @@ virtual ESubOperationResult Exec(); virtual ESubOperationType GetSubOperationType() const { return eSubOperation_Copying; } + virtual void Store(const ISerializerPtr& spSerializer) const; + virtual void Load(const ISerializerPtr& spSerializer); + virtual TSubTaskProgressInfo& GetProgressInfo() { return m_tProgressInfo; } virtual void GetStatsSnapshot(TSubTaskStatsSnapshotPtr& rStats) const; Index: src/libchcore/TSubTaskDelete.cpp =================================================================== diff -u -N -ra5aa3c3cb78f3767641de2627d1a49a1dc35b429 -r0b8ae6ab8b538881b651126bf8e6de9c9912a782 --- src/libchcore/TSubTaskDelete.cpp (.../TSubTaskDelete.cpp) (revision a5aa3c3cb78f3767641de2627d1a49a1dc35b429) +++ src/libchcore/TSubTaskDelete.cpp (.../TSubTaskDelete.cpp) (revision 0b8ae6ab8b538881b651126bf8e6de9c9912a782) @@ -31,8 +31,6 @@ #include #include "TFileInfoArray.h" #include "TFileInfo.h" -#include "SerializationHelpers.h" -#include "TBinarySerializer.h" #include "TTaskLocalStats.h" #include "DataBuffer.h" #include "TCoreException.h" @@ -54,6 +52,7 @@ { } +/* void TDeleteProgressInfo::Serialize(TReadBinarySerializer& rSerializer) { boost::unique_lock lock(m_lock); @@ -65,6 +64,7 @@ boost::shared_lock lock(m_lock); Serializers::Serialize(rSerializer, m_stCurrentIndex); } +*/ void TDeleteProgressInfo::ResetProgress() { @@ -232,7 +232,16 @@ spStats->SetTotalCount(GetContext().GetFilesCache().GetSize()); spStats->SetTotalSize(0); } +} +void TSubTaskDelete::Store(const ISerializerPtr& spSerializer) const +{ + spSerializer; } +void TSubTaskDelete::Load(const ISerializerPtr& spSerializer) +{ + spSerializer; +} + END_CHCORE_NAMESPACE Index: src/libchcore/TSubTaskDelete.h =================================================================== diff -u -N -ra5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8 -r0b8ae6ab8b538881b651126bf8e6de9c9912a782 --- src/libchcore/TSubTaskDelete.h (.../TSubTaskDelete.h) (revision a5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8) +++ src/libchcore/TSubTaskDelete.h (.../TSubTaskDelete.h) (revision 0b8ae6ab8b538881b651126bf8e6de9c9912a782) @@ -42,9 +42,6 @@ TDeleteProgressInfo(); virtual ~TDeleteProgressInfo(); - virtual void Serialize(TReadBinarySerializer& rSerializer); - virtual void Serialize(TWriteBinarySerializer& rSerializer) const; - virtual void ResetProgress(); void SetCurrentIndex(size_t stIndex); @@ -70,6 +67,9 @@ virtual ESubOperationResult Exec(); virtual ESubOperationType GetSubOperationType() const { return eSubOperation_Deleting; } + virtual void Store(const ISerializerPtr& spSerializer) const; + virtual void Load(const ISerializerPtr& spSerializer); + virtual TSubTaskProgressInfo& GetProgressInfo() { return m_tProgressInfo; } virtual void GetStatsSnapshot(TSubTaskStatsSnapshotPtr& spStats) const; Index: src/libchcore/TSubTaskFastMove.cpp =================================================================== diff -u -N -rb193a95402f2bf4c456fb9d65d111caaf6994823 -r0b8ae6ab8b538881b651126bf8e6de9c9912a782 --- src/libchcore/TSubTaskFastMove.cpp (.../TSubTaskFastMove.cpp) (revision b193a95402f2bf4c456fb9d65d111caaf6994823) +++ src/libchcore/TSubTaskFastMove.cpp (.../TSubTaskFastMove.cpp) (revision 0b8ae6ab8b538881b651126bf8e6de9c9912a782) @@ -33,8 +33,6 @@ #include "..\libicpf\log.h" #include "TFileInfo.h" #include -#include "SerializationHelpers.h" -#include "TBinarySerializer.h" #include "DataBuffer.h" #include "TCoreException.h" #include "ErrorCodes.h" @@ -56,6 +54,7 @@ { } +/* void TFastMoveProgressInfo::Serialize(TReadBinarySerializer& rSerializer) { boost::unique_lock lock(m_lock); @@ -67,6 +66,7 @@ boost::shared_lock lock(m_lock); Serializers::Serialize(rSerializer, m_stCurrentIndex); } +*/ void TFastMoveProgressInfo::ResetProgress() { @@ -293,4 +293,14 @@ m_tSubTaskStats.GetSnapshot(spStats); } +void TSubTaskFastMove::Store(const ISerializerPtr& spSerializer) const +{ + spSerializer; +} + +void TSubTaskFastMove::Load(const ISerializerPtr& spSerializer) +{ + spSerializer; +} + END_CHCORE_NAMESPACE Index: src/libchcore/TSubTaskFastMove.h =================================================================== diff -u -N -ra5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8 -r0b8ae6ab8b538881b651126bf8e6de9c9912a782 --- src/libchcore/TSubTaskFastMove.h (.../TSubTaskFastMove.h) (revision a5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8) +++ src/libchcore/TSubTaskFastMove.h (.../TSubTaskFastMove.h) (revision 0b8ae6ab8b538881b651126bf8e6de9c9912a782) @@ -44,9 +44,6 @@ TFastMoveProgressInfo(); virtual ~TFastMoveProgressInfo(); - virtual void Serialize(TReadBinarySerializer& rSerializer); - virtual void Serialize(TWriteBinarySerializer& rSerializer) const; - virtual void ResetProgress(); void SetCurrentIndex(size_t stIndex); @@ -73,6 +70,9 @@ virtual ESubOperationResult Exec(); virtual ESubOperationType GetSubOperationType() const { return eSubOperation_Scanning; } + virtual void Store(const ISerializerPtr& spSerializer) const; + virtual void Load(const ISerializerPtr& spSerializer); + virtual TSubTaskProgressInfo& GetProgressInfo() { return m_tProgressInfo; } virtual void GetStatsSnapshot(TSubTaskStatsSnapshotPtr& rStats) const; Index: src/libchcore/TSubTaskScanDirectory.cpp =================================================================== diff -u -N -rb193a95402f2bf4c456fb9d65d111caaf6994823 -r0b8ae6ab8b538881b651126bf8e6de9c9912a782 --- src/libchcore/TSubTaskScanDirectory.cpp (.../TSubTaskScanDirectory.cpp) (revision b193a95402f2bf4c456fb9d65d111caaf6994823) +++ src/libchcore/TSubTaskScanDirectory.cpp (.../TSubTaskScanDirectory.cpp) (revision 0b8ae6ab8b538881b651126bf8e6de9c9912a782) @@ -33,8 +33,6 @@ #include "..\libicpf\log.h" #include "TFileInfoArray.h" #include "TFileInfo.h" -#include "SerializationHelpers.h" -#include "TBinarySerializer.h" #include "DataBuffer.h" #include "TCoreException.h" #include "ErrorCodes.h" @@ -56,6 +54,7 @@ { } +/* void TScanDirectoriesProgressInfo::Serialize(TReadBinarySerializer& rSerializer) { boost::unique_lock lock(m_lock); @@ -67,6 +66,7 @@ boost::shared_lock lock(m_lock); Serializers::Serialize(rSerializer, m_stCurrentIndex); } +*/ void TScanDirectoriesProgressInfo::ResetProgress() { @@ -322,4 +322,14 @@ return 0; } +void TSubTaskScanDirectories::Store(const ISerializerPtr& spSerializer) const +{ + spSerializer; +} + +void TSubTaskScanDirectories::Load(const ISerializerPtr& spSerializer) +{ + spSerializer; +} + END_CHCORE_NAMESPACE Index: src/libchcore/TSubTaskScanDirectory.h =================================================================== diff -u -N -rb193a95402f2bf4c456fb9d65d111caaf6994823 -r0b8ae6ab8b538881b651126bf8e6de9c9912a782 --- src/libchcore/TSubTaskScanDirectory.h (.../TSubTaskScanDirectory.h) (revision b193a95402f2bf4c456fb9d65d111caaf6994823) +++ src/libchcore/TSubTaskScanDirectory.h (.../TSubTaskScanDirectory.h) (revision 0b8ae6ab8b538881b651126bf8e6de9c9912a782) @@ -45,9 +45,6 @@ TScanDirectoriesProgressInfo(); virtual ~TScanDirectoriesProgressInfo(); - virtual void Serialize(TReadBinarySerializer& rSerializer); - virtual void Serialize(TWriteBinarySerializer& rSerializer) const; - virtual void ResetProgress(); void SetCurrentIndex(size_t stIndex); @@ -74,6 +71,9 @@ virtual ESubOperationResult Exec(); virtual ESubOperationType GetSubOperationType() const { return eSubOperation_Scanning; } + virtual void Store(const ISerializerPtr& spSerializer) const; + virtual void Load(const ISerializerPtr& spSerializer); + virtual TSubTaskProgressInfo& GetProgressInfo() { return m_tProgressInfo; } virtual void GetStatsSnapshot(TSubTaskStatsSnapshotPtr& spStats) const; Index: src/libchcore/TTask.cpp =================================================================== diff -u -N -r320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41 -r0b8ae6ab8b538881b651126bf8e6de9c9912a782 --- src/libchcore/TTask.cpp (.../TTask.cpp) (revision 320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41) +++ src/libchcore/TTask.cpp (.../TTask.cpp) (revision 0b8ae6ab8b538881b651126bf8e6de9c9912a782) @@ -151,6 +151,8 @@ spContainer = m_spSerializer->GetContainer(_T("local_stats")); m_tLocalStats.Load(spContainer); + + m_tSubTasksArray.Load(m_spSerializer); } } @@ -179,6 +181,8 @@ spContainer = m_spSerializer->GetContainer(_T("local_stats")); m_tLocalStats.Store(spContainer); + + m_tSubTasksArray.Store(m_spSerializer); } m_spSerializer->Flush();