Index: src/ch/MiniViewDlg.cpp =================================================================== diff -u -N -r4a3c74a38b00e7793d1e61107a824060e6c2ea95 -r61ed5f2f3084ba759ec27f61b4f909ed8ce305e9 --- src/ch/MiniViewDlg.cpp (.../MiniViewDlg.cpp) (revision 4a3c74a38b00e7793d1e61107a824060e6c2ea95) +++ src/ch/MiniViewDlg.cpp (.../MiniViewDlg.cpp) (revision 61ed5f2f3084ba759ec27f61b4f909ed8ce305e9) @@ -186,16 +186,16 @@ CTaskPtr spTask = m_pTasks->GetAt(stIndex); spTask->GetMiniSnapshot(&m_tMiniDisplayData); - if((m_tMiniDisplayData.m_uiStatus & ST_STEP_MASK) != ST_FINISHED && (m_tMiniDisplayData.m_uiStatus & ST_STEP_MASK) != ST_CANCELLED) + if(m_tMiniDisplayData.m_eTaskState != eTaskState_Finished && m_tMiniDisplayData.m_eTaskState != eTaskState_Cancelled) { pItem = m_ctlStatus.GetItemAddress(index++); // load - if ((m_tMiniDisplayData.m_uiStatus & ST_WORKING_MASK) == ST_ERROR) + if(m_tMiniDisplayData.m_eTaskState == eTaskState_Error) pItem->m_crColor=RGB(255, 0, 0); - else if ((m_tMiniDisplayData.m_uiStatus & ST_WORKING_MASK) == ST_PAUSED) + else if(m_tMiniDisplayData.m_eTaskState == eTaskState_Paused) pItem->m_crColor=RGB(255, 255, 0); - else if ((m_tMiniDisplayData.m_uiStatus & ST_WAITING_MASK) == ST_WAITING) + else if(m_tMiniDisplayData.m_eTaskState == eTaskState_Waiting) pItem->m_crColor=RGB(50, 50, 50); else pItem->m_crColor=RGB(0, 255, 0); @@ -516,7 +516,7 @@ CTaskPtr spTask = pDlg->m_ctlStatus.m_vItems.at(iSel)->m_spTask; if (spTask) { - if(spTask->GetStatus(ST_WAITING_MASK) & ST_WAITING) + if(spTask->GetTaskState() == eTaskState_Waiting) spTask->SetForceFlag(true); else spTask->ResumeProcessing(); Index: src/ch/StatusDlg.cpp =================================================================== diff -u -N -r3ba4fcc537059e952471a77c3cc9893e779bce98 -r61ed5f2f3084ba759ec27f61b4f909ed8ce305e9 --- src/ch/StatusDlg.cpp (.../StatusDlg.cpp) (revision 3ba4fcc537059e952471a77c3cc9893e779bce98) +++ src/ch/StatusDlg.cpp (.../StatusDlg.cpp) (revision 61ed5f2f3084ba759ec27f61b4f909ed8ce305e9) @@ -237,7 +237,7 @@ lvi.pszText=td.m_szStatusText; lvi.cchTextMax=lstrlen(lvi.pszText); lvi.lParam = spTask->GetSessionUniqueID(); - lvi.iImage=GetImageFromStatus(td.m_uiStatus); + lvi.iImage=GetImageFromStatus(td.m_eTaskState); if (nPos < m_ctlStatusList.GetItemCount()) m_ctlStatusList.SetItem(&lvi); else @@ -412,8 +412,7 @@ GetDlgItem(IDC_SHOW_LOG_BUTTON)->EnableWindow(true); GetDlgItem(IDC_DELETE_BUTTON)->EnableWindow(true); - if (m_spSelectedItem->GetStatus(ST_STEP_MASK) == ST_FINISHED - || m_spSelectedItem->GetStatus(ST_STEP_MASK) == ST_CANCELLED) + if (m_spSelectedItem->GetTaskState() == eTaskState_Finished || m_spSelectedItem->GetTaskState() == eTaskState_Cancelled) { GetDlgItem(IDC_CANCEL_BUTTON)->EnableWindow(false); GetDlgItem(IDC_PAUSE_BUTTON)->EnableWindow(false); @@ -422,15 +421,15 @@ else { // pause/resume - if (m_spSelectedItem->GetStatus(ST_WORKING_MASK) & ST_PAUSED) + if (m_spSelectedItem->GetTaskState() == eTaskState_Paused) { GetDlgItem(IDC_PAUSE_BUTTON)->EnableWindow(false); GetDlgItem(IDC_RESUME_BUTTON)->EnableWindow(true); } else { GetDlgItem(IDC_PAUSE_BUTTON)->EnableWindow(true); - if (m_spSelectedItem->GetStatus(ST_WAITING_MASK) & ST_WAITING) + if (m_spSelectedItem->GetTaskState() == eTaskState_Waiting) GetDlgItem(IDC_RESUME_BUTTON)->EnableWindow(true); else GetDlgItem(IDC_RESUME_BUTTON)->EnableWindow(false); @@ -535,7 +534,7 @@ CTaskPtr spTask = GetSelectedItemPointer(); if(spTask) { - if(spTask->GetStatus(ST_WAITING_MASK) & ST_WAITING) + if(spTask->GetTaskState() == eTaskState_Waiting) spTask->SetForceFlag(); else spTask->ResumeProcessing(); @@ -569,8 +568,8 @@ CTaskPtr spTask = GetSelectedItemPointer(); if(spTask) { - UINT uiStatus = spTask->GetStatus(ST_STEP_MASK); - if((uiStatus & ST_STEP_MASK) != ST_FINISHED && (uiStatus & ST_STEP_MASK) != ST_CANCELLED) + ETaskCurrentState eTaskState = spTask->GetTaskState(); + if(eTaskState != eTaskState_Finished && eTaskState != eTaskState_Cancelled) { // ask if cancel if(MsgBox(IDS_CONFIRMCANCEL_STRING, MB_OKCANCEL | MB_ICONQUESTION) == IDOK) @@ -635,7 +634,7 @@ if (!spTask) return; - if(spTask->GetStatus(ST_WORKING_MASK) & ST_PAUSED) + if(spTask->GetTaskState() == eTaskState_Paused) OnResumeButton(); else OnPauseButton(); @@ -646,19 +645,23 @@ *pResult = 0; } -int CStatusDlg::GetImageFromStatus(UINT nStatus) +int CStatusDlg::GetImageFromStatus(ETaskCurrentState eState) { - if ( (nStatus & ST_STEP_MASK) == ST_CANCELLED ) - return 4; - if ( (nStatus & ST_STEP_MASK) == ST_FINISHED ) - return 3; - if ( (nStatus & ST_WAITING_MASK) == ST_WAITING ) - return 5; - if ( (nStatus & ST_WORKING_MASK) == ST_PAUSED ) - return 2; - if ( (nStatus & ST_WORKING_MASK) == ST_ERROR ) - return 1; - return 0; + switch(eState) + { + case eTaskState_Cancelled: + return 4; + case eTaskState_Finished: + return 3; + case eTaskState_Waiting: + return 5; + case eTaskState_Paused: + return 2; + case eTaskState_Error: + return 1; + default: + return 0; + } } LPTSTR CStatusDlg::FormatTime(time_t timeSeconds, LPTSTR lpszBuffer, size_t stMaxBufferSize) @@ -791,10 +794,10 @@ // check if there's a selection currently if ( (m_spSelectedItem=GetSelectedItemPointer()) != NULL ) { - if (m_spSelectedItem->GetStatus(ST_WORKING_MASK) & ST_PAUSED) + if (m_spSelectedItem->GetTaskState() == eTaskState_Paused) { bool bContinue=false; - if (m_spSelectedItem->GetStatus(ST_WORKING_MASK) == ST_ERROR) + if (m_spSelectedItem->GetTaskState() == eTaskState_Error) { m_spSelectedItem->PauseProcessing(); bContinue=true; Index: src/ch/StatusDlg.h =================================================================== diff -u -N -r1fa2eb7e39e2f8d84868d421fe1c4f0afc58d353 -r61ed5f2f3084ba759ec27f61b4f909ed8ce305e9 --- src/ch/StatusDlg.h (.../StatusDlg.h) (revision 1fa2eb7e39e2f8d84868d421fe1c4f0afc58d353) +++ src/ch/StatusDlg.h (.../StatusDlg.h) (revision 61ed5f2f3084ba759ec27f61b4f909ed8ce305e9) @@ -37,7 +37,7 @@ void SetBufferSizesString(UINT uiValue, int iIndex); void RefreshStatus(); LPTSTR FormatTime(time_t timeSeconds, LPTSTR lpszBuffer, size_t stMaxBufferSize); - int GetImageFromStatus(UINT nStatus); + int GetImageFromStatus(ETaskCurrentState eState); void ApplyButtonsState(); void ApplyDisplayDetails(bool bInitial=false); Index: src/ch/task.cpp =================================================================== diff -u -N -rc3ae933971862f544e10106f4f766c206a3478b5 -r61ed5f2f3084ba759ec27f61b4f909ed8ce305e9 --- src/ch/task.cpp (.../task.cpp) (revision c3ae933971862f544e10106f4f766c206a3478b5) +++ src/ch/task.cpp (.../task.cpp) (revision 61ed5f2f3084ba759ec27f61b4f909ed8ce305e9) @@ -583,6 +583,19 @@ return m_nStatus & nMask; } +void CTask::SetTaskState(ETaskCurrentState eTaskState) +{ + // NOTE: we could check some transition rules here + boost::unique_lock lock(m_lock); + m_eCurrentState = eTaskState; +} + +ETaskCurrentState CTask::GetTaskState() const +{ + boost::shared_lock lock(m_lock); + return m_eCurrentState; +} + // m_nBufferSize void CTask::SetBufferSizes(const BUFFERSIZES* bsSizes) { @@ -672,6 +685,7 @@ else { UINT uiData = 0; + int iState = eTaskState_None; ar >> m_tTaskProgressInfo; @@ -680,6 +694,20 @@ ar >> uiData; m_nStatus = uiData; + // load task state, convert "waiting" state to "processing" + ar >> iState; + if(iState >= eTaskState_None && iState < eTaskState_Max) + { + if(iState == eTaskState_Waiting) + iState = eTaskState_Processing; + m_eCurrentState = (ETaskCurrentState)iState; + } + else + { + BOOST_ASSERT(false); + THROW(_T("Wrong data read from stream"), 0, 0, 0); + } + ar >> m_bsSizes; ar >> m_nPriority; @@ -704,8 +732,7 @@ if(!bData && m_bSaved) return; - if(!bData && !m_bSaved && ( (m_nStatus & ST_STEP_MASK) == ST_FINISHED || (m_nStatus & ST_STEP_MASK) == ST_CANCELLED - || (m_nStatus & ST_WORKING_MASK) == ST_PAUSED )) + if(!bData && !m_bSaved && (m_eCurrentState == eTaskState_Finished || m_eCurrentState == eTaskState_Cancelled || m_nStatus == eTaskState_Paused)) { m_bSaved = true; } @@ -738,6 +765,13 @@ UINT uiStatus = (m_nStatus & ST_WRITE_MASK); ar << uiStatus; + // store current state (convert from waiting to processing state before storing) + int iState = m_eCurrentState; + if(iState == eTaskState_Waiting) + iState = eTaskState_Processing; + + ar << iState; + ar << m_bsSizes; ar << m_nPriority; @@ -773,20 +807,18 @@ void CTask::ResumeProcessing() { // the same as retry but less demanding - if( (GetStatus(ST_WORKING_MASK) & ST_PAUSED) && GetStatus(ST_STEP_MASK) != ST_FINISHED - && GetStatus(ST_STEP_MASK) != ST_CANCELLED) + if(GetTaskState() == eTaskState_Paused) { - SetStatus(0, ST_ERROR); + SetTaskState(eTaskState_Processing); BeginProcessing(); } } bool CTask::RetryProcessing() { // retry used to auto-resume, after loading - if(GetStatus(ST_WORKING_MASK) != ST_PAUSED && GetStatus(ST_STEP_MASK) != ST_FINISHED && GetStatus(ST_STEP_MASK) != ST_CANCELLED) + if(GetTaskState() != eTaskState_Paused && GetTaskState() != eTaskState_Finished && GetTaskState() != eTaskState_Cancelled) { - SetStatus(0, ST_ERROR); BeginProcessing(); return true; } @@ -796,8 +828,9 @@ void CTask::RestartProcessing() { KillThread(); - SetStatus(0, ST_ERROR); - SetStatus(ST_NULL_STATUS, ST_STEP_MASK); + + SetTaskState(eTaskState_None); + m_localStats.SetTimeElapsed(0); m_tTaskProgressInfo.SetCurrentIndex(0); @@ -806,22 +839,21 @@ void CTask::PauseProcessing() { - if(GetStatus(ST_STEP_MASK) != ST_FINISHED && GetStatus(ST_STEP_MASK) != ST_CANCELLED) + if(GetTaskState() != eTaskState_Finished && GetTaskState() != eTaskState_Cancelled) { KillThread(); - SetStatus(ST_PAUSED, ST_WORKING_MASK); - m_bSaved=false; + SetTaskState(eTaskState_Paused); + m_bSaved = false; } } void CTask::CancelProcessing() { // change to ST_CANCELLED - if(GetStatus(ST_STEP_MASK) != ST_FINISHED) + if(GetTaskState() != eTaskState_Finished) { KillThread(); - SetStatus(ST_CANCELLED, ST_STEP_MASK); - SetStatus(0, ST_ERROR); + SetTaskState(eTaskState_Cancelled); m_bSaved=false; } } @@ -846,7 +878,8 @@ } } - pData->m_uiStatus=m_nStatus; + pData->m_uiStatus = m_nStatus; + pData->m_eTaskState = m_eCurrentState; // percents pData->m_nPercent = m_localStats.GetProgressInPercent(); @@ -889,6 +922,7 @@ pData->m_pdpDestPath=&m_dpDestPath; pData->m_pafFilters=&m_afFilters; pData->m_uiStatus=m_nStatus; + pData->m_eTaskState = m_eCurrentState; pData->m_stIndex = stCurrentIndex; pData->m_ullProcessedSize = m_localStats.GetProcessedSize(); pData->m_stSize=m_files.GetSize(); @@ -905,33 +939,41 @@ // status string // first - if( (m_nStatus & ST_WORKING_MASK) == ST_ERROR ) + switch(m_eCurrentState) + { + case eTaskState_Error: { GetResManager().LoadStringCopy(IDS_STATUS0_STRING+4, pData->m_szStatusText, _MAX_PATH); _tcscat(pData->m_szStatusText, _T("/")); + break; } - else if( (m_nStatus & ST_WORKING_MASK) == ST_PAUSED ) + case eTaskState_Paused: { GetResManager().LoadStringCopy(IDS_STATUS0_STRING+5, pData->m_szStatusText, _MAX_PATH); _tcscat(pData->m_szStatusText, _T("/")); + break; } - else if( (m_nStatus & ST_STEP_MASK) == ST_FINISHED ) + case eTaskState_Finished: { GetResManager().LoadStringCopy(IDS_STATUS0_STRING+3, pData->m_szStatusText, _MAX_PATH); _tcscat(pData->m_szStatusText, _T("/")); + break; } - else if( (m_nStatus & ST_WAITING_MASK) == ST_WAITING ) + case eTaskState_Waiting: { GetResManager().LoadStringCopy(IDS_STATUS0_STRING+9, pData->m_szStatusText, _MAX_PATH); _tcscat(pData->m_szStatusText, _T("/")); + break; } - else if( (m_nStatus & ST_STEP_MASK) == ST_CANCELLED ) + case eTaskState_Cancelled: { GetResManager().LoadStringCopy(IDS_STATUS0_STRING+8, pData->m_szStatusText, _MAX_PATH); _tcscat(pData->m_szStatusText, _T("/")); + break; } - else + default: _tcscpy(pData->m_szStatusText, _T("")); + } // second part if( (m_nStatus & ST_STEP_MASK) == ST_DELETING ) @@ -1403,7 +1445,7 @@ }//while // change status to finished - SetStatus(ST_FINISHED, ST_STEP_MASK); + SetTaskState(eTaskState_Finished); // add 1 to current index m_tTaskProgressInfo.IncreaseCurrentIndex(); @@ -2264,7 +2306,7 @@ } else { - SetStatus(ST_FINISHED, ST_STEP_MASK); + SetTaskState(eTaskState_Finished); // to look better - increase current index by 1 m_tTaskProgressInfo.SetCurrentIndex(stSize); @@ -2276,14 +2318,14 @@ void CTask::CheckForWaitState() { // limiting operation count - SetStatus(ST_WAITING, ST_WAITING_MASK); + SetTaskState(eTaskState_Waiting); bool bContinue = false; while(!bContinue) { if(CanBegin()) { - SetStatus(0, ST_WAITING); - bContinue=true; + SetTaskState(eTaskState_Processing); + bContinue = true; m_log.logi(_T("Finished waiting for begin permission")); @@ -2450,14 +2492,22 @@ switch(e->m_iType) { case E_ERROR: - SetStatus(ST_ERROR, ST_WORKING_MASK); + SetTaskState(eTaskState_Error); break; case E_CANCEL: - SetStatus(ST_CANCELLED, ST_STEP_MASK); + SetTaskState(eTaskState_Cancelled); break; case E_PAUSE: - SetStatus(ST_PAUSED, ST_PAUSED); + SetTaskState(eTaskState_Paused); break; + case E_KILL_REQUEST: + { + // the only operation + if(GetTaskState() == eTaskState_Waiting) + SetTaskState(eTaskState_Processing); + } + default: + BOOST_ASSERT(false); // unhandled case } // change flags and calls cleanup for a task @@ -2479,8 +2529,6 @@ break; } - if(GetStatus(ST_WAITING_MASK) & ST_WAITING) - SetStatus(0, ST_WAITING); m_localStats.MarkTaskAsNotRunning(); SetContinueFlag(false); SetForceFlag(false); @@ -2666,7 +2714,7 @@ CTaskPtr spTask = m_vTasks.at(stIndex); // delete only when the thread is finished - if((spTask->GetStatus(ST_STEP_MASK) == ST_FINISHED || spTask->GetStatus(ST_STEP_MASK) == ST_CANCELLED)) + if((spTask->GetTaskState() == eTaskState_Finished || spTask->GetTaskState() == eTaskState_Cancelled)) { spTask->OnUnregisterTask(); @@ -2693,7 +2741,7 @@ { CTaskPtr& spTask = *iterTask; - if(spTask == spSelTask && (spTask->GetStatus(ST_STEP_MASK) == ST_FINISHED || spTask->GetStatus(ST_STEP_MASK) == ST_CANCELLED)) + if(spTask == spSelTask && (spTask->GetTaskState() == eTaskState_Finished || spTask->GetTaskState() == eTaskState_Cancelled)) { // kill task if needed spTask->KillThread(); @@ -2726,7 +2774,7 @@ BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) { // turn on some thread - find something with wait state - if(spTask->GetStatus(ST_WAITING_MASK) & ST_WAITING && (stMaxRunningTasks == 0 || m_globalStats.GetRunningTasksCount() < stMaxRunningTasks)) + if(spTask->GetTaskState() == eTaskState_Waiting && (stMaxRunningTasks == 0 || m_globalStats.GetRunningTasksCount() < stMaxRunningTasks)) { spTask->m_localStats.MarkTaskAsRunning(); spTask->SetContinueFlagNL(true); @@ -2876,7 +2924,6 @@ bool CTaskArray::AreAllFinished() { bool bFlag=true; - UINT uiStatus; if(m_globalStats.GetRunningTasksCount() != 0) bFlag = false; @@ -2885,10 +2932,8 @@ boost::shared_lock lock(m_lock); BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) { - uiStatus = spTask->GetStatus(); - bFlag = ((uiStatus & ST_STEP_MASK) == ST_FINISHED || (uiStatus & ST_STEP_MASK) == ST_CANCELLED - || (uiStatus & ST_WORKING_MASK) == ST_PAUSED - || ((uiStatus & ST_WORKING_MASK) == ST_ERROR)); + ETaskCurrentState eState = spTask->GetTaskState(); + bFlag = (eState == eTaskState_Finished || eState == eTaskState_Cancelled || eState == eTaskState_Paused || eState == eTaskState_Error); if(!bFlag) break; Index: src/ch/task.h =================================================================== diff -u -N -r0c8e64ca71144467eed1f1d6c32d59bc2150a004 -r61ed5f2f3084ba759ec27f61b4f909ed8ce305e9 --- src/ch/task.h (.../task.h) (revision 0c8e64ca71144467eed1f1d6c32d59bc2150a004) +++ src/ch/task.h (.../task.h) (revision 61ed5f2f3084ba759ec27f61b4f909ed8ce305e9) @@ -37,8 +37,6 @@ #define ST_SEARCHING 0x00000001 #define ST_COPYING 0x00000002 #define ST_DELETING 0x00000003 -#define ST_FINISHED 0x00000004 -#define ST_CANCELLED 0x00000005 //------------------------------------ #define ST_OPERATION_MASK 0x00000f00 @@ -53,14 +51,19 @@ #define ST_IGNORE_CONTENT 0x00002000 #define ST_FORCE_DIRS 0x00004000 -//------------------------------------ -#define ST_WORKING_MASK 0x000f0000 -#define ST_ERROR 0x000C0000 -#define ST_PAUSED 0x00080000 +enum ETaskCurrentState +{ + eTaskState_None, + eTaskState_Waiting, + eTaskState_Processing, + eTaskState_Paused, + eTaskState_Cancelled, + eTaskState_Error, + eTaskState_Finished, -//------------------------------------ -#define ST_WAITING_MASK 0x00f00000 -#define ST_WAITING 0x00100000 + // insert new values before this one + eTaskState_Max +}; /////////////////////////////////////////////////////////////////////////// // Exceptions @@ -87,6 +90,7 @@ CFiltersArray* m_pafFilters; UINT m_uiStatus; + ETaskCurrentState m_eTaskState; const BUFFERSIZES* m_pbsSizes; int m_nPriority; @@ -107,6 +111,8 @@ CString m_strPath; UINT m_uiStatus; + ETaskCurrentState m_eTaskState; + int m_nPercent; }; @@ -387,6 +393,9 @@ void SetStatus(UINT nStatus, UINT nMask); UINT GetStatus(UINT nMask = 0xffffffff); + void SetTaskState(ETaskCurrentState eTaskState); + ETaskCurrentState GetTaskState() const; + // m_nBufferSize void SetBufferSizes(const BUFFERSIZES* bsSizes); const BUFFERSIZES* GetBufferSizes(); @@ -522,6 +531,7 @@ CFileInfoArray m_files; // list of files/directories found during operating on the task input data (filled by search for files) // changing fast + volatile ETaskCurrentState m_eCurrentState; // current state of processing this task represents volatile UINT m_nStatus; // what phase of the operation is this task in TTaskProgressInfo m_tTaskProgressInfo; // task progress information