Boost logo

Boost Users :

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


Frank Mori Hess wrote:

> We could implement a thread-safe post-disconnect callback by using the
> existing tracking functionality. That is, the connection body could hold
> a "cleanup" shared_ptr with a custom deleter. The custom deleter would
> run the user's cleanup callback. A weak_ptr copy of the cleanup
> shared_ptr would be kept just like it was any other tracked object. When
> disconnect() is called, the cleanup shared_ptr would be reset. If the
> signal is being invoked concurrently when disconnect() is called, the
> cleanup code won't get run until the last invocation is done with the slot
> and destroys its copy of the cleanup shared_ptr.

I think we should perhaps first decide on the interface and behavior
before we discuss an implementation. That cleanup callback should be
optional, without parameters and return value, right? I also think
it should be called synchronously directly from disconnect if the
slot is not running - otherwise from the executing thread directly
after the slot returns.

I don't directly see the necessity for a shared_ptr there and I
have to express my performance worries again. As nice as shared_ptr's
thread-safety is, it doesn't come for free. If you store the callback
in a Boost.Function object maintained by a shared pointer, we're
talking about a minimum of three heap allocations (2 for the
function and 1 for the reference count) - with most allocator
implementations, those allocations imply process-global synchro-
nization. The smart pointer itself (including all temporary copies
and the creation from a weak_ptr) uses atomic reference counting.
Both are scalability issues (mostly the synchronization) and
exceptionally heavy in simple absolute runtime cost (as much as
50 times the cost of a simple object copy and more, depending
on the CPU and system).

I really hate to play the optimization freak here, but we should
keep an eye on those things, because if the abstraction the
library provides comes at a too high runtime cost, the usability
is severely limited. I usually avoid heap allocations in library
code and if I need to have them, I try to provide an optional
allocator template.

> BTW, I've added support for a two-parameter version of signals::track() to
> thread_safe_signals/track.hpp. It seems to work okay, the only thing I
> don't like about it is it implies there a coupling required between the
> value and the tracked shared_ptr, when really there isn't.

Could you give a short example of how that would look with using bind
and a simple free function expecting a pointer or reference to an
object that should be tracked?

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