Bitcoin Core
31.0.0
P2P Digital Currency
Loading...
Searching...
No Matches
src
util
signalinterrupt.cpp
Go to the documentation of this file.
1
// Copyright (c) 2022-present The Bitcoin Core developers
2
// Distributed under the MIT software license, see the accompanying
3
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5
#include <
util/signalinterrupt.h
>
6
7
#ifdef WIN32
8
#include <mutex>
9
#else
10
#include <
util/tokenpipe.h
>
11
#endif
12
13
#include <ios>
14
#include <optional>
15
16
namespace
util
{
17
18
SignalInterrupt::SignalInterrupt
() :
m_flag
{false}
19
{
20
#ifndef WIN32
21
std::optional<TokenPipe> pipe =
TokenPipe::Make
();
22
if
(!pipe)
throw
std::ios_base::failure(
"Could not create TokenPipe"
);
23
m_pipe_r
= pipe->TakeReadEnd();
24
m_pipe_w
= pipe->TakeWriteEnd();
25
#endif
26
}
27
28
SignalInterrupt::operator bool()
const
29
{
30
return
m_flag
;
31
}
32
33
bool
SignalInterrupt::reset
()
34
{
35
// Cancel existing interrupt by waiting for it, this will reset condition flags and remove
36
// the token from the pipe.
37
if
(*
this
&& !
wait
())
return
false
;
38
m_flag
=
false
;
39
return
true
;
40
}
41
42
bool
SignalInterrupt::operator()
()
43
{
44
#ifdef WIN32
45
std::unique_lock<std::mutex> lk(m_mutex);
46
m_flag
=
true
;
47
m_cv.notify_one();
48
#else
49
// This must be reentrant and safe for calling in a signal handler, so using a condition variable is not safe.
50
// Make sure that the token is only written once even if multiple threads call this concurrently or in
51
// case of a reentrant signal.
52
if
(!
m_flag
.exchange(
true
)) {
53
// Write an arbitrary byte to the write end of the pipe.
54
int
res =
m_pipe_w
.TokenWrite(
'x'
);
55
if
(res != 0) {
56
return
false
;
57
}
58
}
59
#endif
60
return
true
;
61
}
62
63
bool
SignalInterrupt::wait
()
64
{
65
#ifdef WIN32
66
std::unique_lock<std::mutex> lk(m_mutex);
67
m_cv.wait(lk, [
this
] {
return
m_flag
.load(); });
68
#else
69
int
res =
m_pipe_r
.TokenRead();
70
if
(res !=
'x'
) {
71
return
false
;
72
}
73
#endif
74
return
true
;
75
}
76
77
}
// namespace util
TokenPipe::Make
static std::optional< TokenPipe > Make()
Create a new pipe.
Definition
tokenpipe.cpp:82
util::SignalInterrupt::reset
bool reset()
Definition
signalinterrupt.cpp:33
util::SignalInterrupt::m_pipe_r
TokenPipeEnd m_pipe_r
Definition
signalinterrupt.h:42
util::SignalInterrupt::m_flag
std::atomic< bool > m_flag
Definition
signalinterrupt.h:38
util::SignalInterrupt::SignalInterrupt
SignalInterrupt()
Definition
signalinterrupt.cpp:18
util::SignalInterrupt::m_pipe_w
TokenPipeEnd m_pipe_w
Definition
signalinterrupt.h:43
util::SignalInterrupt::operator()
bool operator()()
Definition
signalinterrupt.cpp:42
util::SignalInterrupt::wait
bool wait()
Definition
signalinterrupt.cpp:63
util
Definition
httpserver.h:13
signalinterrupt.h
tokenpipe.h
Generated on
for Bitcoin Core by
1.16.1