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