From c3e6fdee6d39d3f52dec421b48a0ac8bad5006f7 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 26 Jan 2021 19:34:47 +0100 Subject: shutdown: Use RAII TokenPipe in shutdown --- src/shutdown.cpp | 56 +++++++++++++++++--------------------------------------- 1 file changed, 17 insertions(+), 39 deletions(-) (limited to 'src/shutdown.cpp') diff --git a/src/shutdown.cpp b/src/shutdown.cpp index 6a73e0b2d8..2fc195e2d1 100644 --- a/src/shutdown.cpp +++ b/src/shutdown.cpp @@ -5,16 +5,15 @@ #include +#include +#include + #include #include #include #ifdef WIN32 #include -#else -#include -#include -#include #endif static std::atomic fRequestShutdown(false); @@ -24,25 +23,18 @@ std::mutex g_shutdown_mutex; std::condition_variable g_shutdown_cv; #else /** On UNIX-like operating systems use the self-pipe trick. - * Index 0 will be the read end of the pipe, index 1 the write end. */ -static int g_shutdown_pipe[2] = {-1, -1}; +static TokenPipeEnd g_shutdown_r; +static TokenPipeEnd g_shutdown_w; #endif bool InitShutdownState() { #ifndef WIN32 -#if HAVE_O_CLOEXEC && HAVE_DECL_PIPE2 - // If we can, make sure that the file descriptors are closed on exec() - // to prevent interference. - if (pipe2(g_shutdown_pipe, O_CLOEXEC) != 0) { - return false; - } -#else - if (pipe(g_shutdown_pipe) != 0) { - return false; - } -#endif + std::optional pipe = TokenPipe::Make(); + if (!pipe) return false; + g_shutdown_r = pipe->TakeReadEnd(); + g_shutdown_w = pipe->TakeWriteEnd(); #endif return true; } @@ -59,17 +51,10 @@ void StartShutdown() // case of a reentrant signal. if (!fRequestShutdown.exchange(true)) { // Write an arbitrary byte to the write end of the shutdown pipe. - const char token = 'x'; - while (true) { - int result = write(g_shutdown_pipe[1], &token, 1); - if (result < 0) { - // Failure. It's possible that the write was interrupted by another signal. - // Other errors are unexpected here. - assert(errno == EINTR); - } else { - assert(result == 1); - break; - } + int res = g_shutdown_w.TokenWrite('x'); + if (res != 0) { + LogPrintf("Sending shutdown token failed\n"); + assert(0); } } #endif @@ -96,17 +81,10 @@ void WaitForShutdown() std::unique_lock lk(g_shutdown_mutex); g_shutdown_cv.wait(lk, [] { return fRequestShutdown.load(); }); #else - char token; - while (true) { - int result = read(g_shutdown_pipe[0], &token, 1); - if (result < 0) { - // Failure. Check if the read was interrupted by a signal. - // Other errors are unexpected here. - assert(errno == EINTR); - } else { - assert(result == 1); - break; - } + int res = g_shutdown_r.TokenRead(); + if (res != 'x') { + LogPrintf("Reading shutdown token failed\n"); + assert(0); } #endif } -- cgit v1.2.3