« Return to Thread: [signals/threadsafe version] Atomic disconnects

Re: [signals/threadsafe version] Atomic disconnects

by Frank Mori Hess :: Rate this Message:

Reply to Author | View in Thread

On Friday 07 March 2008 02:50 am, Johan Torp wrote:

> A typical signals n' slots
> use case  is - at least for me:
>
> signal<void()> sig;
>
> class Foo{
>   Foo() {
>     con = sig.connect(bind(&Foo::some_func, this));
>  }
>
>   scoped_connection con;
>
>   void some_func() {}
> };
To have the connection disconnect on the Foo object's destruction, you're
supposed to pass a shared_ptr owning the object (either directly or
indirectly) to slot::track() before connecting the slot.  This insures the
object is not destroyed while a slot invocation is in progress (the signal
converts its weak_ptr copy to a shared_ptr while the slot runs), and
disconnects the slot when the tracked weak_ptr expires.  It does have the
drawback that you often can't track connections made in the constructor
though, since enable_shared_from_this doesn't work there.  I did provide
postconstructible/deconstruct_ptr to support postconstructors, although it
does all add up to a bit more typing.

I've attached an altered version of your example which does what I've
described.

--
Frank

[example.cpp]

#include <boost/deconstruct_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/postconstructible.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread_safe_signal.hpp>
#include <iostream>

boost::signal<void ()> sig;

class Foo: public boost::enable_shared_from_this<Foo>,
  public boost::postconstructible
{
public:
  static boost::shared_ptr<Foo> create()
  {
    return boost::deconstruct_ptr(new Foo());
  }
  virtual void postconstruct()
  {
    typedef typeof(sig) sig_type;
    sig.connect(
      sig_type::slot_type(&Foo::some_func, this).track(shared_from_this()));
  }
  void some_func()
  {
    std::cout << __PRETTY_FUNCTION__ << std::endl;
    /*...*/
  }
private:
  Foo() {/*...*/}
};

int main()
{
  boost::shared_ptr<Foo> f = Foo::create();
  sig();
  f.reset();
  sig();
  return 0;
}



_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

attachment0 (196 bytes) Download Attachment

 « Return to Thread: [signals/threadsafe version] Atomic disconnects