
On Monday 05 February 2007 03:57 am, Timmo Stange wrote:
Another update: I've added tracking similar to what I described before. It now passes the random_signal_test except for the final connection count check, which may be a result of the different signal and connection lifetime control I had to use. I ran it with 20 initial signals, a deletion probability of 0.5 and 10000 iterations and it never called a slot with a dead tracked weak_ptr, which is what we want. It also cleans up those slots for each connect() call.
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.
The tracking functionality is still somewhat ugly and its per- formance is horrible, but I think it's a starting point. The signals::tracked<...> wrapper template currently only offers implicit conversion to a shared_ptr, which won't enable binding a pointer to member function to it, so it probably needs a full smart pointer interface.
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.
I've also thought about the use of recursive_mutex. I could be turned into a normal mutex if the implementation would unlock it before each slot call and lock it again after that.
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. 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 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. -- Frank