Index: src/libchcore/TTask.cpp =================================================================== diff -u -N -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b -re96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3 --- src/libchcore/TTask.cpp (.../TTask.cpp) (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) +++ src/libchcore/TTask.cpp (.../TTask.cpp) (revision e96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3) @@ -40,628 +40,627 @@ #include #include "TTaskConfigBufferSizes.h" -BEGIN_CHCORE_NAMESPACE - -//////////////////////////////////////////////////////////////////////////// -// TTask members - -TTask::TTask(const ISerializerPtr& spSerializer, const IFeedbackHandlerPtr& spFeedbackHandler) : - m_log(), - m_spInternalFeedbackHandler(spFeedbackHandler), - m_spSrcPaths(new TBasePathDataContainer), - m_bForce(false), - m_bContinue(false), - m_tSubTaskContext(m_tConfiguration, m_spSrcPaths, m_afFilters, - m_cfgTracker, m_log, m_workerThread, - std::make_shared()), - m_tSubTasksArray(m_tSubTaskContext), - m_spSerializer(spSerializer) +namespace chcore { - if(!spFeedbackHandler || !spSerializer) - THROW_CORE_EXCEPTION(eErr_InvalidPointer); -} + //////////////////////////////////////////////////////////////////////////// + // TTask members -TTask::~TTask() -{ - KillThread(); -} + TTask::TTask(const ISerializerPtr& spSerializer, const IFeedbackHandlerPtr& spFeedbackHandler) : + m_log(), + m_spInternalFeedbackHandler(spFeedbackHandler), + m_spSrcPaths(new TBasePathDataContainer), + m_bForce(false), + m_bContinue(false), + m_tSubTaskContext(m_tConfiguration, m_spSrcPaths, m_afFilters, + m_cfgTracker, m_log, m_workerThread, + std::make_shared()), + m_tSubTasksArray(m_tSubTaskContext), + m_spSerializer(spSerializer) + { + if (!spFeedbackHandler || !spSerializer) + THROW_CORE_EXCEPTION(eErr_InvalidPointer); + } -void TTask::SetTaskDefinition(const TTaskDefinition& rTaskDefinition) -{ - m_tBaseData.SetDestinationPath(rTaskDefinition.GetDestinationPath()); - m_tConfiguration = rTaskDefinition.GetConfiguration(); - *m_spSrcPaths = rTaskDefinition.GetSourcePaths(); - m_afFilters = rTaskDefinition.GetFilters(); - m_tBaseData.SetTaskName(rTaskDefinition.GetTaskName()); + TTask::~TTask() + { + KillThread(); + } - m_tSubTasksArray.Init(rTaskDefinition.GetOperationPlan()); - m_tSubTaskContext.SetOperationType(m_tSubTasksArray.GetOperationType()); - m_tSubTaskContext.SetDestinationPath(m_tBaseData.GetDestinationPath()); -} + void TTask::SetTaskDefinition(const TTaskDefinition& rTaskDefinition) + { + m_tBaseData.SetDestinationPath(rTaskDefinition.GetDestinationPath()); + m_tConfiguration = rTaskDefinition.GetConfiguration(); + *m_spSrcPaths = rTaskDefinition.GetSourcePaths(); + m_afFilters = rTaskDefinition.GetFilters(); + m_tBaseData.SetTaskName(rTaskDefinition.GetTaskName()); -void TTask::OnRegisterTask() -{ -} + m_tSubTasksArray.Init(rTaskDefinition.GetOperationPlan()); + m_tSubTaskContext.SetOperationType(m_tSubTasksArray.GetOperationType()); + m_tSubTaskContext.SetDestinationPath(m_tBaseData.GetDestinationPath()); + } -void TTask::OnUnregisterTask() -{ -} + void TTask::OnRegisterTask() + { + } -void TTask::SetTaskState(ETaskCurrentState eTaskState) -{ - // NOTE: we could check some transition rules here - boost::unique_lock lock(m_lock); - m_tBaseData.SetCurrentState(eTaskState); -} + void TTask::OnUnregisterTask() + { + } -ETaskCurrentState TTask::GetTaskState() const -{ - boost::shared_lock lock(m_lock); - return m_tBaseData.GetCurrentState(); -} + void TTask::SetTaskState(ETaskCurrentState eTaskState) + { + // NOTE: we could check some transition rules here + boost::unique_lock lock(m_lock); + m_tBaseData.SetCurrentState(eTaskState); + } -void TTask::SetBufferSizes(const TBufferSizes& bsSizes) -{ - m_tConfiguration.DelayNotifications(); + ETaskCurrentState TTask::GetTaskState() const + { + boost::shared_lock lock(m_lock); + return m_tBaseData.GetCurrentState(); + } - SetTaskPropBufferSizes(m_tConfiguration, bsSizes); - m_tConfiguration.ResumeNotifications(); -} + void TTask::SetBufferSizes(const TBufferSizes& bsSizes) + { + m_tConfiguration.DelayNotifications(); -void TTask::GetBufferSizes(TBufferSizes& bsSizes) -{ - bsSizes = GetTaskPropBufferSizes(m_tConfiguration); -} + SetTaskPropBufferSizes(m_tConfiguration, bsSizes); + m_tConfiguration.ResumeNotifications(); + } -// thread -void TTask::SetPriority(int nPriority) -{ - SetTaskPropValue(m_tConfiguration, nPriority); -} + void TTask::GetBufferSizes(TBufferSizes& bsSizes) + { + bsSizes = GetTaskPropBufferSizes(m_tConfiguration); + } -void TTask::Load() -{ - using namespace chcore; + // thread + void TTask::SetPriority(int nPriority) + { + SetTaskPropValue(m_tConfiguration, nPriority); + } - bool bLogPathLoaded = false; - bool bLoadFailed = false; - const size_t stMaxSize = 1024; - wchar_t szErr[stMaxSize]; - - try + void TTask::Load() { - boost::unique_lock lock(m_lock); + using namespace chcore; - ISerializerContainerPtr spContainer = m_spSerializer->GetContainer(_T("task")); - m_tBaseData.Load(spContainer); + bool bLogPathLoaded = false; + bool bLoadFailed = false; + const size_t stMaxSize = 1024; + wchar_t szErr[stMaxSize]; - bLogPathLoaded = true; + try + { + boost::unique_lock lock(m_lock); - spContainer = m_spSerializer->GetContainer(_T("base_paths")); - m_spSrcPaths->Load(spContainer); + ISerializerContainerPtr spContainer = m_spSerializer->GetContainer(_T("task")); + m_tBaseData.Load(spContainer); - spContainer = m_spSerializer->GetContainer(_T("scanned_files")); - m_tSubTaskContext.GetFilesCache().Load(spContainer, m_spSrcPaths); + bLogPathLoaded = true; - spContainer = m_spSerializer->GetContainer(_T("task_config")); - m_tConfiguration.Load(spContainer); + spContainer = m_spSerializer->GetContainer(_T("base_paths")); + m_spSrcPaths->Load(spContainer); - spContainer = m_spSerializer->GetContainer(_T("filters")); - m_afFilters.Load(spContainer); + spContainer = m_spSerializer->GetContainer(_T("scanned_files")); + m_tSubTaskContext.GetFilesCache().Load(spContainer, m_spSrcPaths); - spContainer = m_spSerializer->GetContainer(_T("local_stats")); - m_tLocalStats.Load(spContainer); + spContainer = m_spSerializer->GetContainer(_T("task_config")); + m_tConfiguration.Load(spContainer); - spContainer = m_spSerializer->GetContainer(_T("feedback")); - m_spInternalFeedbackHandler->Load(spContainer); + spContainer = m_spSerializer->GetContainer(_T("filters")); + m_afFilters.Load(spContainer); - m_tSubTasksArray.Load(m_spSerializer); + spContainer = m_spSerializer->GetContainer(_T("local_stats")); + m_tLocalStats.Load(spContainer); - // ensure copy-based context entries are properly updated after loading - m_tSubTaskContext.SetDestinationPath(m_tBaseData.GetDestinationPath()); - m_tSubTaskContext.SetOperationType(m_tSubTasksArray.GetOperationType()); - } - catch(const TBaseException& e) - { - SetTaskState(eTaskState_LoadError); - bLoadFailed = true; + spContainer = m_spSerializer->GetContainer(_T("feedback")); + m_spInternalFeedbackHandler->Load(spContainer); - _tcscpy_s(szErr, stMaxSize, _T("Task load error: ")); - size_t stLen = _tcslen(szErr); + m_tSubTasksArray.Load(m_spSerializer); - e.GetDetailedErrorInfo(szErr + stLen, stMaxSize - stLen); - } - catch(const std::exception& e) - { - SetTaskState(eTaskState_LoadError); - bLoadFailed = true; - _snwprintf_s(szErr, stMaxSize, _TRUNCATE, _T("Task load error. %hs"), e.what()); - } + // ensure copy-based context entries are properly updated after loading + m_tSubTaskContext.SetDestinationPath(m_tBaseData.GetDestinationPath()); + m_tSubTaskContext.SetOperationType(m_tSubTasksArray.GetOperationType()); + } + catch (const TBaseException& e) + { + SetTaskState(eTaskState_LoadError); + bLoadFailed = true; - if(bLoadFailed) - { - try + _tcscpy_s(szErr, stMaxSize, _T("Task load error: ")); + size_t stLen = _tcslen(szErr); + + e.GetDetailedErrorInfo(szErr + stLen, stMaxSize - stLen); + } + catch (const std::exception& e) { - if(bLogPathLoaded) - GetLog().loge(szErr); + SetTaskState(eTaskState_LoadError); + bLoadFailed = true; + _snwprintf_s(szErr, stMaxSize, _TRUNCATE, _T("Task load error. %hs"), e.what()); } - catch(const std::exception&) + + if (bLoadFailed) { + try + { + if (bLogPathLoaded) + GetLog().loge(szErr); + } + catch (const std::exception&) + { + } } } -} -void TTask::Store() -{ - if(GetTaskState() == eTaskState_LoadError) + void TTask::Store() { - DBTRACE0(_T("Task::Store() - not storing task as it was not loaded correctly\n")); - return; - } + if (GetTaskState() == eTaskState_LoadError) + { + DBTRACE0(_T("Task::Store() - not storing task as it was not loaded correctly\n")); + return; + } - TSimpleTimer timer(true); - DBTRACE0(_T("###### Task::Store() - starting\n")); + TSimpleTimer timer(true); + DBTRACE0(_T("###### Task::Store() - starting\n")); - using namespace chcore; + using namespace chcore; - { - boost::shared_lock lock(m_lock); + { + boost::shared_lock lock(m_lock); - ISerializerContainerPtr spContainer = m_spSerializer->GetContainer(_T("task")); - m_tBaseData.Store(spContainer); + ISerializerContainerPtr spContainer = m_spSerializer->GetContainer(_T("task")); + m_tBaseData.Store(spContainer); - // base paths - spContainer = m_spSerializer->GetContainer(_T("base_paths")); - m_spSrcPaths->Store(spContainer); + // base paths + spContainer = m_spSerializer->GetContainer(_T("base_paths")); + m_spSrcPaths->Store(spContainer); - spContainer = m_spSerializer->GetContainer(_T("scanned_files")); - m_tSubTaskContext.GetFilesCache().Store(spContainer); + spContainer = m_spSerializer->GetContainer(_T("scanned_files")); + m_tSubTaskContext.GetFilesCache().Store(spContainer); - spContainer = m_spSerializer->GetContainer(_T("task_config")); - m_tConfiguration.Store(spContainer); + spContainer = m_spSerializer->GetContainer(_T("task_config")); + m_tConfiguration.Store(spContainer); - spContainer = m_spSerializer->GetContainer(_T("filters")); - m_afFilters.Store(spContainer); + spContainer = m_spSerializer->GetContainer(_T("filters")); + m_afFilters.Store(spContainer); - spContainer = m_spSerializer->GetContainer(_T("local_stats")); - m_tLocalStats.Store(spContainer); + spContainer = m_spSerializer->GetContainer(_T("local_stats")); + m_tLocalStats.Store(spContainer); - spContainer = m_spSerializer->GetContainer(_T("feedback")); - m_spInternalFeedbackHandler->Store(spContainer); + spContainer = m_spSerializer->GetContainer(_T("feedback")); + m_spInternalFeedbackHandler->Store(spContainer); - m_tSubTasksArray.Store(m_spSerializer); - } + m_tSubTasksArray.Store(m_spSerializer); + } - unsigned long long ullGatherTime = timer.Checkpoint(); ullGatherTime; + unsigned long long ullGatherTime = timer.Checkpoint(); ullGatherTime; - m_spSerializer->Flush(); + m_spSerializer->Flush(); - unsigned long long ullFlushTime = timer.Stop(); ullFlushTime; - DBTRACE2(_T("###### Task::Store() - finished - gather: %I64u ms, flush: %I64u ms\n"), ullGatherTime, ullFlushTime); -} + unsigned long long ullFlushTime = timer.Stop(); ullFlushTime; + DBTRACE2(_T("###### Task::Store() - finished - gather: %I64u ms, flush: %I64u ms\n"), ullGatherTime, ullFlushTime); + } -void TTask::KillThread() -{ - m_workerThread.StopThread(); -} + void TTask::KillThread() + { + m_workerThread.StopThread(); + } -void TTask::BeginProcessing() -{ - GetLog().logi(_T("Requested task to begin processing")); + void TTask::BeginProcessing() + { + GetLog().logi(_T("Requested task to begin processing")); - boost::unique_lock lock(m_lock); - if(m_tBaseData.GetCurrentState() != eTaskState_LoadError) - m_workerThread.StartThread(DelegateThreadProc, this, GetTaskPropValue(m_tConfiguration)); -} + boost::unique_lock lock(m_lock); + if (m_tBaseData.GetCurrentState() != eTaskState_LoadError) + m_workerThread.StartThread(DelegateThreadProc, this, GetTaskPropValue(m_tConfiguration)); + } -void TTask::ResumeProcessing() -{ - // the same as retry but less demanding - if(GetTaskState() == eTaskState_Paused) + void TTask::ResumeProcessing() { - GetLog().logi(_T("Requested task resume")); - SetTaskState(eTaskState_Processing); - BeginProcessing(); + // the same as retry but less demanding + if (GetTaskState() == eTaskState_Paused) + { + GetLog().logi(_T("Requested task resume")); + SetTaskState(eTaskState_Processing); + BeginProcessing(); + } } -} -bool TTask::RetryProcessing() -{ - // retry used to auto-resume, after loading - switch(GetTaskState()) + bool TTask::RetryProcessing() { - case eTaskState_Paused: - case eTaskState_Finished: - case eTaskState_Cancelled: - case eTaskState_LoadError: - return false; + // retry used to auto-resume, after loading + switch (GetTaskState()) + { + case eTaskState_Paused: + case eTaskState_Finished: + case eTaskState_Cancelled: + case eTaskState_LoadError: + return false; - default: - BeginProcessing(); - return true; + default: + BeginProcessing(); + return true; + } } -} -void TTask::RestartProcessing() -{ - GetLog().logi(_T("Requested task restart")); - KillThread(); + void TTask::RestartProcessing() + { + GetLog().logi(_T("Requested task restart")); + KillThread(); - SetTaskState(eTaskState_None); + SetTaskState(eTaskState_None); - m_spInternalFeedbackHandler->RestoreDefaults(); - m_tSubTasksArray.ResetProgressAndStats(); - m_tLocalStats.Clear(); + m_spInternalFeedbackHandler->RestoreDefaults(); + m_tSubTasksArray.ResetProgressAndStats(); + m_tLocalStats.Clear(); - BeginProcessing(); -} + BeginProcessing(); + } -void TTask::PauseProcessing() -{ - if(GetTaskState() != eTaskState_Finished && GetTaskState() != eTaskState_Cancelled) + void TTask::PauseProcessing() { - GetLog().logi(_T("Requested task pause")); - KillThread(); - SetTaskState(eTaskState_Paused); + if (GetTaskState() != eTaskState_Finished && GetTaskState() != eTaskState_Cancelled) + { + GetLog().logi(_T("Requested task pause")); + KillThread(); + SetTaskState(eTaskState_Paused); + } } -} -void TTask::CancelProcessing() -{ - // change to ST_CANCELLED - if(GetTaskState() != eTaskState_Finished) + void TTask::CancelProcessing() { - GetLog().logi(_T("Requested task cancel")); - KillThread(); - SetTaskState(eTaskState_Cancelled); + // change to ST_CANCELLED + if (GetTaskState() != eTaskState_Finished) + { + GetLog().logi(_T("Requested task cancel")); + KillThread(); + SetTaskState(eTaskState_Cancelled); + } } -} -void TTask::GetStatsSnapshot(TTaskStatsSnapshotPtr& spSnapshot) -{ - if(!spSnapshot) - THROW_CORE_EXCEPTION(eErr_InvalidArgument); + void TTask::GetStatsSnapshot(TTaskStatsSnapshotPtr& spSnapshot) + { + if (!spSnapshot) + THROW_CORE_EXCEPTION(eErr_InvalidArgument); - spSnapshot->Clear(); + spSnapshot->Clear(); - boost::shared_lock lock(m_lock); - m_tSubTasksArray.GetStatsSnapshot(spSnapshot->GetSubTasksStats()); + boost::shared_lock lock(m_lock); + m_tSubTasksArray.GetStatsSnapshot(spSnapshot->GetSubTasksStats()); - m_tLocalStats.GetSnapshot(spSnapshot); + m_tLocalStats.GetSnapshot(spSnapshot); - spSnapshot->SetTaskName(m_tBaseData.GetTaskName()); - spSnapshot->SetThreadPriority(GetTaskPropValue(m_tConfiguration)); - spSnapshot->SetDestinationPath(m_tBaseData.GetDestinationPath().ToString()); - spSnapshot->SetFilters(m_afFilters); - spSnapshot->SetTaskState(m_tBaseData.GetCurrentState()); - spSnapshot->SetOperationType(m_tSubTasksArray.GetOperationType()); + spSnapshot->SetTaskName(m_tBaseData.GetTaskName()); + spSnapshot->SetThreadPriority(GetTaskPropValue(m_tConfiguration)); + spSnapshot->SetDestinationPath(m_tBaseData.GetDestinationPath().ToString()); + spSnapshot->SetFilters(m_afFilters); + spSnapshot->SetTaskState(m_tBaseData.GetCurrentState()); + spSnapshot->SetOperationType(m_tSubTasksArray.GetOperationType()); - spSnapshot->SetIgnoreDirectories(GetTaskPropValue(m_tConfiguration)); - spSnapshot->SetCreateEmptyFiles(GetTaskPropValue(m_tConfiguration)); - spSnapshot->SetBufferCount(GetTaskPropValue(m_tConfiguration)); + spSnapshot->SetIgnoreDirectories(GetTaskPropValue(m_tConfiguration)); + spSnapshot->SetCreateEmptyFiles(GetTaskPropValue(m_tConfiguration)); + spSnapshot->SetBufferCount(GetTaskPropValue(m_tConfiguration)); - TSubTaskStatsSnapshotPtr spCurrentSubTask = spSnapshot->GetSubTasksStats().GetCurrentSubTaskSnapshot(); + TSubTaskStatsSnapshotPtr spCurrentSubTask = spSnapshot->GetSubTasksStats().GetCurrentSubTaskSnapshot(); - int iCurrentBufferIndex = spCurrentSubTask ? spCurrentSubTask->GetCurrentBufferIndex() : TBufferSizes::eBuffer_Default; - switch(iCurrentBufferIndex) + int iCurrentBufferIndex = spCurrentSubTask ? spCurrentSubTask->GetCurrentBufferIndex() : TBufferSizes::eBuffer_Default; + switch (iCurrentBufferIndex) + { + case TBufferSizes::eBuffer_Default: + spSnapshot->SetCurrentBufferSize(GetTaskPropValue(m_tConfiguration)); + break; + case TBufferSizes::eBuffer_OneDisk: + spSnapshot->SetCurrentBufferSize(GetTaskPropValue(m_tConfiguration)); + break; + case TBufferSizes::eBuffer_TwoDisks: + spSnapshot->SetCurrentBufferSize(GetTaskPropValue(m_tConfiguration)); + break; + case TBufferSizes::eBuffer_CD: + spSnapshot->SetCurrentBufferSize(GetTaskPropValue(m_tConfiguration)); + break; + case TBufferSizes::eBuffer_LAN: + spSnapshot->SetCurrentBufferSize(GetTaskPropValue(m_tConfiguration)); + break; + default: + THROW_CORE_EXCEPTION(eErr_UnhandledCase); + //BOOST_ASSERT(false); // assertions are dangerous here, because we're inside critical section + // (and there could be conflict with Get(Mini)Snapshot called OnTimer in several places. + } + } + + bool TTask::CanBegin() { - case TBufferSizes::eBuffer_Default: - spSnapshot->SetCurrentBufferSize(GetTaskPropValue(m_tConfiguration)); - break; - case TBufferSizes::eBuffer_OneDisk: - spSnapshot->SetCurrentBufferSize(GetTaskPropValue(m_tConfiguration)); - break; - case TBufferSizes::eBuffer_TwoDisks: - spSnapshot->SetCurrentBufferSize(GetTaskPropValue(m_tConfiguration)); - break; - case TBufferSizes::eBuffer_CD: - spSnapshot->SetCurrentBufferSize(GetTaskPropValue(m_tConfiguration)); - break; - case TBufferSizes::eBuffer_LAN: - spSnapshot->SetCurrentBufferSize(GetTaskPropValue(m_tConfiguration)); - break; - default: - THROW_CORE_EXCEPTION(eErr_UnhandledCase); - //BOOST_ASSERT(false); // assertions are dangerous here, because we're inside critical section - // (and there could be conflict with Get(Mini)Snapshot called OnTimer in several places. + bool bRet = true; + boost::unique_lock lock(m_lock); + + if (GetContinueFlagNL() || GetForceFlagNL()) + { + SetForceFlagNL(false); + SetContinueFlagNL(false); + } + else + bRet = false; + + return bRet; } -} -bool TTask::CanBegin() -{ - bool bRet=true; - boost::unique_lock lock(m_lock); + void TTask::SetForceFlag(bool bFlag) + { + boost::unique_lock lock(m_lock); + m_bForce = bFlag; + } - if(GetContinueFlagNL() || GetForceFlagNL()) + bool TTask::GetForceFlag() { - SetForceFlagNL(false); - SetContinueFlagNL(false); + boost::shared_lock lock(m_lock); + return m_bForce; } - else - bRet = false; - return bRet; -} + void TTask::SetContinueFlag(bool bFlag) + { + boost::unique_lock lock(m_lock); + m_bContinue = bFlag; + } -void TTask::SetForceFlag(bool bFlag) -{ - boost::unique_lock lock(m_lock); - m_bForce=bFlag; -} + bool TTask::GetContinueFlag() + { + boost::shared_lock lock(m_lock); + return m_bContinue; + } -bool TTask::GetForceFlag() -{ - boost::shared_lock lock(m_lock); - return m_bForce; -} + ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -void TTask::SetContinueFlag(bool bFlag) -{ - boost::unique_lock lock(m_lock); - m_bContinue=bFlag; -} + void TTask::SetForceFlagNL(bool bFlag) + { + m_bForce = bFlag; + } -bool TTask::GetContinueFlag() -{ - boost::shared_lock lock(m_lock); - return m_bContinue; -} + bool TTask::GetForceFlagNL() + { + return m_bForce; + } -///////////////////////////////////////////////////////////////////////////////////////////////////////////// + void TTask::SetContinueFlagNL(bool bFlag) + { + m_bContinue = bFlag; + } -void TTask::SetForceFlagNL(bool bFlag) -{ - m_bForce=bFlag; -} + bool TTask::GetContinueFlagNL() + { + return m_bContinue; + } -bool TTask::GetForceFlagNL() -{ - return m_bForce; -} + TSubTaskBase::ESubOperationResult TTask::CheckForWaitState() + { + // limiting operation count + SetTaskState(eTaskState_Waiting); + bool bContinue = false; + while (!bContinue) + { + if (CanBegin()) + { + SetTaskState(eTaskState_Processing); + bContinue = true; -void TTask::SetContinueFlagNL(bool bFlag) -{ - m_bContinue=bFlag; -} + m_log.logi(_T("Finished waiting for begin permission")); -bool TTask::GetContinueFlagNL() -{ - return m_bContinue; -} + // return; // skips sleep and kill flag checking + } + else + Sleep(50); // not to make it too hard for processor -TSubTaskBase::ESubOperationResult TTask::CheckForWaitState() -{ - // limiting operation count - SetTaskState(eTaskState_Waiting); - bool bContinue = false; - while(!bContinue) + if (m_workerThread.KillRequested()) + { + // log + m_log.logi(_T("Kill request while waiting for begin permission (wait state)")); + return TSubTaskBase::eSubResult_KillRequest; + } + } + + return TSubTaskBase::eSubResult_Continue; + } + + DWORD WINAPI TTask::DelegateThreadProc(LPVOID pParam) { - if(CanBegin()) - { - SetTaskState(eTaskState_Processing); - bContinue = true; + BOOST_ASSERT(pParam); + if (!pParam) + return 1; - m_log.logi(_T("Finished waiting for begin permission")); + TTask* pTask = (TTask*)pParam; + return pTask->ThrdProc(); + } - // return; // skips sleep and kill flag checking - } - else - Sleep(50); // not to make it too hard for processor + DWORD TTask::ThrdProc() + { + // start tracking time for this thread + TScopedRunningTimeTracker tProcessingGuard(m_tLocalStats); + TFeedbackHandlerWrapperPtr spFeedbackHandler(boost::make_shared(m_spInternalFeedbackHandler, tProcessingGuard)); - if(m_workerThread.KillRequested()) + try { - // log - m_log.logi(_T("Kill request while waiting for begin permission (wait state)")); - return TSubTaskBase::eSubResult_KillRequest; - } - } + TSubTaskBase::ESubOperationResult eResult = TSubTaskBase::eSubResult_Continue; - return TSubTaskBase::eSubResult_Continue; -} + // initialize log file + m_log.init(m_tBaseData.GetLogPath().ToString(), 262144, icpf::log_file::level_debug, false, false); -DWORD WINAPI TTask::DelegateThreadProc(LPVOID pParam) -{ - BOOST_ASSERT(pParam); - if(!pParam) - return 1; + // start operation + OnBeginOperation(); - TTask* pTask = (TTask*)pParam; - return pTask->ThrdProc(); -} + // enable configuration changes tracking + m_tConfiguration.ConnectToNotifier(TTaskConfigTracker::NotificationProc, &m_cfgTracker); + m_tConfiguration.ConnectToNotifier(TTask::OnCfgOptionChanged, this); -DWORD TTask::ThrdProc() -{ - // start tracking time for this thread - TScopedRunningTimeTracker tProcessingGuard(m_tLocalStats); - TFeedbackHandlerWrapperPtr spFeedbackHandler(boost::make_shared(m_spInternalFeedbackHandler, tProcessingGuard)); + // set thread options + HANDLE hThread = GetCurrentThread(); + ::SetThreadPriorityBoost(hThread, GetTaskPropValue(m_tConfiguration)); - try - { - TSubTaskBase::ESubOperationResult eResult = TSubTaskBase::eSubResult_Continue; + // determine when to scan directories + bool bReadTasksSize = GetTaskPropValue(m_tConfiguration); - // initialize log file - m_log.init(m_tBaseData.GetLogPath().ToString(), 262144, icpf::log_file::level_debug, false, false); + // prepare context for subtasks + if (bReadTasksSize) + eResult = m_tSubTasksArray.Execute(spFeedbackHandler, true); + if (eResult == TSubTaskBase::eSubResult_Continue) + { + TScopedRunningTimeTrackerPause scopedPause(tProcessingGuard); - // start operation - OnBeginOperation(); + eResult = CheckForWaitState(); // operation limiting + } + if (eResult == TSubTaskBase::eSubResult_Continue) + eResult = m_tSubTasksArray.Execute(spFeedbackHandler, false); - // enable configuration changes tracking - m_tConfiguration.ConnectToNotifier(TTaskConfigTracker::NotificationProc, &m_cfgTracker); - m_tConfiguration.ConnectToNotifier(TTask::OnCfgOptionChanged, this); + // change status to finished + if (eResult == TSubTaskBase::eSubResult_Continue) + SetTaskState(eTaskState_Finished); - // set thread options - HANDLE hThread = GetCurrentThread(); - ::SetThreadPriorityBoost(hThread, GetTaskPropValue(m_tConfiguration)); + // finishing processing + // change task status + switch (eResult) + { + case TSubTaskBase::eSubResult_Error: + spFeedbackHandler->OperationError(); + SetTaskState(eTaskState_Error); + break; - // determine when to scan directories - bool bReadTasksSize = GetTaskPropValue(m_tConfiguration); + case TSubTaskBase::eSubResult_CancelRequest: + SetTaskState(eTaskState_Cancelled); + break; - // prepare context for subtasks - if(bReadTasksSize) - eResult = m_tSubTasksArray.Execute(spFeedbackHandler, true); - if(eResult == TSubTaskBase::eSubResult_Continue) - { - TScopedRunningTimeTrackerPause scopedPause(tProcessingGuard); + case TSubTaskBase::eSubResult_PauseRequest: + SetTaskState(eTaskState_Paused); + break; - eResult = CheckForWaitState(); // operation limiting - } - if(eResult == TSubTaskBase::eSubResult_Continue) - eResult = m_tSubTasksArray.Execute(spFeedbackHandler, false); + case TSubTaskBase::eSubResult_KillRequest: + // the only operation + if (GetTaskState() == eTaskState_Waiting) + SetTaskState(eTaskState_Processing); + break; - // change status to finished - if(eResult == TSubTaskBase::eSubResult_Continue) - SetTaskState(eTaskState_Finished); + case TSubTaskBase::eSubResult_Continue: + spFeedbackHandler->OperationFinished(); + SetTaskState(eTaskState_Finished); + break; - // finishing processing - // change task status - switch(eResult) - { - case TSubTaskBase::eSubResult_Error: - spFeedbackHandler->OperationError(); - SetTaskState(eTaskState_Error); - break; + default: + BOOST_ASSERT(false); + THROW_CORE_EXCEPTION(eErr_UnhandledCase); + } - case TSubTaskBase::eSubResult_CancelRequest: - SetTaskState(eTaskState_Cancelled); - break; + // if the files cache is not completely read - clean it up + if (!m_tSubTaskContext.GetFilesCache().IsComplete()) + m_tSubTaskContext.GetFilesCache().Clear(); // scanning for files did not finish processing, so the content of the files cache are useless - case TSubTaskBase::eSubResult_PauseRequest: - SetTaskState(eTaskState_Paused); - break; + // save progress before killed + Store(); - case TSubTaskBase::eSubResult_KillRequest: - // the only operation - if(GetTaskState() == eTaskState_Waiting) - SetTaskState(eTaskState_Processing); - break; + // reset flags + SetContinueFlag(false); + SetForceFlag(false); - case TSubTaskBase::eSubResult_Continue: - spFeedbackHandler->OperationFinished(); - SetTaskState(eTaskState_Finished); - break; + m_tConfiguration.DisconnectFromNotifier(TTaskConfigTracker::NotificationProc); + m_tConfiguration.DisconnectFromNotifier(TTask::OnCfgOptionChanged); - default: - BOOST_ASSERT(false); - THROW_CORE_EXCEPTION(eErr_UnhandledCase); + // and the real end + OnEndOperation(); + + return 0; } + catch (...) + { + } - // if the files cache is not completely read - clean it up - if(!m_tSubTaskContext.GetFilesCache().IsComplete()) - m_tSubTaskContext.GetFilesCache().Clear(); // scanning for files did not finish processing, so the content of the files cache are useless + m_tConfiguration.DisconnectFromNotifier(TTaskConfigTracker::NotificationProc); + m_tConfiguration.DisconnectFromNotifier(TTask::OnCfgOptionChanged); - // save progress before killed - Store(); + // log + m_log.loge(_T("Caught exception in ThrdProc")); - // reset flags + // let others know some error happened + spFeedbackHandler->OperationError(); + SetTaskState(eTaskState_Error); + SetContinueFlag(false); SetForceFlag(false); - m_tConfiguration.DisconnectFromNotifier(TTaskConfigTracker::NotificationProc); - m_tConfiguration.DisconnectFromNotifier(TTask::OnCfgOptionChanged); - - // and the real end OnEndOperation(); - return 0; + return 1; } - catch(...) + + void TTask::OnBeginOperation() { + CTime tm = CTime::GetCurrentTime(); + + TString strFormat = _T("\r\n# COPYING THREAD STARTED #\r\nBegan processing data (dd:mm:yyyy) %day.%month.%year at %hour:%minute.%second"); + strFormat.Replace(_t("%year"), boost::lexical_cast(tm.GetYear()).c_str()); + strFormat.Replace(_t("%month"), boost::lexical_cast(tm.GetMonth()).c_str()); + strFormat.Replace(_t("%day"), boost::lexical_cast(tm.GetDay()).c_str()); + strFormat.Replace(_t("%hour"), boost::lexical_cast(tm.GetHour()).c_str()); + strFormat.Replace(_t("%minute"), boost::lexical_cast(tm.GetMinute()).c_str()); + strFormat.Replace(_t("%second"), boost::lexical_cast(tm.GetSecond()).c_str()); + m_log.logi(strFormat.c_str()); } - m_tConfiguration.DisconnectFromNotifier(TTaskConfigTracker::NotificationProc); - m_tConfiguration.DisconnectFromNotifier(TTask::OnCfgOptionChanged); + void TTask::OnEndOperation() + { + CTime tm = CTime::GetCurrentTime(); - // log - m_log.loge(_T("Caught exception in ThrdProc")); + TString strFormat = _T("Finished processing data (dd:mm:yyyy) %day.%month.%year at %hour:%minute.%second"); + strFormat.Replace(_t("%year"), boost::lexical_cast(tm.GetYear()).c_str()); + strFormat.Replace(_t("%month"), boost::lexical_cast(tm.GetMonth()).c_str()); + strFormat.Replace(_t("%day"), boost::lexical_cast(tm.GetDay()).c_str()); + strFormat.Replace(_t("%hour"), boost::lexical_cast(tm.GetHour()).c_str()); + strFormat.Replace(_t("%minute"), boost::lexical_cast(tm.GetMinute()).c_str()); + strFormat.Replace(_t("%second"), boost::lexical_cast(tm.GetSecond()).c_str()); + m_log.logi(strFormat.c_str()); + } - // let others know some error happened - spFeedbackHandler->OperationError(); - SetTaskState(eTaskState_Error); + void TTask::RequestStopThread() + { + m_workerThread.SignalThreadToStop(); + } - SetContinueFlag(false); - SetForceFlag(false); + void TTask::OnCfgOptionChanged(const TStringSet& rsetChanges, void* pParam) + { + TTask* pTask = (TTask*)pParam; + if (!pTask) + THROW_CORE_EXCEPTION(eErr_InvalidArgument); - OnEndOperation(); + if (rsetChanges.HasValue(TaskPropData::GetPropertyName())) + { + pTask->m_workerThread.ChangePriority(GetTaskPropValue(pTask->m_tConfiguration)); + } + } - return 1; -} + bool TTask::IsRunning() const + { + return m_tLocalStats.IsRunning(); + } -void TTask::OnBeginOperation() -{ - CTime tm=CTime::GetCurrentTime(); + TSmartPath TTask::GetLogPath() const + { + return m_tBaseData.GetLogPath(); + } - TString strFormat = _T("\r\n# COPYING THREAD STARTED #\r\nBegan processing data (dd:mm:yyyy) %day.%month.%year at %hour:%minute.%second"); - strFormat.Replace(_t("%year"), boost::lexical_cast(tm.GetYear()).c_str()); - strFormat.Replace(_t("%month"), boost::lexical_cast(tm.GetMonth()).c_str()); - strFormat.Replace(_t("%day"), boost::lexical_cast(tm.GetDay()).c_str()); - strFormat.Replace(_t("%hour"), boost::lexical_cast(tm.GetHour()).c_str()); - strFormat.Replace(_t("%minute"), boost::lexical_cast(tm.GetMinute()).c_str()); - strFormat.Replace(_t("%second"), boost::lexical_cast(tm.GetSecond()).c_str()); - m_log.logi(strFormat.c_str()); -} + TString TTask::GetTaskName() const + { + return m_tBaseData.GetTaskName(); + } -void TTask::OnEndOperation() -{ - CTime tm=CTime::GetCurrentTime(); + void TTask::SetLogPath(const TSmartPath& pathLog) + { + m_tBaseData.SetLogPath(pathLog); + } - TString strFormat = _T("Finished processing data (dd:mm:yyyy) %day.%month.%year at %hour:%minute.%second"); - strFormat.Replace(_t("%year"), boost::lexical_cast(tm.GetYear()).c_str()); - strFormat.Replace(_t("%month"), boost::lexical_cast(tm.GetMonth()).c_str()); - strFormat.Replace(_t("%day"), boost::lexical_cast(tm.GetDay()).c_str()); - strFormat.Replace(_t("%hour"), boost::lexical_cast(tm.GetHour()).c_str()); - strFormat.Replace(_t("%minute"), boost::lexical_cast(tm.GetMinute()).c_str()); - strFormat.Replace(_t("%second"), boost::lexical_cast(tm.GetSecond()).c_str()); - m_log.logi(strFormat.c_str()); -} - -void TTask::RequestStopThread() -{ - m_workerThread.SignalThreadToStop(); -} - -void TTask::OnCfgOptionChanged(const TStringSet& rsetChanges, void* pParam) -{ - TTask* pTask = (TTask*)pParam; - if(!pTask) - THROW_CORE_EXCEPTION(eErr_InvalidArgument); - - if(rsetChanges.HasValue(TaskPropData::GetPropertyName())) + ISerializerPtr TTask::GetSerializer() const { - pTask->m_workerThread.ChangePriority(GetTaskPropValue(pTask->m_tConfiguration)); + return m_spSerializer; } -} -bool TTask::IsRunning() const -{ - return m_tLocalStats.IsRunning(); -} + icpf::log_file& TTask::GetLog() + { + if (!m_log.is_initialized()) + m_log.init(m_tBaseData.GetLogPath().ToString(), 262144, icpf::log_file::level_debug, false, false); -TSmartPath TTask::GetLogPath() const -{ - return m_tBaseData.GetLogPath(); + return m_log; + } } - -TString TTask::GetTaskName() const -{ - return m_tBaseData.GetTaskName(); -} - -void TTask::SetLogPath(const TSmartPath& pathLog) -{ - m_tBaseData.SetLogPath(pathLog); -} - -ISerializerPtr TTask::GetSerializer() const -{ - return m_spSerializer; -} - -icpf::log_file& TTask::GetLog() -{ - if (!m_log.is_initialized()) - m_log.init(m_tBaseData.GetLogPath().ToString(), 262144, icpf::log_file::level_debug, false, false); - - return m_log; -} - -END_CHCORE_NAMESPACE