Boost logo

Boost Users :

From: Timmo Stange (ts_at_[hidden])
Date: 2007-02-02 06:34:41


Timmo Stange wrote:
> Frank Mori Hess wrote:
>
>> One solution is to overload the signal::connect function with another
>> version that accepts an additional weak_ptr<void> argument, which
>> points to the object whose member function is being used as a slot.
[...]
> Both problems can be solved, of course, so please just see this as
> a reminder. The overall solution looks good.

I've thought a little more about it:
The original trackable solution isn't a real beauty by itself as it
is intrusive to entities which it actually tries to treat as "unaware
participants" from the functionality perspective. The trackable
objects shouldn't need to know that their lifetime is being monitored
by the connection. Your shared_ptr approach supports that notion much
better in my opinion, but I would prefer to keep it related to the
connection and not the signal and have most of the original flexibility
in there. How about using a tool like the function argument reference
wrappers to mark the tracked objects? The example for automatic
connection management would then look like this:

struct NewsMessageArea : public MessageArea
{
public:
   // ...

   void displayNews(const NewsItem& news) const
   {
     messageText = news.text();
     update();
   }
};

// ...
boost::shared_ptr<NewsMessageArea> newsMessageArea(new
        NewsMessageArea(/* ... */));
// ...
deliverNews.connect(boost::bind(&NewsMessageArea::displayNews,
                     boost::signals::track(newsMessageArea), _1));

The wrapper signals::track would expect a shared_ptr and transport
a weak_ptr. The information could be collected with visit_each just
like it is done now and the number of trackable objects would only
be limited by boost::bind. I think it is acceptable that the client
code must maintain a shared_ptr to the tracked instance, as that's
expressing rather well what is happening here (even though it
doesn't really share the ownership, it shares information about the
object).

> Patch attached.

Um, looks like I got it wrong. Fixed version attached.

Regards

Timmo Stange

46,47c46,62
< virtual void disconnect() = 0;
< virtual bool connected() const = 0;

---
> 				void disconnect() 
> 				{
> 					boost::mutex::scoped_lock lock(mutex);
> 					do_disconnect();
> 				}
> 				bool connected() const 
> 				{
> 					boost::mutex::scoped_lock lock(mutex);
> 					do_connected();
> 				}
> 
> 			private:
> 				virtual void do_disconnect() = 0;
> 				virtual bool do_connected() const = 0;
> 
> 				// mutex should be locked when slot is called, to prevent race with disconnect()
> 				mutable boost::mutex mutex;
58c73,75
< 				virtual void disconnect()
---
> 
> 			private:
> 				virtual void do_disconnect()
60d76
< 					boost::mutex::scoped_lock lock(mutex);
63c79
< 				virtual bool connected() const
---
> 				virtual bool do_connected() const
65d80
< 					boost::mutex::scoped_lock lock(mutex);
68d82
< 				// mutex should be locked when slot is called, to prevent race with disconnect()
70d83
< 				mutable boost::mutex mutex;

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net