New SharedSingleton, resolves destruction of objects with static storage duration.

This commit is contained in:
Vinnie Falco
2013-09-12 04:35:13 -07:00
parent 41eb8a1e29
commit 55447b05ac
17 changed files with 150 additions and 229 deletions

View File

@@ -210,7 +210,7 @@
<ClInclude Include="..\..\modules\beast_core\memory\beast_RecycledObjectPool.h" /> <ClInclude Include="..\..\modules\beast_core\memory\beast_RecycledObjectPool.h" />
<ClInclude Include="..\..\modules\beast_core\memory\SharedObject.h" /> <ClInclude Include="..\..\modules\beast_core\memory\SharedObject.h" />
<ClInclude Include="..\..\modules\beast_core\memory\beast_ScopedPointer.h" /> <ClInclude Include="..\..\modules\beast_core\memory\beast_ScopedPointer.h" />
<ClInclude Include="..\..\modules\beast_core\memory\beast_SharedSingleton.h" /> <ClInclude Include="..\..\modules\beast_core\memory\SharedSingleton.h" />
<ClInclude Include="..\..\modules\beast_core\memory\beast_StaticObject.h" /> <ClInclude Include="..\..\modules\beast_core\memory\beast_StaticObject.h" />
<ClInclude Include="..\..\modules\beast_core\memory\beast_Uncopyable.h" /> <ClInclude Include="..\..\modules\beast_core\memory\beast_Uncopyable.h" />
<ClInclude Include="..\..\modules\beast_core\memory\beast_WeakReference.h" /> <ClInclude Include="..\..\modules\beast_core\memory\beast_WeakReference.h" />
@@ -285,7 +285,6 @@
<ClInclude Include="..\..\modules\beast_core\thread\beast_CallQueue.h" /> <ClInclude Include="..\..\modules\beast_core\thread\beast_CallQueue.h" />
<ClInclude Include="..\..\modules\beast_core\thread\beast_ConcurrentObject.h" /> <ClInclude Include="..\..\modules\beast_core\thread\beast_ConcurrentObject.h" />
<ClInclude Include="..\..\modules\beast_core\thread\beast_DeadlineTimer.h" /> <ClInclude Include="..\..\modules\beast_core\thread\beast_DeadlineTimer.h" />
<ClInclude Include="..\..\modules\beast_core\thread\beast_GlobalThreadGroup.h" />
<ClInclude Include="..\..\modules\beast_core\thread\beast_InterruptibleThread.h" /> <ClInclude Include="..\..\modules\beast_core\thread\beast_InterruptibleThread.h" />
<ClInclude Include="..\..\modules\beast_core\thread\beast_Listeners.h" /> <ClInclude Include="..\..\modules\beast_core\thread\beast_Listeners.h" />
<ClInclude Include="..\..\modules\beast_core\thread\beast_ManualCallQueue.h" /> <ClInclude Include="..\..\modules\beast_core\thread\beast_ManualCallQueue.h" />

View File

@@ -557,9 +557,6 @@
<ClInclude Include="..\..\modules\beast_core\memory\beast_Uncopyable.h"> <ClInclude Include="..\..\modules\beast_core\memory\beast_Uncopyable.h">
<Filter>beast_core\memory</Filter> <Filter>beast_core\memory</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\modules\beast_core\memory\beast_SharedSingleton.h">
<Filter>beast_core\memory</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\maths\beast_Interval.h"> <ClInclude Include="..\..\modules\beast_core\maths\beast_Interval.h">
<Filter>beast_core\maths</Filter> <Filter>beast_core\maths</Filter>
</ClInclude> </ClInclude>
@@ -728,9 +725,6 @@
<ClInclude Include="..\..\modules\beast_core\thread\beast_ConcurrentObject.h"> <ClInclude Include="..\..\modules\beast_core\thread\beast_ConcurrentObject.h">
<Filter>beast_core\thread</Filter> <Filter>beast_core\thread</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\modules\beast_core\thread\beast_GlobalThreadGroup.h">
<Filter>beast_core\thread</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\thread\beast_InterruptibleThread.h"> <ClInclude Include="..\..\modules\beast_core\thread\beast_InterruptibleThread.h">
<Filter>beast_core\thread</Filter> <Filter>beast_core\thread</Filter>
</ClInclude> </ClInclude>
@@ -1028,6 +1022,9 @@
<ClInclude Include="..\..\modules\beast_asio\basics\BufferType.h"> <ClInclude Include="..\..\modules\beast_asio\basics\BufferType.h">
<Filter>beast_asio\basics</Filter> <Filter>beast_asio\basics</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\modules\beast_core\memory\SharedSingleton.h">
<Filter>beast_core\memory</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\modules\beast_core\containers\beast_AbstractFifo.cpp"> <ClCompile Include="..\..\modules\beast_core\containers\beast_AbstractFifo.cpp">

View File

@@ -2,9 +2,12 @@
BEAST TODO BEAST TODO
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
- Use new file naming convention - Remove ReadWriteMutex and replace it with a CriticalSection
since the implementation is broken.
- Rename ReadWriteMutex to SharedMutex - Rewrite SharedData to work with a CriticalSection
- Use new file naming convention
- Use SemanticVersion for beast version numbers to replace BEAST_VERSION - Use SemanticVersion for beast version numbers to replace BEAST_VERSION

View File

@@ -363,7 +363,7 @@ extern BEAST_API void BEAST_CALLTYPE logAssertion (char const* file, int line) n
#include "memory/beast_ByteOrder.h" #include "memory/beast_ByteOrder.h"
#include "memory/beast_Memory.h" #include "memory/beast_Memory.h"
#include "memory/beast_OptionalScopedPointer.h" #include "memory/beast_OptionalScopedPointer.h"
#include "memory/beast_SharedSingleton.h" #include "memory/SharedSingleton.h"
#include "memory/beast_WeakReference.h" #include "memory/beast_WeakReference.h"
#include "memory/beast_RecycledObjectPool.h" #include "memory/beast_RecycledObjectPool.h"
#include "misc/beast_Main.h" #include "misc/beast_Main.h"
@@ -421,7 +421,6 @@ extern BEAST_API void BEAST_CALLTYPE logAssertion (char const* file, int line) n
#include "thread/beast_InterruptibleThread.h" #include "thread/beast_InterruptibleThread.h"
#include "thread/beast_ThreadGroup.h" #include "thread/beast_ThreadGroup.h"
#include "thread/beast_CallQueue.h" #include "thread/beast_CallQueue.h"
#include "thread/beast_GlobalThreadGroup.h"
#include "thread/beast_Listeners.h" #include "thread/beast_Listeners.h"
#include "thread/beast_ManualCallQueue.h" #include "thread/beast_ManualCallQueue.h"
#include "thread/beast_ParallelFor.h" #include "thread/beast_ParallelFor.h"

View File

@@ -24,20 +24,15 @@
// We need to make a shared singleton or else there are // We need to make a shared singleton or else there are
// issues with the leak detector and order of detruction. // issues with the leak detector and order of detruction.
// //
class NonexistentHolder : public SharedSingleton <NonexistentHolder> class NonexistentHolder
{ {
public: public:
NonexistentHolder () static NonexistentHolder* getInstance()
: SharedSingleton <NonexistentHolder> (SingletonLifetime::persistAfterCreation)
{ {
return SharedSingleton <NonexistentHolder>::getInstance();
} }
static NonexistentHolder* createInstance () File file;
{
return new NonexistentHolder;
}
File const file;
}; };
File const& File::nonexistent () File const& File::nonexistent ()

View File

@@ -74,7 +74,7 @@ public:
Requirement: Requirement:
U* must be convertible to T* U* must be convertible to T*
*/ */
/// @{ /** @{ */
SharedPtr (T* t) noexcept SharedPtr (T* t) noexcept
: m_p (acquire (t)) : m_p (acquire (t))
{ {
@@ -85,14 +85,14 @@ public:
: m_p (acquire (u)) : m_p (acquire (u))
{ {
} }
/// @} /** @} */
/** Construct a container holding an object from another container. /** Construct a container holding an object from another container.
This will increment the object's reference-count (if it is non-null). This will increment the object's reference-count (if it is non-null).
Requirement: Requirement:
U* must be convertible to T* U* must be convertible to T*
*/ */
/// @{ /** @{ */
#if BEAST_SHAREDPTR_PROVIDE_COMPILER_WORKAROUNDS #if BEAST_SHAREDPTR_PROVIDE_COMPILER_WORKAROUNDS
SharedPtr (SharedPtr const& sp) noexcept SharedPtr (SharedPtr const& sp) noexcept
: m_p (acquire (sp.get ())) : m_p (acquire (sp.get ()))
@@ -105,7 +105,7 @@ public:
: m_p (acquire (sp.get ())) : m_p (acquire (sp.get ()))
{ {
} }
/// @} /** @} */
/** Assign a different object to the container. /** Assign a different object to the container.
The previous object beind held, if any, loses a reference count and The previous object beind held, if any, loses a reference count and
@@ -113,7 +113,7 @@ public:
Requirement: Requirement:
U* must be convertible to T* U* must be convertible to T*
*/ */
/// @{ /** @{ */
#if BEAST_SHAREDPTR_PROVIDE_COMPILER_WORKAROUNDS #if BEAST_SHAREDPTR_PROVIDE_COMPILER_WORKAROUNDS
SharedPtr& operator= (T* t) SharedPtr& operator= (T* t)
{ {
@@ -126,10 +126,10 @@ public:
{ {
return assign (u); return assign (u);
} }
/// @} /** @} */
/** Assign an object from another container to this one. */ /** Assign an object from another container to this one. */
/// @{ /** @{ */
SharedPtr& operator= (SharedPtr const& sp) SharedPtr& operator= (SharedPtr const& sp)
{ {
return assign (sp.get ()); return assign (sp.get ());
@@ -141,7 +141,7 @@ public:
{ {
return assign (sp.get ()); return assign (sp.get ());
} }
/// @} /** @} */
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS #if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
/** Construct a container with an object transferred from another container. /** Construct a container with an object transferred from another container.
@@ -149,7 +149,7 @@ public:
Requires: Requires:
U* must be convertible to T* U* must be convertible to T*
*/ */
/// @{ /** @{ */
#if BEAST_SHAREDPTR_PROVIDE_COMPILER_WORKAROUNDS #if BEAST_SHAREDPTR_PROVIDE_COMPILER_WORKAROUNDS
SharedPtr (SharedPtr && sp) noexcept SharedPtr (SharedPtr && sp) noexcept
: m_p (sp.swap <T> (nullptr)) : m_p (sp.swap <T> (nullptr))
@@ -162,14 +162,14 @@ public:
: m_p (sp.swap <U> (nullptr)) : m_p (sp.swap <U> (nullptr))
{ {
} }
/// @} /** @} */
/** Transfer ownership of another object to this container. /** Transfer ownership of another object to this container.
The originating container loses its reference to the object. The originating container loses its reference to the object.
Requires: Requires:
U* must be convertible to T* U* must be convertible to T*
*/ */
/// @{ /** @{ */
#if BEAST_SHAREDPTR_PROVIDE_COMPILER_WORKAROUNDS #if BEAST_SHAREDPTR_PROVIDE_COMPILER_WORKAROUNDS
SharedPtr& operator= (SharedPtr && sp) SharedPtr& operator= (SharedPtr && sp)
{ {
@@ -182,7 +182,7 @@ public:
{ {
return assign (sp.swap <U> (nullptr)); return assign (sp.swap <U> (nullptr));
} }
/// @} /** @} */
#endif #endif
/** Destroy the container and release the held reference, if any. /** Destroy the container and release the held reference, if any.
@@ -262,8 +262,8 @@ private:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/// SharedPtr comparisons. /** SharedPtr comparisons. */
/// @{ /** @{ */
template <class T, class U> template <class T, class U>
bool operator== (SharedPtr <T> const& lhs, U* const rhs) noexcept bool operator== (SharedPtr <T> const& lhs, U* const rhs) noexcept
{ {
@@ -277,28 +277,28 @@ bool operator== (SharedPtr <T> const& lhs, SharedPtr <U> const& rhs) noexcept
} }
template <class T, class U> template <class T, class U>
bool operator== (T const* lhs, SharedPtr<T> const& rhs) noexcept bool operator== (T const* lhs, SharedPtr <U> const& rhs) noexcept
{ {
return lhs == rhs.get(); return lhs == rhs.get();
} }
template <class T, class U> template <class T, class U>
bool operator!= (SharedPtr <T> const& lhs, T const* rhs) noexcept bool operator!= (SharedPtr <T> const& lhs, U const* rhs) noexcept
{ {
return lhs.get() != rhs; return lhs.get() != rhs;
} }
template <class T, class U> template <class T, class U>
bool operator!= (SharedPtr <T> const& lhs, SharedPtr <T> const& rhs) noexcept bool operator!= (SharedPtr <T> const& lhs, SharedPtr <U> const& rhs) noexcept
{ {
return lhs.get() != rhs.get(); return lhs.get() != rhs.get();
} }
template <class T, class U> template <class T, class U>
bool operator!= (T const* lhs, SharedPtr<T> const& rhs) noexcept bool operator!= (T const* lhs, SharedPtr <U> const& rhs) noexcept
{ {
return lhs != rhs.get(); return lhs != rhs.get();
} }
/// @} /** @} */
#endif #endif

View File

@@ -17,8 +17,8 @@
*/ */
//============================================================================== //==============================================================================
#ifndef BEAST_REFERENCECOUNTEDSINGLETON_H_INCLUDED #ifndef BEAST_SHAREDSINGLETON_H_INCLUDED
#define BEAST_REFERENCECOUNTEDSINGLETON_H_INCLUDED #define BEAST_SHAREDSINGLETON_H_INCLUDED
/** Thread-safe singleton which comes into existence on first use. Use this /** Thread-safe singleton which comes into existence on first use. Use this
instead of creating objects with static storage duration. These singletons instead of creating objects with static storage duration. These singletons
@@ -52,11 +52,6 @@ public:
*/ */
createOnDemand, createOnDemand,
/** Like createOnDemand, but after the Singleton is destroyed an
exception will be thrown if an attempt is made to create it again.
*/
createOnDemandOnce,
/** The singleton is created on first use and persists until program exit. /** The singleton is created on first use and persists until program exit.
*/ */
persistAfterCreation, persistAfterCreation,
@@ -71,131 +66,128 @@ public:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** Wraps object to produce a reference counted singleton. */
template <class Object> template <class Object>
class SharedSingleton class SharedSingleton
: public SingletonLifetime : public Object
, private PerformedAtExit , private SharedObject
{ {
protected:
typedef SpinLock LockType;
/** Create the singleton.
@param lifetime The lifetime management option.
*/
explicit SharedSingleton (Lifetime const lifetime)
: m_lifetime (lifetime)
{
bassert (s_instance == nullptr);
if (m_lifetime == persistAfterCreation ||
m_lifetime == neverDestroyed)
{
incReferenceCount ();
}
}
virtual ~SharedSingleton ()
{
bassert (s_instance == nullptr);
}
public: public:
typedef SharedPtr <Object> Ptr; typedef SharedPtr <SharedSingleton <Object> > Ptr;
/** Retrieve a reference to the singleton. static Ptr getInstance (SingletonLifetime::Lifetime lifetime
*/ = SingletonLifetime::persistAfterCreation)
static Ptr getInstance ()
{ {
Ptr instance; StaticData& staticData (getStaticData ());
SharedSingleton* instance = staticData.instance;
instance = s_instance;
if (instance == nullptr) if (instance == nullptr)
{ {
LockType::ScopedLockType lock (*s_mutex); LockType::ScopedLockType lock (staticData.mutex);
instance = staticData.instance;
instance = s_instance;
if (instance == nullptr) if (instance == nullptr)
{ {
s_instance = Object::createInstance (); staticData.instance = &staticData.object;
::new (staticData.instance) SharedSingleton (lifetime);
instance = s_instance; instance = staticData.instance;
} }
} }
return instance; return instance;
} }
inline void incReferenceCount () noexcept
{
++m_refCount;
}
inline void decReferenceCount () noexcept
{
if (--m_refCount == 0)
destroySingleton ();
}
// Caller must synchronize.
inline bool isBeingReferenced () const
{
return m_refCount.get () != 0;
}
private: private:
explicit SharedSingleton (SingletonLifetime::Lifetime lifetime)
: m_lifetime (lifetime)
, m_exitHook (this)
{
if (m_lifetime == SingletonLifetime::persistAfterCreation)
this->incReferenceCount ();
}
~SharedSingleton ()
{
}
void performAtExit () void performAtExit ()
{ {
if (m_lifetime == SingletonLifetime::persistAfterCreation) if (m_lifetime == SingletonLifetime::persistAfterCreation)
decReferenceCount (); this->decReferenceCount ();
} }
void destroySingleton () void destroy () const
{ {
bool destroy; bool callDestructor;
// Handle the condition where one thread is releasing the last // Handle the condition where one thread is releasing the last
// reference just as another thread is trying to acquire it. // reference just as another thread is trying to acquire it.
// //
{ {
LockType::ScopedLockType lock (*s_mutex); StaticData& staticData (getStaticData ());
LockType::ScopedLockType lock (staticData.mutex);
if (isBeingReferenced ()) if (this->getReferenceCount() != 0)
{ {
destroy = false; callDestructor = false;
} }
else else
{ {
destroy = true; callDestructor = true;
s_instance = 0; staticData.instance = nullptr;
} }
} }
if (destroy) if (callDestructor)
{ {
bassert (m_lifetime != neverDestroyed); bassert (m_lifetime != SingletonLifetime::neverDestroyed);
delete static_cast <Object*> (this); this->~SharedSingleton();
} }
} }
private: typedef SpinLock LockType;
Lifetime const m_lifetime;
Atomic <int> m_refCount;
private: class ExitHook
static Object* s_instance; {
static Static::Storage <LockType, SharedSingleton <Object> > s_mutex; public:
explicit ExitHook (SharedSingleton* owner)
: m_owner (owner)
{
}
void performaAtExit ()
{
m_owner->performAtExit();
}
private:
SharedSingleton* m_owner;
};
// This structure gets zero-filled at static initialization time.
// No constructors are called.
//
struct StaticData
{
LockType mutex;
SharedSingleton* instance;
SharedSingleton object;
private:
StaticData();
~StaticData();
};
static StaticData& getStaticData ()
{
static uint8 storage [sizeof (StaticData)];
return *(reinterpret_cast <StaticData*> (&storage [0]));
}
friend class SharedPtr <SharedSingleton>;
SingletonLifetime::Lifetime m_lifetime;
ExitHook m_exitHook;
}; };
/** @{ */
template <class Object> //------------------------------------------------------------------------------
Object* SharedSingleton <Object>::s_instance;
template <class Object>
Static::Storage <typename SharedSingleton <Object>::LockType, SharedSingleton <Object> >
SharedSingleton <Object>::s_mutex;
#endif #endif

View File

@@ -27,7 +27,7 @@
@ingroup beast_concurrent @ingroup beast_concurrent
*/ */
template <class Tag> template <class Tag>
class GlobalFifoFreeStore : public SharedSingleton <GlobalFifoFreeStore <Tag> > class GlobalFifoFreeStore
{ {
public: public:
inline void* allocate (size_t bytes) inline void* allocate (size_t bytes)
@@ -40,15 +40,15 @@ public:
FifoFreeStoreType::deallocate (p); FifoFreeStoreType::deallocate (p);
} }
static GlobalFifoFreeStore* createInstance () typedef SharedPtr <SharedSingleton <GlobalFifoFreeStore> > Ptr;
static Ptr getInstance ()
{ {
return new GlobalFifoFreeStore; return SharedSingleton <GlobalFifoFreeStore>::getInstance();
} }
public: public:
GlobalFifoFreeStore () GlobalFifoFreeStore ()
: SharedSingleton <GlobalFifoFreeStore <Tag> >
(SingletonLifetime::persistAfterCreation)
{ {
} }

View File

@@ -27,8 +27,7 @@ static const size_t globalPageBytes = 8 * 1024;
} }
GlobalPagedFreeStore::GlobalPagedFreeStore () GlobalPagedFreeStore::GlobalPagedFreeStore ()
: SharedSingleton <GlobalPagedFreeStore> (SingletonLifetime::persistAfterCreation) : m_allocator (globalPageBytes)
, m_allocator (globalPageBytes)
{ {
} }
@@ -36,7 +35,9 @@ GlobalPagedFreeStore::~GlobalPagedFreeStore ()
{ {
} }
GlobalPagedFreeStore* GlobalPagedFreeStore::createInstance () GlobalPagedFreeStore::Ptr GlobalPagedFreeStore::getInstance ()
{ {
return new GlobalPagedFreeStore; return SharedSingleton <GlobalPagedFreeStore>::getInstance();
} }

View File

@@ -26,9 +26,7 @@
@ingroup beast_concurrent @ingroup beast_concurrent
*/ */
class BEAST_API GlobalPagedFreeStore class BEAST_API GlobalPagedFreeStore : public LeakChecked <GlobalPagedFreeStore>
: public SharedSingleton <GlobalPagedFreeStore>
, LeakChecked <GlobalPagedFreeStore>
{ {
public: public:
GlobalPagedFreeStore (); GlobalPagedFreeStore ();
@@ -50,7 +48,9 @@ public:
PagedFreeStore::deallocate (p); PagedFreeStore::deallocate (p);
} }
static GlobalPagedFreeStore* createInstance (); typedef SharedPtr <SharedSingleton <GlobalPagedFreeStore> > Ptr;
static Ptr getInstance ();
private: private:
PagedFreeStore m_allocator; PagedFreeStore m_allocator;

View File

@@ -17,18 +17,14 @@
*/ */
//============================================================================== //==============================================================================
class DeadlineTimer::Manager class DeadlineTimer::Manager : protected Thread
: public SharedSingleton <DeadlineTimer::Manager>
, protected Thread
{ {
private: private:
typedef CriticalSection LockType; typedef CriticalSection LockType;
typedef List <DeadlineTimer> Items; typedef List <DeadlineTimer> Items;
public: public:
Manager () Manager () : Thread ("DeadlineTimer::Manager")
: SharedSingleton <Manager> (SingletonLifetime::persistAfterCreation)
, Thread ("DeadlineTimer::Manager")
{ {
startThread (); startThread ();
} }
@@ -200,11 +196,6 @@ public:
} }
} }
static Manager* createInstance ()
{
return new Manager;
}
private: private:
CriticalSection m_mutex; CriticalSection m_mutex;
Items m_items; Items m_items;
@@ -214,7 +205,8 @@ private:
DeadlineTimer::DeadlineTimer (Listener* listener) DeadlineTimer::DeadlineTimer (Listener* listener)
: m_listener (listener) : m_listener (listener)
, m_manager (Manager::getInstance ()) , m_manager (SharedSingleton <Manager>::getInstance (
SingletonLifetime::persistAfterCreation))
, m_isActive (false) , m_isActive (false)
{ {
} }

View File

@@ -112,7 +112,7 @@ private:
class Manager; class Manager;
Listener* const m_listener; Listener* const m_listener;
SharedPtr <Manager> m_manager; SharedPtr <SharedSingleton <Manager> > m_manager;
bool m_isActive; bool m_isActive;
Time m_notificationTime; Time m_notificationTime;
double m_secondsRecurring; // non zero if recurring double m_secondsRecurring; // non zero if recurring

View File

@@ -1,49 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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_GLOBALTHREADGROUP_H_INCLUDED
#define BEAST_GLOBALTHREADGROUP_H_INCLUDED
/*============================================================================*/
/**
A ThreadGroup singleton.
@see ThreadGroup
@ingroup beast_concurrent
*/
class BEAST_API GlobalThreadGroup : public ThreadGroup,
public SharedSingleton <GlobalThreadGroup>
{
private:
friend class SharedSingleton <GlobalThreadGroup>;
GlobalThreadGroup ()
: SharedSingleton <GlobalThreadGroup> (
SingletonLifetime::persistAfterCreation)
{
}
static GlobalThreadGroup* createInstance ()
{
return new GlobalThreadGroup;
}
};
#endif

View File

@@ -616,7 +616,7 @@ void ListenersBase::remove_void (void* const listener)
// Remove it from the list and manually release // Remove it from the list and manually release
// the reference since the list uses raw pointers. // the reference since the list uses raw pointers.
m_groups.erase (m_groups.iterator_to (*group); m_groups.erase (m_groups.iterator_to (*group));
group->decReferenceCount (); group->decReferenceCount ();
// It is still possible for the group to exist at this // It is still possible for the group to exist at this

View File

@@ -60,10 +60,9 @@ public:
It is best to keep this object around instead of creating and destroying It is best to keep this object around instead of creating and destroying
it every time you need to run a loop. it every time you need to run a loop.
@param pool The ThreadGroup to use. If this is omitted then a singleton @param pool The ThreadGroup to use.
ThreadGroup is used which contains one thread per CPU.
*/ */
explicit ParallelFor (ThreadGroup& pool = *GlobalThreadGroup::getInstance ()); explicit ParallelFor (ThreadGroup& pool);
/** Determine the number of threads in the group. /** Determine the number of threads in the group.

View File

@@ -135,7 +135,7 @@ private:
private: private:
class Sqlite3; class Sqlite3;
SharedPtr <Sqlite3> m_instance; SharedPtr <SharedSingleton <Sqlite3> > m_instance;
bool m_bInTransaction; bool m_bInTransaction;
sqlite3* m_connection; sqlite3* m_connection;
String m_fileName; String m_fileName;

View File

@@ -60,12 +60,10 @@
namespace sqdb namespace sqdb
{ {
class session::Sqlite3 : public SharedSingleton <Sqlite3> class session::Sqlite3
{ {
public: public:
friend class SharedSingleton <Sqlite3>; Sqlite3()
Sqlite3() : SharedSingleton <Sqlite3> (SingletonLifetime::persistAfterCreation)
{ {
int threadSafe = sqlite3_threadsafe(); int threadSafe = sqlite3_threadsafe();
@@ -84,30 +82,25 @@ public:
{ {
sqlite3_shutdown(); sqlite3_shutdown();
} }
static Sqlite3* createInstance()
{
return new Sqlite3;
}
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
session::session() session::session()
: prepare(this) : prepare (this)
, m_instance(Sqlite3::getInstance()) , m_instance (SharedSingleton <Sqlite3>::getInstance ())
, m_bInTransaction(false) , m_bInTransaction (false)
, m_connection(nullptr) , m_connection (nullptr)
{ {
} }
session::session(const session& deferredClone) session::session(const session& deferredClone)
: prepare(this) : prepare (this)
, m_instance(Sqlite3::getInstance()) , m_instance (SharedSingleton <Sqlite3>::getInstance ())
, m_bInTransaction(false) , m_bInTransaction (false)
, m_connection(nullptr) , m_connection (nullptr)
, m_fileName(deferredClone.m_fileName) , m_fileName (deferredClone.m_fileName)
, m_connectString(deferredClone.m_connectString) , m_connectString (deferredClone.m_connectString)
{ {
// shouldn't be needed since deferredClone did it // shouldn't be needed since deferredClone did it
//Sqlite::initialize(); //Sqlite::initialize();