Skip to content

Commit c3e6fde

Browse files
committed
shutdown: Use RAII TokenPipe in shutdown
1 parent 612f746 commit c3e6fde

File tree

1 file changed

+17
-39
lines changed

1 file changed

+17
-39
lines changed

src/shutdown.cpp

Lines changed: 17 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,15 @@
55

66
#include <shutdown.h>
77

8+
#include <logging.h>
9+
#include <util/tokenpipe.h>
10+
811
#include <config/bitcoin-config.h>
912

1013
#include <assert.h>
1114
#include <atomic>
1215
#ifdef WIN32
1316
#include <condition_variable>
14-
#else
15-
#include <errno.h>
16-
#include <fcntl.h>
17-
#include <unistd.h>
1817
#endif
1918

2019
static std::atomic<bool> fRequestShutdown(false);
@@ -24,25 +23,18 @@ std::mutex g_shutdown_mutex;
2423
std::condition_variable g_shutdown_cv;
2524
#else
2625
/** On UNIX-like operating systems use the self-pipe trick.
27-
* Index 0 will be the read end of the pipe, index 1 the write end.
2826
*/
29-
static int g_shutdown_pipe[2] = {-1, -1};
27+
static TokenPipeEnd g_shutdown_r;
28+
static TokenPipeEnd g_shutdown_w;
3029
#endif
3130

3231
bool InitShutdownState()
3332
{
3433
#ifndef WIN32
35-
#if HAVE_O_CLOEXEC && HAVE_DECL_PIPE2
36-
// If we can, make sure that the file descriptors are closed on exec()
37-
// to prevent interference.
38-
if (pipe2(g_shutdown_pipe, O_CLOEXEC) != 0) {
39-
return false;
40-
}
41-
#else
42-
if (pipe(g_shutdown_pipe) != 0) {
43-
return false;
44-
}
45-
#endif
34+
std::optional<TokenPipe> pipe = TokenPipe::Make();
35+
if (!pipe) return false;
36+
g_shutdown_r = pipe->TakeReadEnd();
37+
g_shutdown_w = pipe->TakeWriteEnd();
4638
#endif
4739
return true;
4840
}
@@ -59,17 +51,10 @@ void StartShutdown()
5951
// case of a reentrant signal.
6052
if (!fRequestShutdown.exchange(true)) {
6153
// Write an arbitrary byte to the write end of the shutdown pipe.
62-
const char token = 'x';
63-
while (true) {
64-
int result = write(g_shutdown_pipe[1], &token, 1);
65-
if (result < 0) {
66-
// Failure. It's possible that the write was interrupted by another signal.
67-
// Other errors are unexpected here.
68-
assert(errno == EINTR);
69-
} else {
70-
assert(result == 1);
71-
break;
72-
}
54+
int res = g_shutdown_w.TokenWrite('x');
55+
if (res != 0) {
56+
LogPrintf("Sending shutdown token failed\n");
57+
assert(0);
7358
}
7459
}
7560
#endif
@@ -96,17 +81,10 @@ void WaitForShutdown()
9681
std::unique_lock<std::mutex> lk(g_shutdown_mutex);
9782
g_shutdown_cv.wait(lk, [] { return fRequestShutdown.load(); });
9883
#else
99-
char token;
100-
while (true) {
101-
int result = read(g_shutdown_pipe[0], &token, 1);
102-
if (result < 0) {
103-
// Failure. Check if the read was interrupted by a signal.
104-
// Other errors are unexpected here.
105-
assert(errno == EINTR);
106-
} else {
107-
assert(result == 1);
108-
break;
109-
}
84+
int res = g_shutdown_r.TokenRead();
85+
if (res != 'x') {
86+
LogPrintf("Reading shutdown token failed\n");
87+
assert(0);
11088
}
11189
#endif
11290
}

0 commit comments

Comments
 (0)