Frank Mori Hess wrote:
Is there any reason not to put your code into the boos sandbox cvs? It won't conflict with any of my files, as my file and subdirectory name are different. If you do put it in, it might be useful to check in the unmodified boost.signals files as the initial commit, so the cvs can diff all the way back to the originals.
I just didn't want to bother Doug on the Super Bowl weekend ;). I've asked for write access now and will do as you suggest (based on the current CVS - I don't know if there are any relevant differences to 1.33.1, but that's the code I used).
Wouldn't it be cleaner (and perhaps more robust) to just have lock() return a shared_ptr<void> and get rid of the unlock() and shared_ptr member variable? I'm going to try playing around with your file a bit in EPG::signal today.
You need to store the smart_ptrs to an arbitrary amount of tracked objects for the duration of the slot call and I thought it might be more practical to use the tracker (I don't use the client's tracked object) for that instead of creating another scoped con- tainer.
Then the invocation of a slot won't be atomic with respect to the slot being disconnected. It seems worthwhile to me that we should guarantee the slot isn't still running (in any other thread) when disconnect() returns.
I agree. I also realized that this would allow concurrent invocation and I don't think that's expected behaviour.
There's also the matter of what happens in a combiner if a slot it hasn't reached yet is disconnected while it is running, which also will affect EPG::signal since it allows disconnect to happen during signal invocation, as long as the particular slot in question is not running. I was planning to make the slot iterator dereference operation throw an exception if the slot has been disconnected.
I'm not sure I understood this correctly. It should be ok for the client to disconnect slots that already have been called or will be called from an invocation context. That's what you have the ordering for. And it's no problem for the signal either.
I'm also thinking lock contention could be reduced in EPG::signal by making connect() make a new copy of the slot list when a new connection is added, which would allow connect() to return while an signal invocation is still in progress. Already running invocations would continue to iterate over the old slot list, and later invocations would get the updated one. It could be optimized to only create a new copy if a signal invocation is actually in progress.
You'd need a second mutex for that to synchronize concurrent connect() calls in one way or the other. I don't know if that's worth the trouble. Regards Timmo Stange