5
5
6
6
#include < shutdown.h>
7
7
8
+ #include < logging.h>
9
+ #include < util/tokenpipe.h>
10
+
8
11
#include < config/bitcoin-config.h>
9
12
10
13
#include < assert.h>
11
14
#include < atomic>
12
15
#ifdef WIN32
13
16
#include < condition_variable>
14
- #else
15
- #include < errno.h>
16
- #include < fcntl.h>
17
- #include < unistd.h>
18
17
#endif
19
18
20
19
static std::atomic<bool > fRequestShutdown (false );
@@ -24,25 +23,18 @@ std::mutex g_shutdown_mutex;
24
23
std::condition_variable g_shutdown_cv;
25
24
#else
26
25
/* * 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.
28
26
*/
29
- static int g_shutdown_pipe[2 ] = {-1 , -1 };
27
+ static TokenPipeEnd g_shutdown_r;
28
+ static TokenPipeEnd g_shutdown_w;
30
29
#endif
31
30
32
31
bool InitShutdownState ()
33
32
{
34
33
#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 ();
46
38
#endif
47
39
return true ;
48
40
}
@@ -59,17 +51,10 @@ void StartShutdown()
59
51
// case of a reentrant signal.
60
52
if (!fRequestShutdown .exchange (true )) {
61
53
// 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 );
73
58
}
74
59
}
75
60
#endif
@@ -96,17 +81,10 @@ void WaitForShutdown()
96
81
std::unique_lock<std::mutex> lk (g_shutdown_mutex);
97
82
g_shutdown_cv.wait (lk, [] { return fRequestShutdown .load (); });
98
83
#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 );
110
88
}
111
89
#endif
112
90
}
0 commit comments