Bitcoin ABC 0.32.4
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#ifndef WIN32
20 std::optional<TokenPipe> pipe = TokenPipe::Make();
21 if (!pipe) {
22 throw std::ios_base::failure("Could not create TokenPipe");
23 }
24 m_pipe_r = pipe->TakeReadEnd();
25 m_pipe_w = pipe->TakeWriteEnd();
26#endif
27}
28
29SignalInterrupt::operator bool() const {
30 return m_flag;
31}
32
34 // Cancel existing interrupt by waiting for it, this will reset condition
35 // flags and remove the token from the pipe.
36 if (*this) {
37 wait();
38 }
39 m_flag = false;
40}
41
43#ifdef WIN32
44 std::unique_lock<std::mutex> lk(m_mutex);
45 m_flag = true;
46 m_cv.notify_one();
47#else
48 // This must be reentrant and safe for calling in a signal handler, so using
49 // a condition variable is not safe. Make sure that the token is only
50 // written once even if multiple threads call this concurrently or in case
51 // 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 throw std::ios_base::failure("Could not write interrupt token");
57 }
58 }
59#endif
60}
61
63#ifdef WIN32
64 std::unique_lock<std::mutex> lk(m_mutex);
65 m_cv.wait(lk, [this] { return m_flag.load(); });
66#else
67 int res = m_pipe_r.TokenRead();
68 if (res != 'x') {
69 throw std::ios_base::failure("Did not read expected interrupt token");
70 }
71#endif
72}
73
74} // namespace util
int TokenWrite(uint8_t token)
Write token to endpoint.
Definition: tokenpipe.cpp:32
int TokenRead()
Read token from endpoint.
Definition: tokenpipe.cpp:49
static std::optional< TokenPipe > Make()
Create a new pipe.
Definition: tokenpipe.cpp:75
std::atomic< bool > m_flag