(Split out and rewritten chunk of #8631. I’ll rebase that on top of this post-merge and reopen.)
This is a prerequisite for async network handling. As-is, we don’t have enough control over the shutdown process to be able to deal with async connecting and send/recv.
In particular, we need to be sure that message processing has shut down before forcing all networking down, otherwise we run the risk of trying to process a node’s messages during its destruction. This is not a problem now because the current sync model works fine with all threads being interrupted at the same time.
And if that’s not a satisfactory reason for the change, it also gets rid of a nice chunk of boost threading (and simplifies the rebase of #8631 :)
To accomplish this, we need to:
- Set a flag to interrupt all net threads
- notify all blocked condvars
- replace MilliSleep (since they’re boost interruption points)
- teach init to Interrupt/Stop, similar to some of the other subsystems.
The MilliSleeps are replaced with condvars that check for the thread’s interrupt flag. Since the flags are atomic, there’s no need for real locking, so these condvars use a dummy CNullLock.
With all of that done, we may as well switch away from boost threads, since we’re no longer dependent on interruption. @TheBlueMatt 3f3f0b4bce0fb34e803b4893594b44df1f2effe3 is the awkward change I mentioned on IRC. The global will be cleaned up when we move processing into a class as a next step (something like https://github.com/theuni/bitcoin/commit/3f598dbe7100c7c6c7bfb7e10210585327ed9d31)