Re: question re. usage of "static" within static member functions of a class
"Paavo Helde" <paavo@nospam.please.ee> wrote in message
news:Xns9C805D9923BF8nobodyebiee@216.196.109.131...
[...]
In addition, in case of multithreaded applications I usually call all
such instance() methods in the beginning of the program (or in the init
routine of a dynamically loaded library), in order to avoid potential
thread clash in the singleton creation. One could attempt to protect the
singleton creation by a static mutex, but then one would be back at the
statics destruction order problems.
Perhaps I am misunderstanding you, but FWIW in POSIX, it's perfectly legal
to create a `pthread_mutex_t' in static storage. There is absolutely no
static's destruction order problems wrt to the mutex itself:
______________________________________________________________________
#include <pthread.h>
#include <exception>
#include <cassert>
#include <cstdio>
#if ! defined (PTHREAD_UNEXPECTED)
# define PTHREAD_UNEXPECTED(s) \
assert(! (s)), std::unexpected()
#endif
class lock_guard
{
pthread_mutex_t& m_mutex;
public:
lock_guard(pthread_mutex_t& mutex) throw()
: m_mutex(mutex)
{
int status = pthread_mutex_lock(&m_mutex);
if (status)
{
PTHREAD_UNEXPECTED(status);
}
}
~lock_guard() throw()
{
int status = pthread_mutex_unlock(&m_mutex);
if (status)
{
PTHREAD_UNEXPECTED(status);
}
}
};
template<typename T>
struct non_destroying_singleton
{
static T& instance()
{
static T* g_instance = NULL;
static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
lock_guard guard(g_mutex);
if (! g_instance)
{
g_instance = new T();
}
return *g_instance;
}
};
struct foo
{
foo()
{
std::printf("(%p)->foo::foo()\n", (void*)this);
}
~foo()
{
std::printf("(%p)->foo::~foo()\n", (void*)this);
}
};
int
main()
{
{
foo& f1 = non_destroying_singleton<foo>::instance();
foo& f2 = non_destroying_singleton<foo>::instance();
foo& f3 = non_destroying_singleton<foo>::instance();
foo& f4 = non_destroying_singleton<foo>::instance();
foo& f5 = non_destroying_singleton<foo>::instance();
}
return 0;
}
______________________________________________________________________
The singleton template code above `non_destroying_singleton<T>' is 100%
thread-safe.