Boost logo

Boost :

From: Bronek Kozicki (brok_at_[hidden])
Date: 2004-01-15 05:24:23


On Wed, 14 Jan 2004 16:46:25 -0800 (PST), Sean Kelly wrote:
> Currently, there's no way to force a shared_ptr to release something once
> it has been given ownership of it. I've run into instances where I use a

There is a way, and I will show you how I did it in my production code
(single-threaded at this moment, but I think you will have no trouble to
make it concurrency-safe).

class node : public boost::noncopyable // plus some more parent classes
{
private:
  struct deleter
  {
    bool released;

    deleter() : released(false) {}

    void operator() (node* p)
    {
      if (!released)
        delete p;
    }
  };
  
  friend class std::auto_ptr<node>;
  friend void boost::checked_delete<node>(node* x);

  typedef std::vector<boost::shared_ptr<node> > children_collection;

  children_collection children2_;
  node* parent_;
// ...

public:
  std::auto_ptr<node> remove()
  {
    // ...
    boost::shared_ptr<node> me;
    {
      children_collection children2;
      for (children_collection::const_iterator ci =
parent_->children2_.begin(); ci != parent_->children2_.end(); ++ci)
      {
        // simplified, real production code is different
        if (ci->get() != this)
          children2.push_back(*ci);
        else
          me = (*ci);
      }

      parent_->children2_.swap(children2);
    }

    std::auto_ptr<node> me2;
    {
      // you would lock critical section or mutex here, and such
      // synchronization primitive could be stored inside deleter
      assert(me.unique());
      me2.reset(me.get());
      boost::get_deleter<deleter>(me)->released = true;
      me.reset();
    }

    return me2;
  }
}

It's bit complicated and I'm not happy with it, but it works and seems
to be reliable

B.


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