From: Douglas Paul Gregor (gregod_at_[hidden])
Date: 2004-05-05 14:51:07
On Wed, 5 May 2004, Eric Niebler wrote:
> > We could be executing in Signal A and in Signal B simultaneously; then,
> > slot c or d deletes object o (causing slots a, b, c, d to be
> > disconnected). It's okay in Signal A--Signals was design for this--but can
> > we be sure that Signal B won't fail?
> I think I see the problem, but I don't know enough about trackable
> objects to say for sure whether it can be fixed. But it seems to be that
> in step (3i) below (which copies the slot into a local variable while
> the lock is still held) that the local variable should be able to keep a
> trackable object alive long enough to complete the slot call, even if it
> has been "deleted" in another thread.
It's really a user error we're trying to prevent. The user has said
"delete o" when another thread is using "o" within a slot. The only way to
stop the deletion is to acquire a lock in the destructor of a trackable
object and wait until the call is done, but that's playing with fire :)
> At the very least it should be
> possible to implement it such that a zombie trackable object can be
> detected so that calling a zombie slot has well-defined behavior.
That might be doable. I haven't much thought about the locking strategy
for trackable objects, although it's probably just a trivial mutex around
the list of connections.
> >>3) slot_iterator::operator* does the following:
> >> i) copies the slot into a local
> > Might not actually need this step, because the slot itself cannot be
> > deleted at this point.
> I don't think you can skip this step. Consider the next two steps:
> >> ii) releases the lock
> >> iii) calls the slot through the local
> Imagine another thread nulls out the slot between (ii) and (iii). If you
> access the slot directly instead of through a local, you're in for
> trouble. And as I mentioned above, the local variable might be able to
> do some lifetime management for trackable objects.
It depends on what "nulls out" means. Within the current Signals
architecture, the slot itself is unaffected by the disconnect operation,
which touches only the associated connection... it's like having a
pair<bool, slot>, so we can set the bool false (meaning: "don't use this
slot") without affecting someone that's already calling through that slot.