Frank Mori Hess wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On Friday 02 February 2007 06:34 am, Timmo Stange wrote:
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.
Okay, I think I've got it now. The signals::track() wrapper would return some class, call it signals::tracked for now, which is implicitly convertible into a weak_ptr. The code in signal::connect() would use visit_each on the return value from bind to look for any signals::tracked objects inside, and if found store them as weak_ptrs associated with the connection. Then any slots with expired weak_ptrs could be cleaned up when the signal is next emitted, or also in signal::connect() to prevent lots of dead connections from accumulating.
My old (and reiterated) suggestion was to eliminate all the tracking complexity on the signal side and just make the invocation disconnect a slot when it throws bad_weak_ptr. We can make mem_fn convert a weak_ptr argument to a shared_ptr (by abusing get_pointer for weak_ptr) to cover the typical bind( &X::f, wp, ... ) case. This doesn't address your concern that dead slots are only detected when called, but is it really a problem in practice? The remaining thread-safety problem is what happens when a signal is manipulated while being invoked, and are multiple concurrent invocations allowed. The nontrivial part is to solve it without making the invocation performance suffer horribly, which is what people love to benchmark. :-/