Bitcoin Core 28.99.0
P2P Digital Currency
signalinterrupt.cpp
Go to the documentation of this file.
1// Copyright (c) 2022 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
6
7#ifdef WIN32
8#include <mutex>
9#else
10#include <util/tokenpipe.h>
11#endif
12
13#include <ios>
14#include <optional>
15
16namespace util {
17
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
28SignalInterrupt::operator bool() const
29{
30 return m_flag;
31}
32
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
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
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
int TokenWrite(uint8_t token)
Write token to endpoint.
Definition: tokenpipe.cpp:38
int TokenRead()
Read token from endpoint.
Definition: tokenpipe.cpp:56
static std::optional< TokenPipe > Make()
Create a new pipe.
Definition: tokenpipe.cpp:82
std::atomic< bool > m_flag