singleton

I

Ian Collins

Kai-Uwe Bux said:
Ian said:
James said:
[...]
public:
static A *getInstance(){
if(a==null)
{
a=new A(); //remeber delete it..
This form is only really useful if you intend to delete the
singleton.
This form is the most usual case in my code, precisely because I
don't want to delete the singleton. In fact, I don't even want
its destructor to ever be called.
If you don't want to delete the instance, why not use a "block scope
static variable"?

Aren't static objects destructed at the end of the program?
Fair point, but we should clean up after our selves!
 
K

Kai-Uwe Bux

Ian said:
Kai-Uwe Bux said:
Ian said:
James Kanze wrote:

[...]
public:
static A *getInstance(){
if(a==null)
{
a=new A(); //remeber delete it..
This form is only really useful if you intend to delete the
singleton.
This form is the most usual case in my code, precisely because I
don't want to delete the singleton. In fact, I don't even want
its destructor to ever be called.

If you don't want to delete the instance, why not use a "block scope
static variable"?

Aren't static objects destructed at the end of the program?
Fair point, but we should clean up after our selves!

James explicitly stated that he does not want the destructor called. Your
crystal ball must be very good if you feel that you have a good reason to
second guess that requirement. I recall that the desire or need to destroy
a singleton can create problems with other code needing to access the
singleton after it has been destroyed. In such cases, you might be much
better off with a singleton that simply isn't destructed.


Best

Kai-Uwe Bux
 
I

Ian Collins

Kai-Uwe Bux said:
Ian said:
Kai-Uwe Bux said:
Ian Collins wrote:

James Kanze wrote:

[...]
public:
static A *getInstance(){
if(a==null)
{
a=new A(); //remeber delete it..
This form is only really useful if you intend to delete the
singleton.
This form is the most usual case in my code, precisely because I
don't want to delete the singleton. In fact, I don't even want
its destructor to ever be called.

If you don't want to delete the instance, why not use a "block scope
static variable"?
Aren't static objects destructed at the end of the program?
Fair point, but we should clean up after our selves!

James explicitly stated that he does not want the destructor called.

I know, pre-caffeine humour...
 
C

Chris Thomasson

Rahul said:
For the same what? The implementation should guarantee the static
variable is initialised once only.
[...]

for thread safety...

You have to make sure the object is fully visible before you return a
reference; you could do it like:

<error checking omitted for simplicity...>
_______________________________________________________________
template<typename T>
class once {
static T* m_state;
static pthread_mutex_t m_mtx;


public:
static T* get() {
T* local = ATOMIC_LOADPTR_MBDEPENDS(&m_state);
if (local == NULL) {
pthread_mutex_lock(&m_mtx);
if ((local = m_state) == NULL) {
try {
local = new T;
} catch (...) {
pthread_mutex_unlock(&m_mtx);
throw;
}
ATOMIC_STOREPTR_MBRELEASE(&m_state, local);
}
pthread_mutex_unlock(&m_mtx);
}
return local;
}
};


template<typename T>
T* once<T>::m_state = NULL;

template<typename T>
pthread_mutex_t once<T>::m_mtx = PTHREAD_MUTEX_INITIALIZER;
_______________________________________________________________


The 'ATOMIC_LOADPTR_MBDEPENDS()' function performs an atomic pointer load
followed by a data-dependant memory-barrier (e.g., read_barrier_depends() in
Linux). The 'ATOMIC_STOREPTR_MBRELEASE()' function executes a release
memory-barrier (e.g., wmb() in Linux or #LoadStore | #StoreStore in SPARC)
followed by an atomic pointer store. This is necessary to maintain proper
memory visibility of the object your storing/loading to/from the
'once<T>::m_state' member...
 
C

Chris Thomasson

Here is another way to do it:

<error check omitted...>
_______________________________________________________________
#include <pthread.h>


extern "C" void once_base_init(void*);


class once_base {
friend void once_base_init(void*);
virtual void on_init() = 0;
};


void once_base_init(void* state) {
reinterpret_cast<once_base*>(state)->on_init();
}


template<typename T>
class once : private once_base {
static T* m_state;
static pthread_once_t m_once;

void on_init() {
m_state = new T;
}


public:
static T* get() {
pthread_once(&m_once, once_base_init);
return m_state;
}
};


template<typename T>
T* once<T>::m_state = NULL;

template<typename T>
pthread_once_t once<T>::m_once = PTHREAD_ONCE_INIT;
_______________________________________________________________


This is probably the best method because it uses 100% PThread calls; you
don't need atomics and membars.
 
C

Chris Thomasson

Chris Thomasson said:
Here is another way to do it:

<error check omitted...>
_______________________________________________________________ [...]
_______________________________________________________________


This is probably the best method because it uses 100% PThread calls; you
don't need atomics and membars.

STUPID!
STUPID!
STUPID!
STUPID!
STUPID!
STUPID!
STUPID!

ARGH!

I totally forgot that pthread_once does not allow you to pass any state!!!

Sorry about that!


;^(...
 
C

Chris Thomasson

Chris Thomasson said:
Chris Thomasson said:
Here is another way to do it:

<error check omitted...>
_______________________________________________________________ [...]
_______________________________________________________________


This is probably the best method because it uses 100% PThread calls; you
don't need atomics and membars.

STUPID!
STUPID!
STUPID!
STUPID!
STUPID!
STUPID!
STUPID!

ARGH!

I totally forgot that pthread_once does not allow you to pass any state!!!

Sorry about that!


;^(...

LOL! that's too funny.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,608
Members
45,249
Latest member
KattieCort

Latest Threads

Top