init: Signal-safe instant shutdown

Replace the 200ms polling loop with a faster and more efficient waiting
operation.

This was tried a few times before, but given up every time because
solutions use a condition variable which is not safe for use in signals
as they need to be reentrant.

On UNIX-ish OSes, use a safe way: a pipe. When shutdown is requested
write a dummy byte to the pipe. Waiting for shutdown is a matter of a
blocking read from the pipe.

On Windows, there are no signals so using a condition variable is safe.
This commit is contained in:
Wladimir J. van der Laan
2020-12-08 21:49:06 +01:00
parent 16b31cc4c5
commit cd03513dc2
4 changed files with 112 additions and 14 deletions

View File

@@ -917,6 +917,9 @@ bool AppInitBasicSetup(const ArgsManager& args)
// Enable heap terminate-on-corruption
HeapSetInformation(nullptr, HeapEnableTerminationOnCorruption, nullptr, 0);
#endif
if (!InitShutdownState()) {
return InitError(Untranslated("Initializing wait-for-shutdown state failed."));
}
if (!SetupNetworking()) {
return InitError(Untranslated("Initializing networking failed."));