Boost logo

Boost Users :

From: Timmo Stange (ts_at_[hidden])
Date: 2007-02-02 19:12:56


Peter Dimov wrote:

> 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.

That would effectively mean removing the tracking functionality
and introducing an exception handling policy to the signal
(which could be extended to other/all types of exceptions,
made configurable or parameterizable with a suitable template
argument) instead. The downside of it is that it loads off the
burden to ensure correct results on the exception safety of the
client code (which is usually less well tested than the library
code) and additionally makes finding potential problems more
difficult, because exceptions are silently swallowed by the signal
invocation.

> This doesn't address your concern that dead
> slots are only detected when called, but is it really a problem in practice?

I gave one (perhaps a little exotic) example for a valid use
of signals where this particular behaviour would disqualify it.
In many other cases it could at least result in unexpectedly
high memory usage. Think of a user interface that relays user
input from permanent elements (like a menu entry) to numerous
and often changing other elements (like list entries). For a
menu item that's never triggered by the user, you'd get an
ever-growing connection list with mostly dead connections.

Boost.Signals already solves this problem sufficiently well, by
only delaying the connection removal if the disconnect() call
originates from the signal call context and retrying to clean
up the entire list for every subsequent disconnect().

> 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. :-/

 From a user perspective I'd expect invocations to work concurrently,
while manipulations would require exclusive access, which shouldn't
be too difficult to implement (read_write_mutex).
I think the cost of invocations is what should be considered primarily
(and not for the benchmark results), which is why I criticized the
per-slot locking in Frank's implementation. But I agree with him
that optimization is something for later. I saw a suggestion to make
the thread-safety optional through a policy template parameter and
that sounds fine to me. What about an allocator parameter, btw (as
the signal is a slot container)?

Regards

Timmo Stange


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