Boost logo

Boost :

From: Joao Abecasis (jpabecasis_at_[hidden])
Date: 2005-09-08 18:48:45


Anthony Williams wrote:
> Alexander Terekhov <terekhov_at_[hidden]> writes:
>
>
>>Anthony Williams wrote:
>>
>>>However, our once_flag can store a result of a user-defined type, which may
>>>therefore require proper destruction, so that it can notify other processes,
>>>send network packets, write to a file, or whatever; this therefore needs
>>>dealing with somehow before process termination.
>>
>>User would then call _destroy() or _reset() (the later is likely
>>to be called multiple times). I won't tell you "how". Trade secret.
>
>
> Don't be such a tease!
>
> class X
> {
> public
> X()
> {
> acquire_resource();
> }
> void do_something();
> ~X()
> {
> release_resource();
> }
> };
>
> X get_X();
>
> void f()
> {
> static once_flag once;
> call_once(get_X,once).do_something();
> // how do we clean up the X associated with "once", and release it's
> // resource?
> // We can't sensibly call once_destroy() here.
> }

I have written a static_<...> template class that uses boost::call_once
to (I suppose) offer thread-safe initialization of what amounts to
static data. Use case:

void f()
{
     static_<X> x;
}

This seems equal in purpose to what you're now seeking to offer with the
new call_once.

Here's the abbreviated implementation of static_,

     template < ... >
     struct static_
     {
         static_()
         {
             struct constructor
             {
                 static void construct()
                 {
                     new (get_address()) value_type();

                     // Schedule the object for destruction
                     static destructor d;
                 }
             };

             // Ensure constructor is called only once
             boost::call_once(&constructor::construct,
                 constructed_);
         }

     private:
         static pointer get_address()
         {
             return static_cast<pointer>(data_.address());
         }

         struct destructor
         {
             ~destructor()
             {
                 get_address()->~value_type();
             }
         };

         // static storage for object and flag
         static boost::aligned_storage< ... > data_;
         static boost::once_flag constructed_;
     };

I'd like to hear your views on the flaws and shortcomings with this
approach.

Regards,

João


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk