
----- Original Message ----- From: "Andrew Chinkoff" <achinkoff@gmail.com> To: <boost@lists.boost.org> Sent: Wednesday, January 27, 2010 10:48 PM Subject: Re: [boost] [Boost.utility]
Ok, I see. I would try to explain.
Let us look at pseudo code:
<snip>
*** BEGIN EXPLANATION *** Let us imagine that boost::call_once has approximately this implementation (in pseudo code):
call_once(function foo) { if(!called) { Locker locker; if(!called) { called = true; foo(); (1) } } }
If you insert foo code at line (1), you will see the cascade of nested blocks like this:
if(!flag1) { Locker locker; if(!flag2) // "Double Check Locking" { Locker locker; if(!flag3) // "Triple Check Locking" { Locker locker; ... ... ... foo(); ... ... ... } } }
<snip>
I assume that boost::call_once does so:
if(ATOMIC(!flag1)) // (2) { Locker locker; ... }
I would like to ask Boost.Commutiny - is my assumption at line (2) the true? *** END OF EXPLANATION ***
P.S. 1: Sorry for verbosity and complexity, if so.
Andrew, you don't need to make supossitions on how call_once works. Just see the current implementation for Posix systems (extracted from boost/thread/posinx/once.hpp): template<typename Function> void call_once(once_flag& flag,Function f) { static boost::uintmax_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE; static boost::uintmax_t const being_initialized=uninitialized_flag+1; boost::uintmax_t const epoch=flag.epoch; boost::uintmax_t& this_thread_epoch=detail::get_once_per_thread_epoch(); if(epoch<this_thread_epoch) { pthread::pthread_mutex_scoped_lock lk(&detail::once_epoch_mutex); while(flag.epoch<=being_initialized) { if(flag.epoch==uninitialized_flag) { flag.epoch=being_initialized; try { pthread::pthread_mutex_scoped_unlock relocker(&detail::once_epoch_mutex); f(); } catch(...) { flag.epoch=uninitialized_flag; BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv)); throw; } flag.epoch=--detail::once_global_epoch; BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv)); } else { while(flag.epoch==being_initialized) { BOOST_VERIFY(!pthread_cond_wait(&detail::once_epoch_cv,&detail::once_epoch_mutex)); } } } this_thread_epoch=detail::once_global_epoch; } } Now you can make a concrete request on a concrete implementation. Best, Vicente