Peter Dimov wrote:
But then you need to deal with the possibility that a call can already be in progress at the time your destructor is invoked. (If you can guarantee that this cannot happen, it seems to me that you can also guarantee that a call isn't started after the disconnect.) So let's assume that you lock the object mutex. There's still the nasty scenario where:
~X locks the object mutex X::f is called by the signal and blocks on the object mutex ~X disconnects and destroys *this, including the object mutex X::f crashes and burns
I can't think of a way to avoid the above that doesn't also solve the "call after disconnect" problem.
Let me give you a short summary of how Frank and I plan to provide tracking for the thread-safe Signals implementation: The client has to maintain ownership of objects to track through shared_ptr. It informs the signal that it wants those objects to be tracked by wrapping that shared_ptr in a signals::tracked object (with a signals::track() helper function for bind(...) et al.). The signal holds the reference to that object as a weak_ptr and will not call the associated slot if it is expired. Otherwise it will hold a local shared_ptr to that object during the slot call, ensuring its lifetime for the duration. The scenario you're discussing is much better handled using that tracking functionality, especially as it makes manual disconnection completely unnecessary. I think it only needs proper documentation to keep the user from trying stunts like the above - provided they read it... Regards Timmo Stange