diff --git a/beast/module/core/core.h b/beast/module/core/core.h index 0484e109b3..2ecc4619ed 100644 --- a/beast/module/core/core.h +++ b/beast/module/core/core.h @@ -52,9 +52,7 @@ #include #include #include -#include #include -#include #include @@ -144,7 +142,6 @@ class FileOutputStream; #include #include #include -#include #include #include diff --git a/beast/module/core/files/DirectoryIterator.h b/beast/module/core/files/DirectoryIterator.h index ec107bba43..582cb51c0d 100644 --- a/beast/module/core/files/DirectoryIterator.h +++ b/beast/module/core/files/DirectoryIterator.h @@ -41,7 +41,7 @@ namespace beast { It can also guess how far it's got using a wildly inaccurate algorithm. */ -class DirectoryIterator : LeakChecked +class DirectoryIterator { public: //============================================================================== @@ -119,7 +119,7 @@ public: private: //============================================================================== - class NativeIterator : LeakChecked + class NativeIterator { public: NativeIterator (const File& directory, const String& wildCard); diff --git a/beast/module/core/files/File.cpp b/beast/module/core/files/File.cpp index 1048981ac2..8ed627ad5e 100644 --- a/beast/module/core/files/File.cpp +++ b/beast/module/core/files/File.cpp @@ -22,29 +22,16 @@ //============================================================================== #include - +#include #include #include namespace beast { -// We need to make a shared singleton or else there are -// issues with the leak detector and order of detruction. -// -class NonexistentHolder +File const& File::nonexistent() { -public: - static NonexistentHolder* getInstance() - { - return SharedSingleton ::getInstance(); - } - - File file; -}; - -File const& File::nonexistent () -{ - return NonexistentHolder::getInstance ()->file; + static beast::static_initializer instance; + return *instance; } //------------------------------------------------------------------------------ diff --git a/beast/module/core/files/FileInputStream.h b/beast/module/core/files/FileInputStream.h index f145516232..02a863174c 100644 --- a/beast/module/core/files/FileInputStream.h +++ b/beast/module/core/files/FileInputStream.h @@ -35,7 +35,6 @@ namespace beast */ class FileInputStream : public InputStream - , LeakChecked { public: //============================================================================== diff --git a/beast/module/core/files/FileOutputStream.h b/beast/module/core/files/FileOutputStream.h index 650513e7f1..ccb1ec3ade 100644 --- a/beast/module/core/files/FileOutputStream.h +++ b/beast/module/core/files/FileOutputStream.h @@ -35,7 +35,6 @@ namespace beast */ class FileOutputStream : public OutputStream - , LeakChecked { public: //============================================================================== diff --git a/beast/module/core/memory/MemoryBlock.h b/beast/module/core/memory/MemoryBlock.h index 2272848bed..8c080dd72a 100644 --- a/beast/module/core/memory/MemoryBlock.h +++ b/beast/module/core/memory/MemoryBlock.h @@ -25,7 +25,6 @@ #define BEAST_MODULE_CORE_MEMORY_MEMORYBLOCK_H_INCLUDED #include -#include #include namespace beast { @@ -35,7 +34,7 @@ namespace beast { A class to hold a resizable block of raw data. */ -class MemoryBlock : LeakChecked +class MemoryBlock { public: //============================================================================== diff --git a/beast/module/core/memory/SharedSingleton.h b/beast/module/core/memory/SharedSingleton.h deleted file mode 100644 index 84a2e9c1e4..0000000000 --- a/beast/module/core/memory/SharedSingleton.h +++ /dev/null @@ -1,205 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#ifndef BEAST_MODULE_CORE_MEMORY_SHAREDSINGLETON_H_INCLUDED -#define BEAST_MODULE_CORE_MEMORY_SHAREDSINGLETON_H_INCLUDED - -#include -#include -#include - -#include - -namespace beast -{ - -/** Thread-safe singleton which comes into existence on first use. Use this - instead of creating objects with static storage duration. These singletons - are automatically reference counted, so if you hold a pointer to it in every - object that depends on it, the order of destruction of objects is assured - to be correct. - - Object Requirements: - DefaultConstructible - TriviallyDestructible (when lifetime == neverDestroyed) - Destructible - - @class SharedSingleton - @ingroup beast_core -*/ -/** @{ */ -class SingletonLifetime -{ -public: - // It would be nice if we didn't have to qualify the enumeration but - // Argument Dependent Lookup is inapplicable here because: - // - // "Base classes dependent on a template parameter aren't part of lookup." - // - ville - // - - /** Construction options for SharedSingleton - - @ingroup beast_core - */ - enum Lifetime - { - /** Created on first use, destroyed when the last reference is removed. - */ - createOnDemand, - - /** The singleton is created on first use and persists until program exit. - */ - persistAfterCreation, - - /** The singleton is created when needed and never destroyed. - - This is useful for applications which do not have a clean exit. - */ - neverDestroyed - }; -}; - -//------------------------------------------------------------------------------ - -/** Wraps object to produce a reference counted singleton. */ -template -class SharedSingleton - : public Object - , private SharedObject -{ -public: - typedef SharedPtr > Ptr; - - static Ptr get (SingletonLifetime::Lifetime lifetime - = SingletonLifetime::persistAfterCreation) - { - StaticData& staticData (getStaticData ()); - SharedSingleton* instance = staticData.instance; - if (instance == nullptr) - { - std::lock_guard lock (staticData.mutex); - instance = staticData.instance; - if (instance == nullptr) - { - bassert (lifetime == SingletonLifetime::createOnDemand || ! staticData.destructorCalled); - staticData.instance = &staticData.object; - new (staticData.instance) SharedSingleton (lifetime); - std::atomic_thread_fence (std::memory_order_seq_cst); - instance = staticData.instance; - } - } - return instance; - } - - // DEPRECATED LEGACY FUNCTION NAME - static Ptr getInstance (SingletonLifetime::Lifetime lifetime - = SingletonLifetime::persistAfterCreation) - { - return get (lifetime); - } - -private: - explicit SharedSingleton (SingletonLifetime::Lifetime lifetime) - : m_lifetime (lifetime) - , m_exitHook (this) - { - if (m_lifetime == SingletonLifetime::persistAfterCreation || - m_lifetime == SingletonLifetime::neverDestroyed) - this->incReferenceCount (); - } - - ~SharedSingleton () - { - } - - void onExit () - { - if (m_lifetime == SingletonLifetime::persistAfterCreation) - this->decReferenceCount (); - } - - void destroy () const - { - bool callDestructor; - - // Handle the condition where one thread is releasing the last - // reference just as another thread is trying to acquire it. - // - { - StaticData& staticData (getStaticData ()); - std::lock_guard lock (staticData.mutex); - - if (this->getReferenceCount() != 0) - { - callDestructor = false; - } - else - { - callDestructor = true; - staticData.instance = nullptr; - staticData.destructorCalled = true; - } - } - - if (callDestructor) - { - bassert (m_lifetime != SingletonLifetime::neverDestroyed); - - this->~SharedSingleton(); - } - } - - typedef SpinLock LockType; - - // This structure gets zero-filled at static initialization time. - // No constructors are called. - // - class StaticData - { - public: - LockType mutex; - SharedSingleton* instance; - SharedSingleton object; - bool destructorCalled; - - StaticData() = delete; - StaticData(StaticData const&) = delete; - StaticData& operator= (StaticData const&) = delete; - ~StaticData() = delete; - }; - - static StaticData& getStaticData () - { - static std::uint8_t storage [sizeof (StaticData)]; - return *(reinterpret_cast (&storage [0])); - } - - friend class SharedPtr ; - friend class AtExitMemberHook ; - - SingletonLifetime::Lifetime m_lifetime; - AtExitMemberHook m_exitHook; -}; - -//------------------------------------------------------------------------------ - -} // beast - -#endif diff --git a/beast/module/core/native/win32_Files.cpp b/beast/module/core/native/win32_Files.cpp index 592f3285f9..f4748d3757 100644 --- a/beast/module/core/native/win32_Files.cpp +++ b/beast/module/core/native/win32_Files.cpp @@ -399,7 +399,6 @@ bool File::setAsCurrentWorkingDirectory() const //============================================================================== class DirectoryIterator::NativeIterator::Pimpl - : LeakChecked { public: Pimpl (const File& directory, const String& wildCard) diff --git a/beast/module/core/streams/FileInputSource.h b/beast/module/core/streams/FileInputSource.h index ac335e728b..5e35312b4a 100644 --- a/beast/module/core/streams/FileInputSource.h +++ b/beast/module/core/streams/FileInputSource.h @@ -35,7 +35,6 @@ namespace beast */ class FileInputSource : public InputSource - , LeakChecked { public: //============================================================================== diff --git a/beast/module/core/streams/InputSource.h b/beast/module/core/streams/InputSource.h index 6a0c1f64d1..cf39bf9bb7 100644 --- a/beast/module/core/streams/InputSource.h +++ b/beast/module/core/streams/InputSource.h @@ -36,7 +36,7 @@ namespace beast @see FileInputSource */ -class InputSource : LeakChecked +class InputSource { public: //============================================================================== diff --git a/beast/module/core/streams/InputStream.h b/beast/module/core/streams/InputStream.h index afe92919c0..2a31e03eda 100644 --- a/beast/module/core/streams/InputStream.h +++ b/beast/module/core/streams/InputStream.h @@ -38,7 +38,6 @@ class MemoryBlock; @see OutputStream, FileInputStream */ class InputStream - : LeakChecked { public: /** Destructor. */ diff --git a/beast/module/core/streams/MemoryOutputStream.h b/beast/module/core/streams/MemoryOutputStream.h index c705b97f01..82217a9faa 100644 --- a/beast/module/core/streams/MemoryOutputStream.h +++ b/beast/module/core/streams/MemoryOutputStream.h @@ -43,8 +43,7 @@ namespace beast */ class MemoryOutputStream : public OutputStream - , LeakChecked -{ +{ public: //============================================================================== /** Creates an empty memory stream, ready to be written into. diff --git a/beast/module/core/thread/DeadlineTimer.cpp b/beast/module/core/thread/DeadlineTimer.cpp index f544860819..9685277543 100644 --- a/beast/module/core/thread/DeadlineTimer.cpp +++ b/beast/module/core/thread/DeadlineTimer.cpp @@ -17,12 +17,13 @@ */ //============================================================================== +#include + namespace beast { class DeadlineTimer::Manager - : public LeakChecked - , protected Thread + : protected Thread { private: typedef CriticalSection LockType; @@ -42,6 +43,14 @@ public: bassert (m_items.empty ()); } + static + Manager& + instance() + { + static beast::static_initializer m; + return *m; + } + // Okay to call on an active timer. // However, an extra notification may still happen due to concurrency. // @@ -210,19 +219,18 @@ private: DeadlineTimer::DeadlineTimer (Listener* listener) : m_listener (listener) - , m_manager (SharedSingleton ::getInstance ()) , m_isActive (false) { } DeadlineTimer::~DeadlineTimer () { - m_manager->deactivate (*this); + Manager::instance().deactivate (*this); } void DeadlineTimer::cancel () { - m_manager->deactivate (*this); + Manager::instance().deactivate (*this); } void DeadlineTimer::setExpiration (double secondsUntilDeadline) @@ -232,7 +240,7 @@ void DeadlineTimer::setExpiration (double secondsUntilDeadline) RelativeTime const when ( RelativeTime::fromStartup() + secondsUntilDeadline); - m_manager->activate (*this, 0, when); + Manager::instance().activate (*this, 0, when); } void DeadlineTimer::setRecurringExpiration (double secondsUntilDeadline) @@ -242,7 +250,7 @@ void DeadlineTimer::setRecurringExpiration (double secondsUntilDeadline) RelativeTime const when ( RelativeTime::fromStartup() + secondsUntilDeadline); - m_manager->activate (*this, secondsUntilDeadline, when); + Manager::instance().activate (*this, secondsUntilDeadline, when); } } // beast diff --git a/beast/module/core/thread/DeadlineTimer.h b/beast/module/core/thread/DeadlineTimer.h index 348ab5f7f8..ba7ff0d717 100644 --- a/beast/module/core/thread/DeadlineTimer.h +++ b/beast/module/core/thread/DeadlineTimer.h @@ -20,8 +20,6 @@ #ifndef BEAST_MODULE_CORE_THREAD_DEADLINETIMER_H_INCLUDED #define BEAST_MODULE_CORE_THREAD_DEADLINETIMER_H_INCLUDED -#include - namespace beast { /** Provides periodic or one time notifications at a specified time interval. @@ -108,7 +106,6 @@ private: class Manager; Listener* const m_listener; - SharedPtr > m_manager; bool m_isActive; RelativeTime m_notificationTime; double m_secondsRecurring; // non zero if recurring diff --git a/beast/module/core/time/AtExitHook.cpp b/beast/module/core/time/AtExitHook.cpp index de391c110f..fae8090d49 100644 --- a/beast/module/core/time/AtExitHook.cpp +++ b/beast/module/core/time/AtExitHook.cpp @@ -17,8 +17,9 @@ */ //============================================================================== -namespace beast -{ +#include + +namespace beast { // Manages the list of hooks, and calls // whoever is in the list at exit time. @@ -33,7 +34,9 @@ public: static inline Manager& get () { - return StaticObject ::get(); + static beast::static_initializer< + Manager> instance; + return *instance; } void insert (Item& item) @@ -73,10 +76,6 @@ private: AtExitHook* const hook (item.hook ()); hook->onExit (); } - - // Now do the leak checking - // - LeakCheckedBase::checkForLeaks (); } struct StaticDestructor diff --git a/beast/module/sqdb/api/session.h b/beast/module/sqdb/api/session.h index 93965edabb..2cb13e9be0 100644 --- a/beast/module/sqdb/api/session.h +++ b/beast/module/sqdb/api/session.h @@ -61,7 +61,6 @@ #define BEAST_MODULE_SQDB_API_SESSION_H_INCLUDED #include -#include namespace beast { namespace sqdb { @@ -137,8 +136,6 @@ private: Error hard_exec(std::string const& query); private: - class Sqlite3; - SharedPtr > m_instance; bool m_bInTransaction; sqlite3* m_connection; String m_fileName; diff --git a/beast/module/sqdb/source/session.cpp b/beast/module/sqdb/source/session.cpp index 39f0777aad..d63b1b2e06 100644 --- a/beast/module/sqdb/source/session.cpp +++ b/beast/module/sqdb/source/session.cpp @@ -62,26 +62,27 @@ namespace beast { namespace sqdb { -class session::Sqlite3 +class Sqlite3Instance { public: - Sqlite3() + Sqlite3Instance() { assert (sqlite3_threadsafe() != 0); sqlite3_initialize(); } - ~Sqlite3() + ~Sqlite3Instance() { sqlite3_shutdown(); } }; +Sqlite3Instance sqlite3_instance; + //------------------------------------------------------------------------------ session::session() : prepare (this) - , m_instance (SharedSingleton ::getInstance ()) , m_bInTransaction (false) , m_connection (nullptr) { @@ -89,7 +90,6 @@ session::session() session::session(const session& deferredClone) : prepare (this) - , m_instance (SharedSingleton ::getInstance ()) , m_bInTransaction (false) , m_connection (nullptr) , m_fileName (deferredClone.m_fileName) diff --git a/beast/threads/Thread.h b/beast/threads/Thread.h index 8c4dcbc69c..f6ce9b3e80 100644 --- a/beast/threads/Thread.h +++ b/beast/threads/Thread.h @@ -24,7 +24,6 @@ #ifndef BEAST_THREADS_THREAD_H_INCLUDED #define BEAST_THREADS_THREAD_H_INCLUDED -#include #include #include @@ -43,7 +42,7 @@ namespace beast { @see CriticalSection, WaitableEvent, Process, ThreadWithProgressWindow, MessageManagerLock */ -class Thread : LeakChecked +class Thread { public: //============================================================================== diff --git a/beast/threads/WaitableEvent.h b/beast/threads/WaitableEvent.h index 3a3bd061e9..3eeb827903 100644 --- a/beast/threads/WaitableEvent.h +++ b/beast/threads/WaitableEvent.h @@ -38,7 +38,6 @@ namespace beast { method. */ class WaitableEvent - //, LeakChecked // VFALCO TODO Move LeakChecked to beast/ { public: //============================================================================== diff --git a/beast/utility/LeakChecked.h b/beast/utility/LeakChecked.h deleted file mode 100644 index 5cec09bbfb..0000000000 --- a/beast/utility/LeakChecked.h +++ /dev/null @@ -1,181 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#ifndef BEAST_UTILITY_LEAKCHECKED_H_INCLUDED -#define BEAST_UTILITY_LEAKCHECKED_H_INCLUDED - -#include -#include -#include - -#include - -namespace beast { - -namespace detail { - -class LeakCheckedBase -{ -public: - static void checkForLeaks (); - -protected: - class LeakCounterBase : public LockFreeStack ::Node - { - public: - LeakCounterBase (); - - virtual ~LeakCounterBase () - { - } - - inline int increment () - { - return ++m_count; - } - - inline int decrement () - { - return --m_count; - } - - virtual char const* getClassName () const = 0; - - private: - void checkForLeaks (); - virtual void checkPureVirtual () const = 0; - - class Singleton; - friend class LeakCheckedBase; - - std::atomic m_count; - }; - - static void reportDanglingPointer (char const* objectName); -}; - -//------------------------------------------------------------------------------ - -/** Detects leaks at program exit. - - To use this, derive your class from this template using CRTP (curiously - recurring template pattern). -*/ -template -class LeakChecked : private LeakCheckedBase -{ -protected: - LeakChecked () noexcept - { - getCounter ().increment (); - } - - LeakChecked (LeakChecked const&) noexcept - { - getCounter ().increment (); - } - - ~LeakChecked () - { - if (getCounter ().decrement () < 0) - { - reportDanglingPointer (getLeakCheckedName ()); - } - } - -private: - // Singleton that maintains the count of this object - // - class LeakCounter : public LeakCounterBase - { - public: - LeakCounter () noexcept - { - } - - char const* getClassName () const - { - return getLeakCheckedName (); - } - - void checkPureVirtual () const { } - }; - -private: - /* Due to a bug in Visual Studio 10 and earlier, the string returned by - typeid().name() will appear to leak on exit. Therefore, we should - only call this function when there's an actual leak, or else there - will be spurious leak notices at exit. - */ - static const char* getLeakCheckedName () - { - return typeid (Object).name (); - } - - // Retrieve the singleton for this object - // - static LeakCounter& getCounter () noexcept - { - return StaticObject ::get(); - } -}; - -} - -//------------------------------------------------------------------------------ - -namespace detail -{ - -namespace disabled -{ - -class LeakCheckedBase -{ -public: - static void checkForLeaks () - { - } -}; - -template -class LeakChecked : public LeakCheckedBase -{ -public: -}; - -} - -} - -//------------------------------------------------------------------------------ - -// Lift the appropriate implementation into our namespace -// -#if BEAST_CHECK_MEMORY_LEAKS -using detail::LeakChecked; -using detail::LeakCheckedBase; -#else -using detail::disabled::LeakChecked; -using detail::disabled::LeakCheckedBase; -#endif - -} - -#endif diff --git a/beast/utility/StaticObject.h b/beast/utility/StaticObject.h deleted file mode 100644 index d1ce01cbef..0000000000 --- a/beast/utility/StaticObject.h +++ /dev/null @@ -1,124 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#ifndef BEAST_UTILITY_STATICOBJECT_H_INCLUDED -#define BEAST_UTILITY_STATICOBJECT_H_INCLUDED - -#include -#include -#include - -namespace beast { - -// Spec: N2914=09-0104 -// -// [3.6.2] Initialization of non-local objects -// -// Objects with static storage duration (3.7.1) or thread storage -// duration (3.7.2) shall be zero-initialized (8.5) before any -// other initialization takes place. -// - -/** Wrapper to produce an object with static storage duration. - - The object is constructed in a thread-safe fashion when the get function - is first called. Note that the destructor for Object is never called. To - invoke the destructor, use the AtExitHook facility (with caution). - - The Tag parameter allows multiple instances of the same Object type, by - using different tags. - - Object must meet these requirements: - DefaultConstructible - - @see AtExitHook -*/ -template -class StaticObject -{ -public: - static Object& get () - { - StaticData& staticData (StaticData::get()); - - if (staticData.state.load () != initialized) - { - if (staticData.state.exchange (initializing) == uninitialized) - { - // Initialize the object. - new (&staticData.object) Object; - staticData.state = initialized; - } - else - { - std::size_t n = 0; - - while (staticData.state.load () != initialized) - { - ++n; - - std::this_thread::yield (); - - if (n > 10) - { - std::chrono::milliseconds duration (1); - - if (n > 100) - duration *= 10; - - std::this_thread::sleep_for (duration); - } - } - } - } - - assert (staticData.state.load () == initialized); - return staticData.object; - } - -private: - static int const uninitialized = 0; - static int const initializing = 1; - static int const initialized = 2; - - // This structure gets zero-filled at static initialization time. - // No constructors are called. - // - class StaticData - { - public: - std::atomic state; - Object object; - - static StaticData& get () - { - static std::uint8_t storage [sizeof (StaticData)]; - return *(reinterpret_cast (&storage [0])); - } - - StaticData() = delete; - StaticData(StaticData const&) = delete; - StaticData& operator= (StaticData const&) = delete; - ~StaticData() = delete; - }; -}; - -} - -#endif diff --git a/beast/utility/Utility.unity.cpp b/beast/utility/Utility.unity.cpp index 71ce60e47d..ccf58e5b29 100644 --- a/beast/utility/Utility.unity.cpp +++ b/beast/utility/Utility.unity.cpp @@ -25,7 +25,6 @@ #include #include -#include #include #include diff --git a/beast/utility/impl/Journal.cpp b/beast/utility/impl/Journal.cpp index 25ee34609a..ec674f6914 100644 --- a/beast/utility/impl/Journal.cpp +++ b/beast/utility/impl/Journal.cpp @@ -18,7 +18,7 @@ //============================================================================== #include -#include +#include namespace beast { @@ -60,8 +60,8 @@ public: Journal::Sink& Journal::getNullSink () { - return *SharedSingleton ::get ( - SingletonLifetime::neverDestroyed); + static beast::static_initializer sink; + return *sink; } //------------------------------------------------------------------------------ diff --git a/beast/utility/impl/LeakChecked.cpp b/beast/utility/impl/LeakChecked.cpp deleted file mode 100644 index 20478665c2..0000000000 --- a/beast/utility/impl/LeakChecked.cpp +++ /dev/null @@ -1,102 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#include - -namespace beast { - -namespace detail -{ - -class LeakCheckedBase::LeakCounterBase::Singleton -{ -public: - void push_back (LeakCounterBase* counter) - { - m_list.push_front (counter); - } - - void checkForLeaks () - { - for (;;) - { - LeakCounterBase* const counter = m_list.pop_front (); - - if (!counter) - break; - - counter->checkForLeaks (); - } - } - - static Singleton& getInstance () - { - static Singleton instance; - - return instance; - } - -private: - friend class LeakCheckedBase; - - LockFreeStack m_list; -}; - -//------------------------------------------------------------------------------ - -LeakCheckedBase::LeakCounterBase::LeakCounterBase () - : m_count (0) -{ - Singleton::getInstance ().push_back (this); -} - -void LeakCheckedBase::LeakCounterBase::checkForLeaks () -{ - // If there's a runtime error from this line, it means there's - // an order of destruction problem between different translation units! - // - this->checkPureVirtual (); - - int const count = m_count.load (); - - if (count > 0) - { - outputDebugString ("Leaked objects: " + std::to_string (count) + - " instances of " + getClassName ()); - } -} - -//------------------------------------------------------------------------------ - -void LeakCheckedBase::reportDanglingPointer (char const* objectName) -{ - outputDebugString (std::string ("Dangling pointer deletion: ") + objectName); - bassertfalse; -} - -//------------------------------------------------------------------------------ - -void LeakCheckedBase::checkForLeaks () -{ - LeakCounterBase::Singleton::getInstance ().checkForLeaks (); -} - -} - -}