$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Anthony Williams (anthwil_at_[hidden])
Date: 2002-08-07 09:51:52
> From: Rob Stewart [mailto:stewart_at_[hidden]]
> Sent: 07 August 2002 15:31
> From: Andrew J Bromage <ajb_at_[hidden]>
> >     class something
> >     {
> >     public:
> >         const expensive_data&
> >         get_expensive()
> >         {
> >             m_once.call_once(&make_expensive_data);
> >             return *m_expensive;
> >         }
> > 	  something(const other_data& other)
> > 	    : m_other(other)
> > 	  {
> > 	  }
> >     private:
> >         boost::once m_once;
> >         std::auto_ptr<expensive_data> m_expensive;
> > 	  other_data m_other;
> >         void
> >         make_expensive_data()
> >         {
> >             m_expensive = new expensive_data(m_other);
> >         }
> >     };
> > 
> > Moreover (and this is what makes it tricky), I want to do it with as
> > little mutex contention as possible.  In particular I want to avoid
> > obtaining a lock when get_expensive() is called after the expensive
> > data has been created.
> 
> Is it that tricky?  If there was a static pointer that was 
> initialized to zero
> and was set to the address of the initialized object once 
> ready, then a simple
> test of the pointer would indicate whether a synchronized 
> check and possibly
> initialization is needed.
This is the double-checked locking pattern, which is not safe on some
architectures --- the non-NULL-ness of the pointer may become visible before
the pointed-to data, so it is no better than unchecked access to the data.
Anthony