From 57d0e556d83021b17ffe3a61544f63ae2d73b3eb Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Sun, 30 Jun 2013 03:25:20 -0700 Subject: [PATCH] Fix File::nonexistent false leak using SharedSingleton --- modules/beast_core/files/beast_File.cpp | 35 +++++++++++++++---- modules/beast_core/files/beast_File.h | 4 +-- .../beast_core/files/beast_TemporaryFile.cpp | 4 +-- .../beast_core/native/beast_android_Files.cpp | 2 +- modules/beast_core/native/beast_bsd_Files.cpp | 2 +- .../beast_core/native/beast_linux_Files.cpp | 2 +- modules/beast_core/native/beast_mac_Files.mm | 2 +- .../beast_core/native/beast_win32_Files.cpp | 4 +-- .../time/beast_PerformanceCounter.cpp | 4 +-- .../time/beast_PerformanceCounter.h | 7 ++-- 10 files changed, 45 insertions(+), 21 deletions(-) diff --git a/modules/beast_core/files/beast_File.cpp b/modules/beast_core/files/beast_File.cpp index 7fa1e889a..6c0706ed0 100644 --- a/modules/beast_core/files/beast_File.cpp +++ b/modules/beast_core/files/beast_File.cpp @@ -21,6 +21,32 @@ */ //============================================================================== +// We need to make a shared singleton or else there are +// issues with the leak detector and order of detruction. +// +class NonexistentHolder : public SharedSingleton +{ +public: + NonexistentHolder () + : SharedSingleton (SingletonLifetime::persistAfterCreation) + { + } + + static NonexistentHolder* createInstance () + { + return new NonexistentHolder; + } + + File const file; +}; + +File const& File::nonexistent () +{ + return NonexistentHolder::getInstance ()->file; +} + +//------------------------------------------------------------------------------ + File::File (const String& fullPathName) : fullPath (parseAbsolutePath (fullPathName)) { @@ -67,9 +93,6 @@ File& File::operator= (File&& other) noexcept } #endif -const File File::nonexistent; - - //============================================================================== String File::parseAbsolutePath (const String& p) { @@ -321,7 +344,7 @@ String File::getFileNameWithoutExtension() const bool File::isAChildOf (const File& potentialParent) const { - if (potentialParent == File::nonexistent) + if (potentialParent == File::nonexistent ()) return false; const String ourPath (getPathUpToLastSlash()); @@ -633,7 +656,7 @@ bool File::hasFileExtension (const String& possibleSuffix) const File File::withFileExtension (const String& newExtension) const { if (fullPath.isEmpty()) - return File::nonexistent; + return File::nonexistent (); String filePart (getFileName()); @@ -914,7 +937,7 @@ public: const File home (File::getSpecialLocation (File::userHomeDirectory)); const File temp (File::getSpecialLocation (File::tempDirectory)); - expect (! File::nonexistent.exists()); + expect (! File::nonexistent ().exists()); expect (home.isDirectory()); expect (home.exists()); expect (! home.existsAsFile()); diff --git a/modules/beast_core/files/beast_File.h b/modules/beast_core/files/beast_File.h index 839ae0b62..96444f8e2 100644 --- a/modules/beast_core/files/beast_File.h +++ b/modules/beast_core/files/beast_File.h @@ -53,7 +53,7 @@ public: /** Creates an (invalid) file object. The file is initially set to an empty path, so getFullPath() will return - an empty string, and comparing the file to File::nonexistent will return + an empty string, and comparing the file to File::nonexistent() will return true. You can use its operator= method to point it at a proper file. @@ -100,7 +100,7 @@ public: //============================================================================== /** This static constant is used for referring to an 'invalid' file. */ - static const File nonexistent; + static File const& nonexistent (); //============================================================================== /** Checks whether the file actually exists. diff --git a/modules/beast_core/files/beast_TemporaryFile.cpp b/modules/beast_core/files/beast_TemporaryFile.cpp index 561d2c16c..e5603da72 100644 --- a/modules/beast_core/files/beast_TemporaryFile.cpp +++ b/modules/beast_core/files/beast_TemporaryFile.cpp @@ -45,7 +45,7 @@ TemporaryFile::TemporaryFile (const File& target, const int optionFlags) targetFile (target) { // If you use this constructor, you need to give it a valid target file! - bassert (targetFile != File::nonexistent); + bassert (targetFile != File::nonexistent ()); } TemporaryFile::TemporaryFile (const File& target, const File& temporary) @@ -74,7 +74,7 @@ bool TemporaryFile::overwriteTargetFileWithTemporary() const { // This method only works if you created this object with the constructor // that takes a target file! - bassert (targetFile != File::nonexistent); + bassert (targetFile != File::nonexistent ()); if (temporaryFile.exists()) { diff --git a/modules/beast_core/native/beast_android_Files.cpp b/modules/beast_core/native/beast_android_Files.cpp index 51d57f85e..5e3972347 100644 --- a/modules/beast_core/native/beast_android_Files.cpp +++ b/modules/beast_core/native/beast_android_Files.cpp @@ -127,7 +127,7 @@ File File::getSpecialLocation (const SpecialLocationType type) break; } - return File::nonexistent; + return File::nonexistent (); } //============================================================================== diff --git a/modules/beast_core/native/beast_bsd_Files.cpp b/modules/beast_core/native/beast_bsd_Files.cpp index 7f8c1eef0..e29f551dc 100644 --- a/modules/beast_core/native/beast_bsd_Files.cpp +++ b/modules/beast_core/native/beast_bsd_Files.cpp @@ -213,7 +213,7 @@ File File::getSpecialLocation (const SpecialLocationType type) break; } - return File::nonexistent; + return File::nonexistent (); } //============================================================================== diff --git a/modules/beast_core/native/beast_linux_Files.cpp b/modules/beast_core/native/beast_linux_Files.cpp index 7f8c1eef0..e29f551dc 100644 --- a/modules/beast_core/native/beast_linux_Files.cpp +++ b/modules/beast_core/native/beast_linux_Files.cpp @@ -213,7 +213,7 @@ File File::getSpecialLocation (const SpecialLocationType type) break; } - return File::nonexistent; + return File::nonexistent (); } //============================================================================== diff --git a/modules/beast_core/native/beast_mac_Files.mm b/modules/beast_core/native/beast_mac_Files.mm index 09b55030e..183492670 100644 --- a/modules/beast_core/native/beast_mac_Files.mm +++ b/modules/beast_core/native/beast_mac_Files.mm @@ -251,7 +251,7 @@ File File::getSpecialLocation (const SpecialLocationType type) return File (resultPath.convertToPrecomposedUnicode()); } - return File::nonexistent; + return File::nonexistent (); } //============================================================================== diff --git a/modules/beast_core/native/beast_win32_Files.cpp b/modules/beast_core/native/beast_win32_Files.cpp index a15fdb6b6..444bc51c3 100644 --- a/modules/beast_core/native/beast_win32_Files.cpp +++ b/modules/beast_core/native/beast_win32_Files.cpp @@ -88,7 +88,7 @@ namespace WindowsFileHelpers if (SHGetSpecialFolderPath (0, path, type, FALSE)) return File (String (path)); - return File::nonexistent; + return File::nonexistent (); } File getModuleFileName (HINSTANCE moduleHandle) @@ -536,7 +536,7 @@ File BEAST_CALLTYPE File::getSpecialLocation (const SpecialLocationType type) default: bassertfalse; // unknown type? - return File::nonexistent; + return File::nonexistent (); } return WindowsFileHelpers::getSpecialFolderPath (csidlType); diff --git a/modules/beast_core/time/beast_PerformanceCounter.cpp b/modules/beast_core/time/beast_PerformanceCounter.cpp index fe1f82c8a..6231e11b1 100644 --- a/modules/beast_core/time/beast_PerformanceCounter.cpp +++ b/modules/beast_core/time/beast_PerformanceCounter.cpp @@ -30,7 +30,7 @@ PerformanceCounter::PerformanceCounter (const String& name_, totalTime (0), outputFile (loggingFile) { - if (outputFile != File::nonexistent) + if (outputFile != File::nonexistent ()) { String s ("**** Counter for \""); s << name_ << "\" started at: " @@ -81,7 +81,7 @@ void PerformanceCounter::printStatistics() s << newLine; - if (outputFile != File::nonexistent) + if (outputFile != File::nonexistent ()) outputFile.appendText (s, false, false); numRuns = 0; diff --git a/modules/beast_core/time/beast_PerformanceCounter.h b/modules/beast_core/time/beast_PerformanceCounter.h index f82651138..039876487 100644 --- a/modules/beast_core/time/beast_PerformanceCounter.h +++ b/modules/beast_core/time/beast_PerformanceCounter.h @@ -57,12 +57,13 @@ public: @param counterName the name used when printing out the statistics @param runsPerPrintout the number of start/stop iterations before calling printStatistics() - @param loggingFile a file to dump the results to - if this is File::nonexistent, - the results are just written to the debugger output + @param loggingFile a file to dump the results to - if this is + File::nonexistent (), the results are just written + to the debugger output */ PerformanceCounter (const String& counterName, int runsPerPrintout = 100, - const File& loggingFile = File::nonexistent); + const File& loggingFile = File::nonexistent ()); /** Destructor. */ ~PerformanceCounter();