Index: src/ch/FileInfo.cpp =================================================================== diff -u -r4ec3aef62d14193e3021e6bc3f8bcdf11770c7d5 -r860b25a7b72cd40f83d810f7c72a5e2a76f88987 --- src/ch/FileInfo.cpp (.../FileInfo.cpp) (revision 4ec3aef62d14193e3021e6bc3f8bcdf11770c7d5) +++ src/ch/FileInfo.cpp (.../FileInfo.cpp) (revision 860b25a7b72cd40f83d810f7c72a5e2a76f88987) @@ -514,6 +514,15 @@ /////////////////////////////////////////////////////////////////////// // Array +CFileInfoArray::CFileInfoArray(CClipboardArray& rClipboardArray) : + m_rClipboard(rClipboardArray) +{ +} + +CFileInfoArray::~CFileInfoArray() +{ +} + void CFileInfoArray::AddFileInfo(const CFileInfoPtr& spFileInfo) { boost::unique_lock lock(m_lock); @@ -554,3 +563,32 @@ boost::unique_lock lock(m_lock); m_vFiles.clear(); } + +unsigned long long CFileInfoArray::CalculateTotalSize() +{ + unsigned long long ullSize = 0; + + boost::shared_lock lock(m_lock); + BOOST_FOREACH(CFileInfoPtr& spFileInfo, m_vFiles) + { + ullSize += spFileInfo->GetLength64(); + } + + return ullSize; +} + +unsigned long long CFileInfoArray::CalculatePartialSize(size_t stCount) +{ + unsigned long long ullSize = 0; + + boost::shared_lock lock(m_lock); + if(stCount > m_vFiles.size()) + THROW(_T("Invalid argument"), 0, 0, 0); + + for(std::vector::iterator iter = m_vFiles.begin(); iter != m_vFiles.begin() + stCount; ++iter) + { + ullSize += (*iter)->GetLength64(); + } + + return ullSize; +} Index: src/ch/FileInfo.h =================================================================== diff -u -rbd08c279240bac9e7902f8da6a9251e0252ec324 -r860b25a7b72cd40f83d810f7c72a5e2a76f88987 --- src/ch/FileInfo.h (.../FileInfo.h) (revision bd08c279240bac9e7902f8da6a9251e0252ec324) +++ src/ch/FileInfo.h (.../FileInfo.h) (revision 860b25a7b72cd40f83d810f7c72a5e2a76f88987) @@ -257,76 +257,95 @@ class CFileInfoArray { public: - CFileInfoArray(CClipboardArray& A_rClipboardArray) : - m_rClipboard(A_rClipboardArray) - { - } + CFileInfoArray(CClipboardArray& rClipboardArray); + ~CFileInfoArray(); + // Adds a new object info to this container void AddFileInfo(const CFileInfoPtr& spFileInfo); + /// Retrieves count of elements in this object size_t GetSize() const; + + /// Retrieves an element at the specified index CFileInfoPtr GetAt(size_t stIndex) const; + + /// Retrieves a copy of the element at a specified index CFileInfo GetCopyAt(size_t stIndex) const; - + + /// Removes all elements from this object void Clear(); - // store/restore + // specialized operations on contents of m_vFiles + /// Calculates the size of the first stCount file info objects + unsigned long long CalculatePartialSize(size_t stCount); + + /// Calculates the size of all file info objects inside this object + unsigned long long CalculateTotalSize(); + + /// Stores infos about elements in the archive template - void Store(Archive& ar, unsigned int /*uiVersion*/, bool bOnlyFlags) + void Store(Archive& ar, unsigned int /*uiVersion*/, bool bOnlyFlags); + + /// Restores info from the archive + template + void Load(Archive& ar, unsigned int /*uiVersion*/, bool bOnlyFlags); + +protected: + CClipboardArray& m_rClipboard; + std::vector m_vFiles; + mutable boost::shared_mutex m_lock; +}; + +template +void CFileInfoArray::Store(Archive& ar, unsigned int /*uiVersion*/, bool bOnlyFlags) +{ + size_t stCount = m_vFiles.size(); + ar << stCount; + for(std::vector::iterator iterFile = m_vFiles.begin(); iterFile != m_vFiles.end(); ++iterFile) { - size_t stCount = m_vFiles.size(); - ar << stCount; - for(std::vector::iterator iterFile = m_vFiles.begin(); iterFile != m_vFiles.end(); ++iterFile) + if(bOnlyFlags) { - if(bOnlyFlags) - { - uint_t uiFlags = (*iterFile)->GetFlags(); - ar << uiFlags; - } - else - ar << *(*iterFile); + uint_t uiFlags = (*iterFile)->GetFlags(); + ar << uiFlags; } + else + ar << *(*iterFile); } +} - template - void Load(Archive& ar, unsigned int /*uiVersion*/, bool bOnlyFlags) +template +void CFileInfoArray::Load(Archive& ar, unsigned int /*uiVersion*/, bool bOnlyFlags) +{ + size_t stCount; + ar >> stCount; + + if(!bOnlyFlags) { - size_t stCount; - ar >> stCount; + m_vFiles.clear(); + m_vFiles.reserve(stCount); + } + else if(stCount != m_vFiles.size()) + THROW(_T("Invalid count of flags received"), 0, 0, 0); - if(!bOnlyFlags) + CFileInfoPtr spFileInfo; + + uint_t uiFlags = 0; + for(size_t stIndex = 0; stIndex < stCount; stIndex++) + { + if(bOnlyFlags) { - m_vFiles.clear(); - m_vFiles.reserve(stCount); + CFileInfoPtr& spFileInfo = m_vFiles.at(stIndex); + ar >> uiFlags; + spFileInfo->SetFlags(uiFlags); } - else if(stCount != m_vFiles.size()) - THROW(_T("Invalid count of flags received"), 0, 0, 0); - - CFileInfoPtr spFileInfo; - - uint_t uiFlags = 0; - for(size_t stIndex = 0; stIndex < stCount; stIndex++) + else { - if(bOnlyFlags) - { - CFileInfoPtr& spFileInfo = m_vFiles.at(stIndex); - ar >> uiFlags; - spFileInfo->SetFlags(uiFlags); - } - else - { - spFileInfo.reset(new CFileInfo); - spFileInfo->SetClipboard(&m_rClipboard); - ar >> *spFileInfo; - m_vFiles.push_back(spFileInfo); - } + spFileInfo.reset(new CFileInfo); + spFileInfo->SetClipboard(&m_rClipboard); + ar >> *spFileInfo; + m_vFiles.push_back(spFileInfo); } } +} -protected: - CClipboardArray& m_rClipboard; - std::vector m_vFiles; - mutable boost::shared_mutex m_lock; -}; - #endif Index: src/ch/task.cpp =================================================================== diff -u -r1b2ffe919dbe75066f66267549f11eb128132e10 -r860b25a7b72cd40f83d810f7c72a5e2a76f88987 --- src/ch/task.cpp (.../task.cpp) (revision 1b2ffe919dbe75066f66267549f11eb128132e10) +++ src/ch/task.cpp (.../task.cpp) (revision 860b25a7b72cd40f83d810f7c72a5e2a76f88987) @@ -645,17 +645,13 @@ void CTask::CalculateProcessedSize() { - unsigned long long ullProcessedSize = 0; - - // count all from previous passes boost::shared_lock lock(m_lock); + CalculateProcessedSizeNL(); +} - for(size_t stIndex = 0; stIndex < m_stCurrentIndex; ++stIndex) - { - ullProcessedSize += m_files.GetAt(stIndex)->GetLength64(); - } - - m_localStats.SetProcessedSize(ullProcessedSize); +void CTask::CalculateProcessedSizeNL() +{ + m_localStats.SetProcessedSize(m_files.CalculatePartialSize(m_stCurrentIndex)); } // m_strUniqueName @@ -678,6 +674,8 @@ m_files.Load(ar, 0, false); + CalculateTotalSizeNL(); + ar >> m_dpDestPath; ar >> m_strUniqueName; @@ -690,26 +688,19 @@ ar >> stData; m_stCurrentIndex = stData; + + CalculateProcessedSizeNL(); + ar >> uiData; m_nStatus = uiData; ar >> m_bsSizes; ar >> m_nPriority; - // this info could be calculated on load (low cost) - unsigned long long ullTotalSize = 0; - ar >> ullTotalSize; - m_localStats.SetTotalSize(ullTotalSize); - time_t timeElapsed = 0; ar >> timeElapsed; m_localStats.SetTimeElapsed(timeElapsed); - // this info could be calculated on load (low cost) - unsigned long long ullProcessedSize = 0; - ar >> ullProcessedSize; - m_localStats.SetProcessedSize(ullProcessedSize); - m_clipboard.Load(ar, 0, bData); m_files.Load(ar, 0, true); @@ -764,15 +755,9 @@ ar << m_bsSizes; ar << m_nPriority; - unsigned long long ullTotalSize = m_localStats.GetTotalSize(); - ar << ullTotalSize; - time_t timeElapsed = m_localStats.GetTimeElapsed(); ar << timeElapsed; - unsigned long long ullProcessedSize = m_localStats.GetProcessedSize(); - ar << ullProcessedSize; - m_clipboard.Store(ar, 0, bData); if(GetStatusNL(ST_STEP_MASK) > ST_SEARCHING) m_files.Store(ar, 0, true); @@ -1187,9 +1172,9 @@ unsigned long long ullTotalSize = 0; size_t nSize = m_files.GetSize(); - for(size_t i = 0; i < nSize; i++) + for(size_t stIndex = 0; stIndex < nSize; stIndex++) { - ullTotalSize += m_files.GetAt(i)->GetLength64(); + ullTotalSize += m_files.GetAt(stIndex)->GetLength64(); } m_localStats.SetTotalSize(ullTotalSize); Index: src/ch/task.h =================================================================== diff -u -r1b2ffe919dbe75066f66267549f11eb128132e10 -r860b25a7b72cd40f83d810f7c72a5e2a76f88987 --- src/ch/task.h (.../task.h) (revision 1b2ffe919dbe75066f66267549f11eb128132e10) +++ src/ch/task.h (.../task.h) (revision 860b25a7b72cd40f83d810f7c72a5e2a76f88987) @@ -308,19 +308,12 @@ size_t GetClipboardDataSize(); int ReplaceClipboardStrings(CString strOld, CString strNew); - // m_files - int FilesAddDir(CString strDirName, size_t stSrcIndex, bool bRecurse, bool bIncludeDirs); - void FilesAdd(const CFileInfoPtr& spFileInfo); - CFileInfoPtr FilesGetAt(size_t stIndex); - CFileInfoPtr FilesGetAtCurrentIndex(); - void FilesRemoveAll(); - size_t FilesGetSize(); - // m_strDestPath void SetDestPath(LPCTSTR lpszPath); const CDestPath& GetDestPath(); - int GetDestDriveNumber(); + void SetFilters(const CFiltersArray* pFilters); + // m_nStatus void SetStatus(UINT nStatus, UINT nMask); UINT GetStatus(UINT nMask = 0xffffffff); @@ -352,8 +345,6 @@ void GetSnapshot(TASK_DISPLAY_DATA *pData); void GetMiniSnapshot(TASK_MINI_DISPLAY_DATA *pData); - void SetFilters(const CFiltersArray* pFilters); - CClipboardArray* GetClipboard() { return &m_clipboard; }; void SetTaskPath(const tchar_t* pszDir); @@ -367,24 +358,37 @@ size_t GetSessionUniqueID() const { return m_stSessionUniqueID; } protected: - /// Thread function that delegates call to the CTask::ThrdProc - static DWORD WINAPI DelegateThreadProc(LPVOID pParam); - /// Main function for the task processing thread - DWORD WINAPI ThrdProc(); - // methods are called when task is being added or removed from the global task array /// Method is called when this task is being added to a CTaskArray object void OnRegisterTask(TTasksGlobalStats& rtGlobalStats); /// Method is called when task is being removed from the CTaskArray object void OnUnregisterTask(); + /// Method is called when processing is being started void OnBeginOperation(); + /// Method is called when processing is being ended void OnEndOperation(); - void CheckForWaitState(); + // Processing operations + + /// Thread function that delegates call to the CTask::ThrdProc + static DWORD WINAPI DelegateThreadProc(LPVOID pParam); + + /// Main function for the task processing thread + DWORD WINAPI ThrdProc(); + void ProcessFiles(); void CustomCopyFile(CUSTOM_COPY_PARAMS* pData); + void DeleteFiles(); + void RecurseDirectories(); + + void CheckForWaitState(); + + // Helper filesystem methods + static bool SetFileDirectoryTime(LPCTSTR lpszName, const CFileInfoPtr& spFileInfo); + + // Playground /* void CustomCopyFile2(CUSTOM_COPY_PARAMS* / *pData* /); @@ -399,10 +403,15 @@ // End of playground - void DeleteFiles(); - void RecurseDirectories(); - static bool SetFileDirectoryTime(LPCTSTR lpszName, const CFileInfoPtr& spFileInfo); + // m_files + int FilesAddDir(CString strDirName, size_t stSrcIndex, bool bRecurse, bool bIncludeDirs); + void FilesAdd(const CFileInfoPtr& spFileInfo); + CFileInfoPtr FilesGetAt(size_t stIndex); + CFileInfoPtr FilesGetAtCurrentIndex(); + void FilesRemoveAll(); + size_t FilesGetSize(); + // m_stCurrentIndex void IncreaseCurrentIndex(); size_t GetCurrentIndex(); @@ -415,6 +424,7 @@ // m_strDestPath void SetDestPathNL(LPCTSTR lpszPath); const CDestPath& GetDestPathNL(); + int GetDestDriveNumber(); int GetDestDriveNumberNL(); // m_nStatus @@ -426,18 +436,18 @@ const BUFFERSIZES* GetBufferSizesNL(); int GetCurrentBufferIndexNL(); - // m_pThread // m_nPriority int GetPriorityNL(); void SetPriorityNL(int nPriority); + void CalculateProcessedSize(); + void CalculateProcessedSizeNL(); + void CalculateTotalSize(); void CalculateTotalSizeNL(); void DeleteProgress(LPCTSTR lpszDirectory); - void CalculateProcessedSize(); - void KillThread(); CString GetUniqueNameNL(); @@ -457,45 +467,50 @@ void RequestStopThread(); private: - // task initial information (needed to start a task); might be a bit processed. - CClipboardArray m_clipboard; // original paths with which we started operation - CDestPath m_dpDestPath; // destination path + // task initial information (needed to start a task); might be a bit processed. + CClipboardArray m_clipboard; // original paths with which we started operation + CDestPath m_dpDestPath; // destination path - // task settings - int m_nPriority; // task priority (really processing thread priority) + // task settings + int m_nPriority; // task priority (really processing thread priority) - CString m_strUniqueName; // name for the task (should be something like uuid) - CFiltersArray m_afFilters; // filtering settings for files (will be filtered according to the rules inside when searching for files) + CString m_strUniqueName; // name for the task (should be something like uuid) + CFiltersArray m_afFilters; // filtering settings for files (will be filtered according to the rules inside when searching for files) - BUFFERSIZES m_bsSizes; // sizes of buffers used to copy (derived from the global + BUFFERSIZES m_bsSizes; // sizes of buffers used to copy (derived from the global - // current task state (derivatives of the task initial information) - // changing slowly or only partially - CFileInfoArray m_files; // list of files/directories found during operating on the task input data (filled by search for files) + // current task state (derivatives of the task initial information) + // changing slowly or only partially + CFileInfoArray m_files; // list of files/directories found during operating on the task input data (filled by search for files) - // changing fast - volatile UINT m_nStatus; // what phase of the operation is this task in - volatile size_t m_stCurrentIndex; // index to the m_files array stating currently processed item + // changing fast + volatile UINT m_nStatus; // what phase of the operation is this task in - // task control variables (per-session state) - TTaskLocalStats m_localStats; // local statistics + volatile size_t m_stCurrentIndex; // index to the m_files array stating currently processed item - bool m_bForce; // if the continuation of tasks should be independent of limitation - bool m_bContinue; // used by ClipboardMonitorProc + // task control variables (per-session state) + TTaskLocalStats m_localStats; // local statistics - tstring_t m_strTaskBasePath; // base path at which the files will be stored - bool m_bSaved; // has the state been saved ('til next modification) + bool m_bForce; // if the continuation of tasks should be independent of max concurrently running task limit + bool m_bContinue; // allows task to continue - size_t m_stSessionUniqueID; + tstring_t m_strTaskBasePath; // base path at which the files will be stored + bool m_bSaved; // has the state been saved ('til next modification) - // other helpers - icpf::log_file m_log; - TWorkerThreadController m_workerThread; + size_t m_stSessionUniqueID; ///< Per-session unique ID for this task - mutable boost::shared_mutex m_lock; // protection for this class + // other helpers + icpf::log_file m_log; ///< Log file where task information will be stored - chcore::IFeedbackHandler* m_piFeedbackHandler; // feedback + /// Thread controlling object + TWorkerThreadController m_workerThread; + /// Mutex for locking concurrent access to members of this class + mutable boost::shared_mutex m_lock; + + /// Pointer to the feedback handler, providing responses to feedback requests + chcore::IFeedbackHandler* m_piFeedbackHandler; + friend class CTaskArray; };