|
Boost : |
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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk