
"Roland Schwarz" <roland.schwarz@chello.at> wrote in message news:45463A2F.8030209@chello.at...
Chris Thomasson wrote:
[...]
In this discussion we came to the conclusion that the problem with this scheme is not the construction, but the destruction.
When will the destructor of this object being run?
Well, I guess you can do something like this: First of all, imagine I added a cas function to atomic::var... template<typename T> class once { // I forgot to make this a ptr in the pseudo-code! Argh... var<T*> m_state; // we can add a counter... var<intword_t> m_count; private: bool try_dec() throw() { intword_t local; do { local = m_count.load(mb::naked); if (! local || local < 1) { return false; } // use mb::fence to cover *both acquire and release // wrt the result of the decrement } while(! m_count.cas(local, local - 1, mb::fence)); return (local == 1); } bool try_inc() throw() { intword_t local; do { local = m_count.load(mb::naked); if (! local || local < 1) { return false; } } while(! m_count.cas(local, local + 1, mb::acquire)); return true; } public: once() throw() : m_state(0), m_count(1) {} ~once() throw() { if (try_dec()) { try { delete local; } catch(...) { assert(false); throw; } } } public: // atomic load / thread-saftey: strong T* load() const { T *local = m_state.load(mb::depends); if (! local) { externlib_api::hashed_mutex::guard_t const &lock(this); if (! try_inc()) { return 0; } local = m_state.load(mb::naked); if (! local) { // call try_dec on exceptions... local = new T; m_state.store(local, mb::release); } } else if(! try_inc()) { return 0; } return local; } // dec the refcount void dec() { if (try_dec()) { delete local; } } }; * : http://groups.google.com/group/comp.programming.threads/browse_thread/thread... What do you think?