Index: src/ch/task.cpp =================================================================== diff -u -N -rca046f75806db6693a4b2dc6ddb255f76d0bbc3f -r8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f --- src/ch/task.cpp (.../task.cpp) (revision ca046f75806db6693a4b2dc6ddb255f76d0bbc3f) +++ src/ch/task.cpp (.../task.cpp) (revision 8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f) @@ -49,16 +49,14 @@ void TTasksGlobalStats::IncreaseGlobalTotalSize(unsigned long long ullModify) { - m_lock.lock(); + boost::unique_lock lock(m_lock); m_ullGlobalTotalSize += ullModify; - m_lock.unlock(); } void TTasksGlobalStats::DecreaseGlobalTotalSize(unsigned long long ullModify) { - m_lock.lock(); + boost::unique_lock lock(m_lock); m_ullGlobalTotalSize -= ullModify; - m_lock.unlock(); } unsigned long long TTasksGlobalStats::GetGlobalTotalSize() const @@ -69,16 +67,14 @@ void TTasksGlobalStats::IncreaseGlobalProcessedSize(unsigned long long ullModify) { - m_lock.lock(); + boost::unique_lock lock(m_lock); m_ullGlobalProcessedSize += ullModify; - m_lock.unlock(); } void TTasksGlobalStats::DecreaseGlobalProcessedSize(unsigned long long ullModify) { - m_lock.lock(); + boost::unique_lock lock(m_lock); m_ullGlobalProcessedSize -= ullModify; - m_lock.unlock(); } unsigned long long TTasksGlobalStats::GetGlobalProcessedSize() const @@ -89,19 +85,16 @@ void TTasksGlobalStats::IncreaseGlobalProgressData(unsigned long long ullTasksPosition, unsigned long long ullTasksSize) { - m_lock.lock(); + boost::unique_lock lock(m_lock); m_ullGlobalTotalSize += ullTasksSize; m_ullGlobalProcessedSize += ullTasksPosition; - m_lock.unlock(); - } void TTasksGlobalStats::DecreaseGlobalProgressData(unsigned long long ullTasksPosition, unsigned long long ullTasksSize) { - m_lock.lock(); + boost::unique_lock lock(m_lock); m_ullGlobalTotalSize -= ullTasksSize; m_ullGlobalProcessedSize -= ullTasksPosition; - m_lock.unlock(); } int TTasksGlobalStats::GetProgressPercents() const @@ -118,16 +111,14 @@ void TTasksGlobalStats::IncreaseRunningTasks() { - m_lock.lock(); + boost::unique_lock lock(m_lock); ++m_stRunningTasks; - m_lock.unlock(); } void TTasksGlobalStats::DecreaseRunningTasks() { - m_lock.lock(); + boost::unique_lock lock(m_lock); --m_stRunningTasks; - m_lock.unlock(); } size_t TTasksGlobalStats::GetRunningTasksCount() const @@ -426,7 +417,6 @@ m_log(), m_piFeedbackHandler(piFeedbackHandler), m_files(m_arrSourcePaths), - m_nPriority(THREAD_PRIORITY_NORMAL), m_bForce(false), m_bContinue(false), m_bRareStateModified(false), @@ -436,12 +426,6 @@ m_eCurrentState(eTaskState_None) { BOOST_ASSERT(piFeedbackHandler); - - m_bsSizes.m_uiDefaultSize=65536; - m_bsSizes.m_uiOneDiskSize=4194304; - m_bsSizes.m_uiTwoDisksSize=262144; - m_bsSizes.m_uiCDSize=262144; - m_bsSizes.m_uiLANSize=65536; } CTask::~CTask() @@ -548,38 +532,37 @@ return m_eCurrentState; } -// m_nBufferSize -void CTask::SetBufferSizes(const BUFFERSIZES* bsSizes) +void CTask::SetBufferSizes(const BUFFERSIZES& bsSizes) { - boost::unique_lock lock(m_lock); - m_bsSizes = *bsSizes; - m_bOftenStateModified = true; + m_tTaskDefinition.GetConfiguration().DelayNotifications(); + SetTaskPropValue(m_tTaskDefinition.GetConfiguration(), bsSizes.m_uiDefaultSize); + SetTaskPropValue(m_tTaskDefinition.GetConfiguration(), bsSizes.m_uiOneDiskSize); + SetTaskPropValue(m_tTaskDefinition.GetConfiguration(), bsSizes.m_uiTwoDisksSize); + SetTaskPropValue(m_tTaskDefinition.GetConfiguration(), bsSizes.m_uiCDSize); + SetTaskPropValue(m_tTaskDefinition.GetConfiguration(), bsSizes.m_uiLANSize); + SetTaskPropValue(m_tTaskDefinition.GetConfiguration(), bsSizes.m_bOnlyDefault); + m_tTaskDefinition.GetConfiguration().ResumeNotifications(); } -const BUFFERSIZES* CTask::GetBufferSizes() +void CTask::GetBufferSizes(BUFFERSIZES& bsSizes) { - boost::shared_lock lock(m_lock); - return &m_bsSizes; + bsSizes.m_uiDefaultSize = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); + bsSizes.m_uiOneDiskSize = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); + bsSizes.m_uiTwoDisksSize = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); + bsSizes.m_uiCDSize = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); + bsSizes.m_uiLANSize = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); + bsSizes.m_bOnlyDefault = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); } int CTask::GetCurrentBufferIndex() { return m_files.GetBufferIndexAt(m_tTaskBasicProgressInfo.GetCurrentIndex(), m_tDestinationPath); } -// m_pThread -// m_nPriority -int CTask::GetPriority() -{ - boost::shared_lock lock(m_lock); - - return m_nPriority; -} - +// thread void CTask::SetPriority(int nPriority) { - boost::unique_lock lock(m_lock); - SetPriorityNL(nPriority); + SetTaskPropValue(m_tTaskDefinition.GetConfiguration(), nPriority); } void CTask::CalculateTotalSize() @@ -654,9 +637,6 @@ THROW(_T("Wrong data read from stream"), 0, 0, 0); } - ar2 >> m_bsSizes; - ar2 >> m_nPriority; - time_t timeElapsed = 0; ar2 >> timeElapsed; m_localStats.SetTimeElapsed(timeElapsed); @@ -709,9 +689,6 @@ ar << iState; - ar << m_bsSizes; - ar << m_nPriority; - time_t timeElapsed = m_localStats.GetTimeElapsed(); ar << timeElapsed; @@ -740,7 +717,7 @@ m_bRareStateModified = true; m_bOftenStateModified = true; - m_workerThread.StartThread(DelegateThreadProc, this, m_nPriority); + m_workerThread.StartThread(DelegateThreadProc, this, GetTaskPropValue(m_tTaskDefinition.GetConfiguration())); } void CTask::ResumeProcessing() @@ -856,8 +833,7 @@ } } - pData->m_pbsSizes=&m_bsSizes; - pData->m_nPriority=m_nPriority; + pData->m_nPriority = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); pData->m_strDstPath = m_tTaskDefinition.GetDestinationPath(); pData->m_pafFilters=&m_afFilters; pData->m_eTaskState = m_eCurrentState; @@ -873,10 +849,33 @@ pData->m_bCreateEmptyFiles = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); if(m_files.GetSize() > 0) - pData->m_iCurrentBufferIndex=m_bsSizes.m_bOnlyDefault ? 0 : m_files.GetAt((stCurrentIndex < m_files.GetSize()) ? stCurrentIndex : 0)->GetBufferIndex(m_tDestinationPath); + pData->m_iCurrentBufferIndex = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()) ? 0 : m_files.GetAt((stCurrentIndex < m_files.GetSize()) ? stCurrentIndex : 0)->GetBufferIndex(m_tDestinationPath); else - pData->m_iCurrentBufferIndex=0; + pData->m_iCurrentBufferIndex = 0; + switch(pData->m_iCurrentBufferIndex) + { + case BI_DEFAULT: + pData->m_iCurrentBufferSize = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); + break; + case BI_ONEDISK: + pData->m_iCurrentBufferSize = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); + break; + case BI_TWODISKS: + pData->m_iCurrentBufferSize = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); + break; + case BI_CD: + pData->m_iCurrentBufferSize = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); + break; + case BI_LAN: + pData->m_iCurrentBufferSize = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); + break; + default: + THROW(_T("Unhandled case"), 0, 0, 0); + //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. + } + // percents pData->m_nPercent = m_localStats.GetProgressInPercent(); @@ -1010,33 +1009,6 @@ return bResult != 0; } -// m_nBufferSize -void CTask::SetBufferSizesNL(const BUFFERSIZES* bsSizes) -{ - m_bsSizes = *bsSizes; - m_bOftenStateModified = true; -} - -const BUFFERSIZES* CTask::GetBufferSizesNL() -{ - return &m_bsSizes; -} - -// m_pThread -// m_nPriority -int CTask::GetPriorityNL() -{ - return m_nPriority; -} - -void CTask::SetPriorityNL(int nPriority) -{ - m_workerThread.ChangePriority(nPriority); - - m_nPriority = nPriority; - m_bOftenStateModified = true; -} - void CTask::CalculateTotalSizeNL() { unsigned long long ullTotalSize = 0; @@ -1920,7 +1892,7 @@ } // recreate buffer if needed - if(m_cfgTracker.IsModified() && m_cfgTracker.IsModified(TOptionsSet() % eTO_DefaultBufferSize % eTO_OneDiskBufferSize % eTO_TwoDisksBufferSize % eTO_CDBufferSize % eTO_LANBufferSize % eTO_UseOnlyDefaultBuffer)) + if(m_cfgTracker.IsModified() && m_cfgTracker.IsModified(TOptionsSet() % eTO_DefaultBufferSize % eTO_OneDiskBufferSize % eTO_TwoDisksBufferSize % eTO_CDBufferSize % eTO_LANBufferSize % eTO_UseOnlyDefaultBuffer, true)) { BUFFERSIZES bs; bs.m_bOnlyDefault = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); @@ -1949,11 +1921,11 @@ fmt.SetParam(_t("%dstfile"), pData->strDstFile); m_log.logi(fmt); - pData->dbBuffer.Create(GetBufferSizes()); + pData->dbBuffer.Create(&bs); } // establish count of data to read - if(GetBufferSizes()->m_bOnlyDefault) + if(GetTaskPropValue(m_tTaskDefinition.GetConfiguration())) iBufferIndex = BI_DEFAULT; else iBufferIndex = pData->spSrcFile->GetBufferIndex(m_tDestinationPath); @@ -2094,7 +2066,15 @@ // remove changes in buffer sizes to avoid re-creation later m_cfgTracker.RemoveModificationSet(TOptionsSet() % eTO_DefaultBufferSize % eTO_OneDiskBufferSize % eTO_TwoDisksBufferSize % eTO_CDBufferSize % eTO_LANBufferSize % eTO_UseOnlyDefaultBuffer); - ccp.dbBuffer.Create(GetBufferSizes()); + BUFFERSIZES bs; + bs.m_bOnlyDefault = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); + bs.m_uiDefaultSize = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); + bs.m_uiOneDiskSize = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); + bs.m_uiTwoDisksSize = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); + bs.m_uiCDSize = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); + bs.m_uiLANSize = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); + + ccp.dbBuffer.Create(&bs); ccp.pDestPath = &m_tDestinationPath; // helpers @@ -2372,6 +2352,7 @@ // enable configuration changes tracking m_tTaskDefinition.GetConfiguration().ConnectToNotifier(TTaskConfigTracker::NotificationProc, &m_cfgTracker); + m_tTaskDefinition.GetConfiguration().ConnectToNotifier(CTask::OnCfgOptionChanged, this); // set thread options HANDLE hThread = GetCurrentThread(); @@ -2491,13 +2472,15 @@ m_localStats.MarkTaskAsNotRunning(); m_tTaskDefinition.GetConfiguration().DisconnectFromNotifier(TTaskConfigTracker::NotificationProc); + m_tTaskDefinition.GetConfiguration().DisconnectFromNotifier(CTask::OnCfgOptionChanged); // and the real end OnEndOperation(); } catch(...) { m_tTaskDefinition.GetConfiguration().DisconnectFromNotifier(TTaskConfigTracker::NotificationProc); + m_tTaskDefinition.GetConfiguration().DisconnectFromNotifier(CTask::OnCfgOptionChanged); // refresh time m_localStats.DisableTimeTracking(); @@ -2596,6 +2579,18 @@ } } +void CTask::OnCfgOptionChanged(const std::set& rsetChanges, void* pParam) +{ + CTask* pTask = (CTask*)pParam; + if(!pTask) + THROW(_T("Invalid pointer"), 0, 0, 0); + + if(rsetChanges.find(TaskPropData::GetPropertyName()) != rsetChanges.end()) + { + pTask->m_workerThread.ChangePriority(GetTaskPropValue(pTask->GetTaskDefinition().GetConfiguration())); + } +} + //////////////////////////////////////////////////////////////////////////////// // CTaskArray members CTaskArray::CTaskArray() : @@ -2724,24 +2719,25 @@ { std::vector vTasksToRemove; - m_lock.lock(); - - size_t stIndex = m_vTasks.size(); - while(stIndex--) + // separate scope for locking { - CTaskPtr spTask = m_vTasks.at(stIndex); - - // delete only when the thread is finished - if((spTask->GetTaskState() == eTaskState_Finished || spTask->GetTaskState() == eTaskState_Cancelled)) + boost::unique_lock lock(m_lock); + + size_t stIndex = m_vTasks.size(); + while(stIndex--) { - spTask->OnUnregisterTask(); + CTaskPtr spTask = m_vTasks.at(stIndex); - vTasksToRemove.push_back(spTask); - m_vTasks.erase(m_vTasks.begin() + stIndex); + // delete only when the thread is finished + if((spTask->GetTaskState() == eTaskState_Finished || spTask->GetTaskState() == eTaskState_Cancelled)) + { + spTask->OnUnregisterTask(); + + vTasksToRemove.push_back(spTask); + m_vTasks.erase(m_vTasks.begin() + stIndex); + } } } - - m_lock.unlock(); BOOST_FOREACH(CTaskPtr& spTask, vTasksToRemove) {