Make dormant be a postage::watch
We need to replace the AtomicBool for dormant mode with something that can wake up tasks. postage::watch is the closest thing I found which is the right shape, and which we can use. (tokio has a watch which is better than postage's but it's not available to us.)
The dormancy handling should all be downstream of the watch, so that it is not possible to accidentally bypass it by setting the watch directly. (I think there may be a pre-existing bug here which I fix, since wait_for_bootstrap
sets the dormant mode but didn't fire up the periodic tasks - but maybe the bootstrap code will do that?)
There are some flies in this ointment:
-
postage::watch does not signal receivers when the sender is dropped. But in order to centralise the dormancy logic downstream of the watch, we end up introducing a task whose job is solely to listen on the watch. That task needs to go away when the (last)
TorClient
does. So we need some mechanism to be able to detect this situation. The most natural approach, seemed to me, to make this part of what the dormant watch receivers get. -
postage::watch does not provide a cooked way to update the value but notify senders only if it has changed. This is a SMOP, but slightly fiddly.
For both of these I chose to break this functionality out as its own facility in tor-basic-utils, rather than open-coding a solution. So this MR contains two extensions to postage::watch.