Boost logo

Boost :

From: Borgerding, Mark A. (MarkAB_at_[hidden])
Date: 2000-03-03 16:52:22


> -----Original Message-----
> From: Jens Maurer [mailto:jmaurer_at_[hidden]]
> Sent: Friday, March 03, 2000 4:25 PM
> To: boost_at_[hidden]
> Subject: [boost] Re: shared_ptr co-existence with other smart pointers
...
>
> But, there are shared pointer variants such as linked_ptr<>
> which can inform all other instances that the underlying
> object is no longer managed by this linked_ptr<> cooperative.
> With these, it would be safe to call release(), because
> no other linked_ptr<> will try to delete the data storage,
> and accesses will try to dereference a NULL pointer, with the
> usual implementation-defined *bang*.

I though of several approaches to release().

Approach #1)
Notify everybody.

In this approach, every linked_ptr to a given heap object would be
nullified. The problem with this is that it could have unexpected results
in other threads.

void foobar(linked_ptr<foo> spFoo)
{
        if (spFoo.get())
        {
                // spFoo is not null, we checked.
                
                // Suppose the time slice is interrupted here
                // and spFoo is nullified.
                //
                spFoo->bar(); // BOOM!
        }
}

Conclusion:
        - Indirect results possible
        - Prone to difficult-to-find errors

Approach #2)
"I got mine. Don't worry 'bout his."

In this approach, a linked_ptr would mark the heap object as non-destroyable
and nullify itself. All connected linked_ptrs would still have the ptr, but
would know not to delete it.

Conclusion:
        - dangling pointers likely
        - Prone to difficult-to-find errors

Aprroach #3)
release only if unique() is true

This is the approach currently defined in linked_ptr:

   // element_type * release ()
   // Effects:
   // If unique() returns true: the previous value of get() is returned
and
   // the user claims responsibility for deletion.
   // If unique returns false: the previous value of get() will be
deleted
   // by other linked_ptr objects and 0 is returned.
   // Postcondition: get() thereafter returns 0
   element_type * release() {
      element_type * origPtr = 0;
      if ( unique() ) {
         origPtr = ptr;
         ptr = 0;// just give it up without deletion
      }else
         reset(0);// take *this out of list, leaving
      // responsibility for deletion to other nodes
      return origPtr;// null if not unique
   }

By using the return code of release to find out if the object was the last
reference, a user can avoid dangling pointers.

Conclusion:
        -Slight bias toward double-deletion, which makes it
        -Slightly prone to easy-to-find errors

All things considered, the conditional release may be a little less
powerful, but it is a lot more stable and predicatble than the other
approaches.

- Mark


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