diff options
author | Daniel Wilhelm <daniel@wili.li> | 2014-04-18 17:26:50 +0200 |
---|---|---|
committer | Daniel Wilhelm <daniel@wili.li> | 2014-04-18 17:26:50 +0200 |
commit | 669df123648aaa6aeccc70206b5417bc48b4e9ae (patch) | |
tree | 463c107a8d6405020bb304f7a7253e6b64afeee0 /lib | |
parent | 5.18 (diff) | |
download | FreeFileSync-669df123648aaa6aeccc70206b5417bc48b4e9ae.tar.gz FreeFileSync-669df123648aaa6aeccc70206b5417bc48b4e9ae.tar.bz2 FreeFileSync-669df123648aaa6aeccc70206b5417bc48b4e9ae.zip |
5.19
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ShadowCopy/Shadow_Server2003.vcxproj | 8 | ||||
-rw-r--r-- | lib/ShadowCopy/Shadow_Windows7.vcxproj | 8 | ||||
-rw-r--r-- | lib/ShadowCopy/Shadow_XP.vcxproj | 8 | ||||
-rw-r--r-- | lib/Thumbnail/Thumbnail.vcxproj | 8 | ||||
-rw-r--r-- | lib/db_file.cpp | 10 | ||||
-rw-r--r-- | lib/dir_exist_async.h | 2 | ||||
-rw-r--r-- | lib/dir_lock.cpp | 39 | ||||
-rw-r--r-- | lib/generate_logfile.h | 4 | ||||
-rw-r--r-- | lib/icon_buffer.cpp | 4 | ||||
-rw-r--r-- | lib/parallel_scan.cpp | 8 | ||||
-rw-r--r-- | lib/parse_lng.h | 7 | ||||
-rw-r--r-- | lib/perf_check.cpp | 76 | ||||
-rw-r--r-- | lib/perf_check.h | 30 | ||||
-rw-r--r-- | lib/process_xml.cpp | 45 | ||||
-rw-r--r-- | lib/process_xml.h | 10 | ||||
-rw-r--r-- | lib/resolve_path.cpp | 21 | ||||
-rw-r--r-- | lib/shadow.cpp | 11 | ||||
-rw-r--r-- | lib/status_handler.cpp | 11 | ||||
-rw-r--r-- | lib/status_handler.h | 15 | ||||
-rw-r--r-- | lib/versioning.cpp | 7 |
20 files changed, 162 insertions, 170 deletions
diff --git a/lib/ShadowCopy/Shadow_Server2003.vcxproj b/lib/ShadowCopy/Shadow_Server2003.vcxproj index 520a4d6d..a9b8f740 100644 --- a/lib/ShadowCopy/Shadow_Server2003.vcxproj +++ b/lib/ShadowCopy/Shadow_Server2003.vcxproj @@ -87,7 +87,7 @@ </BuildLog> <ClCompile> <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions> <MinimalRebuild>true</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> @@ -123,7 +123,7 @@ </Midl> <ClCompile> <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions> <MinimalRebuild>true</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> @@ -157,7 +157,7 @@ <ClCompile> <Optimization>MaxSpeed</Optimization> <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <FunctionLevelLinking>true</FunctionLevelLinking> <PrecompiledHeader> @@ -195,7 +195,7 @@ <ClCompile> <Optimization>MaxSpeed</Optimization> <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <FunctionLevelLinking>true</FunctionLevelLinking> <PrecompiledHeader> diff --git a/lib/ShadowCopy/Shadow_Windows7.vcxproj b/lib/ShadowCopy/Shadow_Windows7.vcxproj index 1fe769d0..7c6f1f1d 100644 --- a/lib/ShadowCopy/Shadow_Windows7.vcxproj +++ b/lib/ShadowCopy/Shadow_Windows7.vcxproj @@ -87,7 +87,7 @@ </BuildLog> <ClCompile> <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions> <MinimalRebuild>true</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> @@ -133,7 +133,7 @@ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions> <SmallerTypeCheck>true</SmallerTypeCheck> </ClCompile> <Link> @@ -157,7 +157,7 @@ <ClCompile> <Optimization>MaxSpeed</Optimization> <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <FunctionLevelLinking>true</FunctionLevelLinking> <PrecompiledHeader> @@ -205,7 +205,7 @@ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> - <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> diff --git a/lib/ShadowCopy/Shadow_XP.vcxproj b/lib/ShadowCopy/Shadow_XP.vcxproj index 0d231f3d..0d54f2e4 100644 --- a/lib/ShadowCopy/Shadow_XP.vcxproj +++ b/lib/ShadowCopy/Shadow_XP.vcxproj @@ -86,7 +86,7 @@ </BuildLog> <ClCompile> <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <MinimalRebuild>true</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> @@ -123,7 +123,7 @@ </Midl> <ClCompile> <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <MinimalRebuild>true</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> @@ -158,7 +158,7 @@ <ClCompile> <Optimization>MaxSpeed</Optimization> <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <FunctionLevelLinking>true</FunctionLevelLinking> <PrecompiledHeader> @@ -196,7 +196,7 @@ <ClCompile> <Optimization>MaxSpeed</Optimization> <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <FunctionLevelLinking>true</FunctionLevelLinking> <PrecompiledHeader> diff --git a/lib/Thumbnail/Thumbnail.vcxproj b/lib/Thumbnail/Thumbnail.vcxproj index 87fb152b..1ec016be 100644 --- a/lib/Thumbnail/Thumbnail.vcxproj +++ b/lib/Thumbnail/Thumbnail.vcxproj @@ -94,7 +94,7 @@ <WarningLevel>Level4</WarningLevel> <SuppressStartupBanner>true</SuppressStartupBanner> <DebugInformationFormat>EditAndContinue</DebugInformationFormat> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> + <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> <SmallerTypeCheck>true</SmallerTypeCheck> </ClCompile> @@ -129,7 +129,7 @@ <WarningLevel>Level4</WarningLevel> <SuppressStartupBanner>true</SuppressStartupBanner> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> + <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> <SmallerTypeCheck>true</SmallerTypeCheck> </ClCompile> @@ -161,7 +161,7 @@ <WarningLevel>Level4</WarningLevel> <SuppressStartupBanner>true</SuppressStartupBanner> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> + <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> </ClCompile> @@ -198,7 +198,7 @@ <WarningLevel>Level4</WarningLevel> <SuppressStartupBanner>true</SuppressStartupBanner> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> + <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> </ClCompile> diff --git a/lib/db_file.cpp b/lib/db_file.cpp index 2f699e3a..ab7f9212 100644 --- a/lib/db_file.cpp +++ b/lib/db_file.cpp @@ -91,7 +91,7 @@ StreamMapping loadStreams(const Zstring& filename) //throw FileError, FileErrorD { try { - BinStreamIn streamIn = loadBinStream<BinaryStream>(filename); //throw FileError, ErrorNotExisting + BinStreamIn streamIn = loadBinStream<BinaryStream>(filename); //throw FileError //read FreeFileSync file identifier char formatDescr[sizeof(FILE_FORMAT_DESCR)] = {}; @@ -118,10 +118,12 @@ StreamMapping loadStreams(const Zstring& filename) //throw FileError, FileErrorD } return output; } - catch (ErrorNotExisting&) + catch (FileError&) { - throw FileErrorDatabaseNotExisting(_("Initial synchronization:") + L" \n" + - replaceCpy(_("Database file %x does not yet exist."), L"%x", fmtFileName(filename))); + if (!somethingExists(filename)) //a benign(?) race condition with FileError + throw FileErrorDatabaseNotExisting(_("Initial synchronization:") + L" \n" + + replaceCpy(_("Database file %x does not yet exist."), L"%x", fmtFileName(filename))); + throw; } catch (UnexpectedEndOfStreamError&) { diff --git a/lib/dir_exist_async.h b/lib/dir_exist_async.h index dd77a36a..39ae6aff 100644 --- a/lib/dir_exist_async.h +++ b/lib/dir_exist_async.h @@ -47,7 +47,7 @@ std::set<Zstring, LessFilename> getExistingDirsUpdating(const std::set<Zstring, const boost::system_time endTime = boost::get_system_time() + boost::posix_time::seconds(10); //10 sec should be enough even if Win32 waits much longer auto itDirname = dirnames.begin(); - for (auto it = dirEx.begin(); it != dirEx.end(); ++it, ++itDirname) + for (auto it = dirEx.begin(); it != dirEx.end(); (void)++it, ++itDirname) //void: prevent ADL from dragging in boost's ,-overload: "MSVC warning C4913: user defined binary operator ',' exists but no overload could convert all operands" { procCallback.reportStatus(replaceCpy(_("Searching for folder %x..."), L"%x", fmtFileName(*itDirname), false)); //may throw! diff --git a/lib/dir_lock.cpp b/lib/dir_lock.cpp index 60d83a67..d7e3ba56 100644 --- a/lib/dir_lock.cpp +++ b/lib/dir_lock.cpp @@ -68,7 +68,7 @@ public: } catch (const std::exception& e) //exceptions must be catched per thread { - wxSafeShowMessage(_("An exception occurred"), utfCvrtTo<wxString>(e.what()) + L" (Dirlock)"); //simple wxMessageBox won't do for threads + wxSafeShowMessage(L"FreeFileSync - " + _("An exception occurred"), utfCvrtTo<wxString>(e.what()) + L" (Dirlock)"); //simple wxMessageBox won't do for threads } } @@ -123,7 +123,7 @@ private: namespace { -UInt64 getLockFileSize(const Zstring& filename) //throw FileError, ErrorNotExisting +UInt64 getLockFileSize(const Zstring& filename) //throw FileError { #ifdef ZEN_WIN WIN32_FIND_DATA fileInfo = {}; @@ -144,11 +144,7 @@ UInt64 getLockFileSize(const Zstring& filename) //throw FileError, ErrorNotExist const ErrorCode lastError = getLastError(); const std::wstring errorMsg = replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(filename)); const std::wstring errorDescr = formatSystemError(functionName, lastError); - - if (errorCodeForNotExisting(lastError)) - throw ErrorNotExisting(errorMsg, errorDescr); - else - throw FileError(errorMsg, errorDescr); + throw FileError(errorMsg, errorDescr); } @@ -359,9 +355,9 @@ struct LockInformation //throw FileError //wxGetFullHostName() is a performance killer for some users, so don't touch! -LockInformation retrieveLockInfo(const Zstring& lockfilename) //throw FileError, ErrorNotExisting +LockInformation retrieveLockInfo(const Zstring& lockfilename) //throw FileError { - BinStreamIn streamIn = loadBinStream<BinaryStream>(lockfilename); //throw FileError, ErrorNotExisting + BinStreamIn streamIn = loadBinStream<BinaryStream>(lockfilename); //throw FileError try { return LockInformation(streamIn); //throw UnexpectedEndOfStreamError @@ -374,9 +370,9 @@ LockInformation retrieveLockInfo(const Zstring& lockfilename) //throw FileError, inline -std::string retrieveLockId(const Zstring& lockfilename) //throw FileError, ErrorNotExisting +std::string retrieveLockId(const Zstring& lockfilename) //throw FileError { - return retrieveLockInfo(lockfilename).lockId; + return retrieveLockInfo(lockfilename).lockId; //throw FileError } @@ -408,6 +404,7 @@ ProcessStatus getProcessStatus(const LockInformation& lockInfo) //throw FileErro const std::int64_t TICKS_PER_SEC = ticksPerSec(); //= 0 on error + void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //throw FileError { const std::wstring infoMsg = replaceCpy(_("Waiting while directory is locked (%x)..."), L"%x", fmtFileName(lockfilename)); @@ -422,7 +419,7 @@ void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //thr std::string originalLockId; //empty if it cannot be retrieved try { - const LockInformation& lockInfo = retrieveLockInfo(lockfilename); //throw FileError, ErrorNotExisting + const LockInformation& lockInfo = retrieveLockInfo(lockfilename); //throw FileError originalLockId = lockInfo.lockId; switch (getProcessStatus(lockInfo)) //throw FileError { @@ -443,7 +440,7 @@ void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //thr while (true) { const TickVal now = getTicks(); - const UInt64 fileSizeNew = ::getLockFileSize(lockfilename); //throw FileError, ErrorNotExisting + const UInt64 fileSizeNew = ::getLockFileSize(lockfilename); //throw FileError if (TICKS_PER_SEC <= 0 || !lastLifeSign.isValid() || !now.isValid()) throw FileError(L"System Timer failed!"); //no i18n: "should" never throw ;) @@ -462,10 +459,10 @@ void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //thr //now that the lock is in place check existence again: meanwhile another process may have deleted and created a new lock! if (!originalLockId.empty()) - if (retrieveLockId(lockfilename) != originalLockId) //throw FileError, ErrorNotExisting -> since originalLockId is filled, we are not expecting errors! + if (retrieveLockId(lockfilename) != originalLockId) //throw FileError -> since originalLockId is filled, we are not expecting errors! return; //another process has placed a new lock, leave scope: the wait for the old lock is technically over... - if (::getLockFileSize(lockfilename) != fileSizeOld) //throw FileError, ErrorNotExisting + if (::getLockFileSize(lockfilename) != fileSizeOld) //throw FileError continue; //late life sign removeFile(lockfilename); //throw FileError @@ -494,9 +491,11 @@ void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //thr } } } - catch (const ErrorNotExisting&) + catch (FileError&) { - return; //what we are waiting for... + if (!somethingExists(lockfilename)) //a benign(?) race condition with FileError + return; //what we are waiting for... + throw; } } @@ -582,7 +581,7 @@ public: ~SharedDirLock() { threadObj.interrupt(); //thread lifetime is subset of this instances's life - threadObj.join(); //we assume precondition "threadObj.joinable()"!!! + threadObj.join(); //we assert precondition "threadObj.joinable()"!!! ::releaseLock(lockfilename_); //throw () } @@ -618,7 +617,7 @@ public: try //check based on lock GUID, deadlock prevention: "lockfilename" may be an alternative name for a lock already owned by this process { - const std::string lockId = retrieveLockId(lockfilename); //throw FileError, ErrorNotExisting + const std::string lockId = retrieveLockId(lockfilename); //throw FileError if (const std::shared_ptr<SharedDirLock>& activeLock = getActiveLock(lockId)) //returns null-lock if not found { fileToGuid[lockfilename] = lockId; //found an alias for one of our active locks @@ -629,7 +628,7 @@ public: //lock not owned by us => create a new one auto newLock = std::make_shared<SharedDirLock>(lockfilename, callback); //throw FileError - const std::string& newLockGuid = retrieveLockId(lockfilename); //throw FileError, ErrorNotExisting + const std::string& newLockGuid = retrieveLockId(lockfilename); //throw FileError //update registry fileToGuid[lockfilename] = newLockGuid; //throw() diff --git a/lib/generate_logfile.h b/lib/generate_logfile.h index 31f7bd43..ff97b63a 100644 --- a/lib/generate_logfile.h +++ b/lib/generate_logfile.h @@ -147,9 +147,9 @@ void saveToLastSyncsLog(const SummaryInfo& summary, //throw FileError Utf8String oldStream; try { - oldStream = loadBinStream<Utf8String>(filename); //throw FileError, ErrorNotExisting + oldStream = loadBinStream<Utf8String>(filename); //throw FileError } - catch (const ErrorNotExisting&) {} + catch (FileError&) {} if (!oldStream.empty()) { diff --git a/lib/icon_buffer.cpp b/lib/icon_buffer.cpp index cf916174..b0874d83 100644 --- a/lib/icon_buffer.cpp +++ b/lib/icon_buffer.cpp @@ -426,7 +426,7 @@ public: { assert(boost::this_thread::get_id() == mainThreadId ); { - boost::unique_lock<boost::mutex> dummy(lockFiles); + boost::lock_guard<boost::mutex> dummy(lockFiles); filesToLoad = newLoad; } conditionNewFiles.notify_all(); //instead of notify_one(); workaround bug: https://svn.boost.org/trac/boost/ticket/7796 @@ -437,7 +437,7 @@ public: { assert(boost::this_thread::get_id() == mainThreadId ); { - boost::unique_lock<boost::mutex> dummy(lockFiles); + boost::lock_guard<boost::mutex> dummy(lockFiles); filesToLoad.push_back(newEntry); //set as next item to retrieve } conditionNewFiles.notify_all(); diff --git a/lib/parallel_scan.cpp b/lib/parallel_scan.cpp index df8ff095..2bac5690 100644 --- a/lib/parallel_scan.cpp +++ b/lib/parallel_scan.cpp @@ -180,7 +180,7 @@ public: errorMsg.clear(); errorResponse.reset(); - dummy.unlock(); //optimization for condition_variable::notify_one() + dummy.unlock(); //optimization for condition_variable::notify_all() conditionCanReportError.notify_all(); //instead of notify_one(); workaround bug: https://svn.boost.org/trac/boost/ticket/7796 return rv; @@ -194,7 +194,7 @@ public: FillBufferCallback::HandleError rv = callback.reportError(copyStringTo<std::wstring>(errorMsg)); //throw! errorResponse = make_unique<FillBufferCallback::HandleError>(rv); - dummy.unlock(); //optimization for condition_variable::notify_one() + dummy.unlock(); //optimization for condition_variable::notify_all() conditionGotResponse.notify_all(); //instead of notify_one(); workaround bug: https://svn.boost.org/trac/boost/ticket/7796 } } @@ -236,7 +236,7 @@ public: std::wstring statusText = copyStringTo<std::wstring>(textScanning); const long activeCount = activeWorker; if (activeCount >= 2) - statusText += L" " + replaceCpy(_P("[1 Thread]", "[%x Threads]", activeCount), L"%x", numberTo<std::wstring>(activeCount)); + statusText += L" [" + replaceCpy(_P("1 thread", "%x threads", activeCount), L"%x", numberTo<std::wstring>(activeCount)) + L"]"; statusText += L" " + fmtFileName(filename); return statusText; @@ -273,8 +273,8 @@ private: boost::detail::atomic_count itemsScanned; boost::detail::atomic_count activeWorker; }; -//------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------------- struct TraverserShared { diff --git a/lib/parse_lng.h b/lib/parse_lng.h index 8cd8e943..be47b66b 100644 --- a/lib/parse_lng.h +++ b/lib/parse_lng.h @@ -294,7 +294,7 @@ private: static void normalize(std::string& text) { - zen::trim(text); //remmove whitespace from end + zen::trim(text); //remove whitespace from both ends //Delimiter: //---------- @@ -378,8 +378,11 @@ private: if (token().type == Token::TK_PLURAL_BEGIN) return parsePlural(pluralOut, pluralInfo); + if (token().type != Token::TK_TEXT) + throw ParsingError(L"Source text empty", scn.posRow(), scn.posCol()); std::string original = tk.text; - consumeToken(Token::TK_TEXT); + nextToken(); + consumeToken(Token::TK_SRC_END); consumeToken(Token::TK_TRG_BEGIN); diff --git a/lib/perf_check.cpp b/lib/perf_check.cpp index 33361201..0f5506b3 100644 --- a/lib/perf_check.cpp +++ b/lib/perf_check.cpp @@ -16,10 +16,10 @@ using namespace zen; PerfCheck::PerfCheck(unsigned int windowSizeRemainingTime, - unsigned int windowSizeBytesPerSecond) : + unsigned int windowSizeSpeed) : windowSizeRemTime(windowSizeRemainingTime), - windowSizeBPS(windowSizeBytesPerSecond), - windowMax(std::max(windowSizeRemainingTime, windowSizeBytesPerSecond)) {} + windowSizeSpeed_(windowSizeSpeed), + windowMax(std::max(windowSizeRemainingTime, windowSizeSpeed)) {} PerfCheck::~PerfCheck() @@ -43,9 +43,9 @@ PerfCheck::~PerfCheck() } -void PerfCheck::addSample(int objectsCurrent, double dataCurrent, long timeMs) +void PerfCheck::addSample(int itemsCurrent, double dataCurrent, long timeMs) { - samples.insert(samples.end(), std::make_pair(timeMs, Record(objectsCurrent, dataCurrent))); //use fact that time is monotonously ascending + samples.insert(samples.end(), std::make_pair(timeMs, Record(itemsCurrent, dataCurrent))); //use fact that time is monotonously ascending //remove all records earlier than "now - windowMax" const long newBegin = timeMs - windowMax; @@ -55,20 +55,32 @@ void PerfCheck::addSample(int objectsCurrent, double dataCurrent, long timeMs) } -std::wstring PerfCheck::getRemainingTime(double dataRemaining) const +inline +std::pair<const std::multimap<long, PerfCheck::Record>::value_type*, const std::multimap<long, PerfCheck::Record>::value_type*> PerfCheck::getBlockFromEnd(long windowSize) const { if (!samples.empty()) { - const auto& recordBack = *samples.rbegin(); + auto itBack = samples.rbegin(); //find start of records "window" - auto itFront = samples.upper_bound(recordBack.first - windowSizeRemTime); + auto itFront = samples.upper_bound(itBack->first - windowSize); if (itFront != samples.begin()) --itFront; //one point before window begin in order to handle "measurement holes" + return std::make_pair(&*itFront, &*itBack); + } + return std::make_pair(nullptr, nullptr); +} - const auto& recordFront = *itFront; + +zen::Opt<std::wstring> PerfCheck::getRemainingTime(double dataRemaining) const +{ + auto blk = getBlockFromEnd(windowSizeRemTime); + if (blk.first && blk.second) + { + const auto& itemFront = *blk.first; + const auto& itemBack = *blk.second; //----------------------------------------------------------------------------------------------- - const long timeDelta = recordBack.first - recordFront.first; - const double dataDelta = recordBack.second.data_ - recordFront.second.data_; + const long timeDelta = itemBack.first - itemFront.first; + const double dataDelta = itemBack.second.data_ - itemFront.second.data_; //objects model logical operations *NOT* disk accesses, so we better play safe and use "bytes" only! //http://sourceforge.net/p/freefilesync/feature-requests/197/ @@ -76,29 +88,43 @@ std::wstring PerfCheck::getRemainingTime(double dataRemaining) const if (!numeric::isNull(dataDelta)) //sign(dataRemaining) != sign(dataDelta) usually an error, so show it! return remainingTimeToString(dataRemaining * timeDelta / (1000.0 * dataDelta)); } - return L"-"; //fallback + return NoValue(); } -std::wstring PerfCheck::getBytesPerSecond() const +zen::Opt<std::wstring> PerfCheck::getBytesPerSecond() const { - if (!samples.empty()) + auto blk = getBlockFromEnd(windowSizeSpeed_); + if (blk.first && blk.second) { - const auto& recordBack = *samples.rbegin(); - //find start of records "window" - auto itFront = samples.upper_bound(recordBack.first - windowSizeBPS); - if (itFront != samples.begin()) - --itFront; //one point before window begin in order to handle "measurement holes" + const auto& itemFront = *blk.first; + const auto& itemBack = *blk.second; + //----------------------------------------------------------------------------------------------- + const long timeDelta = itemBack.first - itemFront.first; + const double dataDelta = itemBack.second.data_ - itemFront.second.data_; + + if (timeDelta != 0/* && dataDelta > 0*/) + return filesizeToShortString(zen::Int64(dataDelta * 1000.0 / timeDelta)) + _("/sec"); + } + return NoValue(); +} + - const auto& recordFront = *itFront; +zen::Opt<std::wstring> PerfCheck::getItemsPerSecond() const +{ + auto blk = getBlockFromEnd(windowSizeSpeed_); + if (blk.first && blk.second) + { + const auto& itemFront = *blk.first; + const auto& itemBack = *blk.second; //----------------------------------------------------------------------------------------------- - const long timeDelta = recordBack.first - recordFront.first; - const double dataDelta = recordBack.second.data_ - recordFront.second.data_; + const long timeDelta = itemBack.first - itemFront.first; + const int itemsDelta = itemBack.second.itemCount_ - itemFront.second.itemCount_; - if (timeDelta != 0 && dataDelta > 0) - return filesizeToShortString(zen::Int64(dataDelta * 1000 / timeDelta)) + _("/sec"); + if (timeDelta != 0) + return replaceCpy(_("%x items"), L"%x", formatThreeDigitPrecision(itemsDelta * 1000.0 / timeDelta)) + _("/sec"); } - return L"-"; //fallback + return NoValue(); } diff --git a/lib/perf_check.h b/lib/perf_check.h index 3e04b778..9d82be57 100644 --- a/lib/perf_check.h +++ b/lib/perf_check.h @@ -9,31 +9,37 @@ #include <map> #include <string> +#include <zen/optional.h> class PerfCheck { public: - PerfCheck(unsigned int windowSizeRemainingTime, //unit: [ms] - unsigned int windowSizeBytesPerSecond); // + PerfCheck(unsigned int windowSizeRemainingTime, //unit: [ms] + unsigned int windowSizeSpeed); // ~PerfCheck(); - void addSample(int objectsCurrent, double dataCurrent, long timeMs); //timeMs must be ascending! + void addSample(int itemsCurrent, double dataCurrent, long timeMs); //timeMs must be ascending! - std::wstring getRemainingTime(double dataRemaining) const; - std::wstring getBytesPerSecond() const; //for window + zen::Opt<std::wstring> getRemainingTime(double dataRemaining) const; + zen::Opt<std::wstring> getBytesPerSecond() const; //for window + zen::Opt<std::wstring> getItemsPerSecond() const; //for window private: - const long windowSizeRemTime; //unit: [ms] - const long windowSizeBPS; // - const long windowMax; - struct Record { - Record(int objCount, double data) : objCount_(objCount), data_(data) {} - int objCount_; + Record(int itemCount, double data) : itemCount_(itemCount), data_(data) {} + int itemCount_; double data_; //unit: [bytes] }; - std::multimap<long, Record> samples; //time, unit: [ms] + + std::pair<const std::multimap<long, Record>::value_type*, + const std::multimap<long, Record>::value_type*> getBlockFromEnd(long windowSize) const; + + const long windowSizeRemTime; //unit: [ms] + const long windowSizeSpeed_; // + const long windowMax; + + std::map<long, Record> samples; //time, unit: [ms] }; #endif // STATISTICS_H_INCLUDED diff --git a/lib/process_xml.cpp b/lib/process_xml.cpp index 2422b2ef..49e4c711 100644 --- a/lib/process_xml.cpp +++ b/lib/process_xml.cpp @@ -99,6 +99,7 @@ void xmlAccess::OptionalDialogs::resetDialogs() warningDirectoryLockFailed = true; popupOnConfigChange = true; confirmSyncStart = true; + confirmExternalCommandMassInvoke = true; } @@ -157,36 +158,6 @@ xmlAccess::XmlBatchConfig xmlAccess::convertGuiToBatchPreservingExistingBatch(co } -xmlAccess::MergeType xmlAccess::getMergeType(const std::vector<Zstring>& filenames) //throw() -{ - bool guiCfgExists = false; - bool batchCfgExists = false; - - for (auto it = filenames.begin(); it != filenames.end(); ++it) - { - switch (xmlAccess::getXmlType(*it)) //throw() - { - case XML_TYPE_GUI: - guiCfgExists = true; - break; - - case XML_TYPE_BATCH: - batchCfgExists = true; - break; - - case XML_TYPE_GLOBAL: - case XML_TYPE_OTHER: - return MERGE_OTHER; - } - } - - if (guiCfgExists) - return batchCfgExists ? MERGE_GUI_BATCH : MERGE_GUI; - else - return batchCfgExists ? MERGE_BATCH : MERGE_OTHER; -} - - namespace { std::vector<Zstring> splitFilterByLines(const Zstring& filterPhrase) @@ -243,13 +214,13 @@ void writeText(const SyncDirection& value, std::string& output) { switch (value) { - case SYNC_DIR_LEFT: + case SyncDirection::LEFT: output = "left"; break; - case SYNC_DIR_RIGHT: + case SyncDirection::RIGHT: output = "right"; break; - case SYNC_DIR_NONE: + case SyncDirection::NONE: output = "none"; break; } @@ -261,11 +232,11 @@ bool readText(const std::string& input, SyncDirection& value) std::string tmp = input; zen::trim(tmp); if (tmp == "left") - value = SYNC_DIR_LEFT; + value = SyncDirection::LEFT; else if (tmp == "right") - value = SYNC_DIR_RIGHT; + value = SyncDirection::RIGHT; else if (tmp == "none") - value = SYNC_DIR_NONE; + value = SyncDirection::NONE; else return false; return true; @@ -1037,6 +1008,7 @@ void readConfig(const XmlIn& in, XmlGlobalSettings& config) inOpt["WarnDirectoryLockFailed" ].attribute("Enabled", config.optDialogs.warningDirectoryLockFailed); inOpt["ConfirmSaveConfig" ].attribute("Enabled", config.optDialogs.popupOnConfigChange); inOpt["ConfirmStartSync" ].attribute("Enabled", config.optDialogs.confirmSyncStart); + inOpt["ConfirmExternalCommandMassInvoke"].attribute("Enabled", config.optDialogs.confirmExternalCommandMassInvoke); //gui specific global settings (optional) XmlIn inGui = in["Gui"]; @@ -1415,6 +1387,7 @@ void writeConfig(const XmlGlobalSettings& config, XmlOut& out) outOpt["WarnDirectoryLockFailed" ].attribute("Enabled", config.optDialogs.warningDirectoryLockFailed); outOpt["ConfirmSaveConfig" ].attribute("Enabled", config.optDialogs.popupOnConfigChange); outOpt["ConfirmStartSync" ].attribute("Enabled", config.optDialogs.confirmSyncStart); + outOpt["ConfirmExternalCommandMassInvoke"].attribute("Enabled", config.optDialogs.confirmExternalCommandMassInvoke); //gui specific global settings (optional) XmlOut outGui = out["Gui"]; diff --git a/lib/process_xml.h b/lib/process_xml.h index 95fa644d..b189e51f 100644 --- a/lib/process_xml.h +++ b/lib/process_xml.h @@ -103,6 +103,7 @@ struct OptionalDialogs bool warningDirectoryLockFailed; bool popupOnConfigChange; bool confirmSyncStart; + bool confirmExternalCommandMassInvoke; }; @@ -278,15 +279,6 @@ void writeConfig(const XmlBatchConfig& config, const Zstring& filename); //th void writeConfig(const XmlGlobalSettings& config); // //convert (multiple) *.ffs_gui, *.ffs_batch files or combinations of both into target config structure: -enum MergeType -{ - MERGE_GUI, //pure gui config files - MERGE_BATCH, // " batch " - MERGE_GUI_BATCH, //gui and batch files - MERGE_OTHER -}; -MergeType getMergeType(const std::vector<Zstring>& filenames); //noexcept - void readAnyConfig(const std::vector<Zstring>& filenames, XmlGuiConfig& config); //throw FfsXmlError //config conversion utilities diff --git a/lib/resolve_path.cpp b/lib/resolve_path.cpp index 035e1d77..daa99d2a 100644 --- a/lib/resolve_path.cpp +++ b/lib/resolve_path.cpp @@ -620,20 +620,28 @@ void zen::loginNetworkShare(const Zstring& dirnameOrig, bool allowUserInteractio nullptr, // __in LPCTSTR lpPassword, nullptr, // __in LPCTSTR lpUsername, 0); //__in DWORD dwFlags + //53L ERROR_BAD_NETPATH The network path was not found. + //86L ERROR_INVALID_PASSWORD + //1219L ERROR_SESSION_CREDENTIAL_CONFLICT Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. Disconnect all previous connections to the server or shared resource and try again. + //1326L ERROR_LOGON_FAILURE Logon failure: unknown user name or bad password. + //1236L ERROR_CONNECTION_ABORTED if (somethingExists(trgRes.lpRemoteName)) //blocks! return; //success: connection usable! -> don't care about "rv" if (rv == ERROR_BAD_NETPATH || //Windows 7 - rv == ERROR_BAD_NET_NAME) //XP + rv == ERROR_BAD_NET_NAME|| //XP + rv == ERROR_CONNECTION_ABORTED) //failed to connect to a network that existed not too long ago; will later return ERROR_BAD_NETPATH return; //no need to show a prompt for an unreachable network device //2. if first attempt failed, we need to *force* prompt by using CONNECT_PROMPT if (allowUserInteraction) { //avoid problem II.) - DWORD rv2= WNetCancelConnection2(trgRes.lpRemoteName, //_In_ LPCTSTR lpName, - 0, //_In_ DWORD dwFlags, - true); //_In_ BOOL fForce + DWORD rv2= ::WNetCancelConnection2(trgRes.lpRemoteName, //_In_ LPCTSTR lpName, + 0, //_In_ DWORD dwFlags, + true); //_In_ BOOL fForce + //2250L ERROR_NOT_CONNECTED + //enforce login prompt DWORD rv3 = ::WNetAddConnection2(&trgRes, // __in LPNETRESOURCE lpNetResource, nullptr, // __in LPCTSTR lpPassword, @@ -641,11 +649,6 @@ void zen::loginNetworkShare(const Zstring& dirnameOrig, bool allowUserInteractio CONNECT_INTERACTIVE | CONNECT_PROMPT); //__in DWORD dwFlags (void)rv2; (void)rv3; - //Sample error codes: - //53L ERROR_BAD_NETPATH The network path was not found. - //86L ERROR_INVALID_PASSWORD - //1219L ERROR_SESSION_CREDENTIAL_CONFLICT Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. Disconnect all previous connections to the server or shared resource and try again. - //1326L ERROR_LOGON_FAILURE Logon failure: unknown user name or bad password. } }; diff --git a/lib/shadow.cpp b/lib/shadow.cpp index 1161646e..71372270 100644 --- a/lib/shadow.cpp +++ b/lib/shadow.cpp @@ -111,14 +111,11 @@ Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile, const std::function const Zstring volumeNamePf = appendSeparator(&volBuffer[0]); //msdn: if buffer is 1 char too short, GetVolumePathName() may skip last separator without error! //input file is always absolute! directory formatting takes care of this! Therefore volume name can always be found. - const size_t pos = filenameFinal.find(volumeNamePf); //filenameFinal needs NOT to begin with volumeNamePf: consider for example \\?\ prefix! + const size_t pos = filenameFinal.find(volumeNamePf); //filenameFinal needs NOT to begin with volumeNamePf: consider \\?\ prefix! if (pos == Zstring::npos) - { - std::wstring msg = _("Volume name %x not part of file name %y."); - replace(msg, L"%x", fmtFileName(volumeNamePf), false); - replace(msg, L"%y", fmtFileName(filenameFinal), false); - throw FileError(msg); - } + throw FileError(replaceCpy(replaceCpy(_("Volume name %x is not part of file path %y."), + L"%x", fmtFileName(volumeNamePf)), + L"%y", fmtFileName(filenameFinal))); //get or create instance of shadow volume VolNameShadowMap::const_iterator it = shadowVol.find(volumeNamePf); diff --git a/lib/status_handler.cpp b/lib/status_handler.cpp index c24c6f50..5fb80161 100644 --- a/lib/status_handler.cpp +++ b/lib/status_handler.cpp @@ -5,21 +5,12 @@ // ************************************************************************** #include "status_handler.h" -#include <wx/app.h> +//#include <wx/app.h> #include <zen/tick_count.h> using namespace zen; -void zen::updateUiNow() -{ - //process UI events and prevent application from "not responding" -> NO performance issue! - wxTheApp->Yield(); - - // while (wxTheApp->Pending()) - // wxTheApp->Dispatch(); -} - namespace { const std::int64_t TICKS_UPDATE_INTERVAL = UI_UPDATE_INTERVAL* ticksPerSec() / 1000; diff --git a/lib/status_handler.h b/lib/status_handler.h index ed496824..c19935b1 100644 --- a/lib/status_handler.h +++ b/lib/status_handler.h @@ -16,13 +16,12 @@ namespace zen { bool updateUiIsAllowed(); //test if a specific amount of time is over -void updateUiNow(); //do the updating /* Updating GUI is fast! time per single call to ProcessCallback::forceUiRefresh() - - Comparison 25 µs - - Synchronization 0.6 ms (despite complex graph control!) + - Comparison 0.025 ms + - Synchronization 0.74 ms (despite complex graph control!) */ //gui may want to abort process @@ -72,11 +71,13 @@ protected: virtual void requestUiRefresh() { - if (updateUiIsAllowed()) //test if specific time span between ui updates is over + if (abortRequested) //triggered by requestAbortion() + { + forceUiRefresh(); + abortThisProcess(); + } + else if (updateUiIsAllowed()) //test if specific time span between ui updates is over forceUiRefresh(); - - if (abortRequested) //check *after* GUI update, to have up-to-date screen - abortThisProcess(); //triggered by requestAbortion() } virtual void reportStatus(const std::wstring& text) { statusText_ = text; requestUiRefresh(); /*throw AbortThisProcess */ } diff --git a/lib/versioning.cpp b/lib/versioning.cpp index 1bf5a65e..a6458196 100644 --- a/lib/versioning.cpp +++ b/lib/versioning.cpp @@ -129,15 +129,14 @@ void moveObject(const Zstring& sourceFile, //throw FileError { assert(!dirExists(sourceFile) || symlinkExists(sourceFile)); //we process files and symlinks only - auto removeTarget = [&]() + auto removeTarget = [&] { //remove target object if (fileExists(targetFile)) //file or symlink removeFile(targetFile); //throw FileError else if (dirExists(targetFile)) //directory or symlink - removeDirectory(targetFile); //throw FileError - //we do not expect targetFile to be a directory in general => no callback required - else assert(false); + removeDirectory(targetFile); //throw FileError; we do not expect targetFile to be a directory in general => no callback required + //else assert(false); -> may simply not exist if ErrorDifferentVolume! }; //first try to move directly without copying |