tokenpipe.h raw
1 // Copyright (c) 2021-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 #ifndef BITCOIN_UTIL_TOKENPIPE_H
6 #define BITCOIN_UTIL_TOKENPIPE_H
7
8 #ifndef WIN32
9
10 #include <cstdint>
11 #include <optional>
12
13 /** One end of a token pipe. */
14 class TokenPipeEnd
15 {
16 private:
17 int m_fd = -1;
18
19 public:
20 TokenPipeEnd(int fd = -1);
21 ~TokenPipeEnd();
22
23 /** Return value constants for TokenWrite and TokenRead. */
24 enum Status {
25 TS_ERR = -1, //!< I/O error
26 TS_EOS = -2, //!< Unexpected end of stream
27 };
28
29 /** Write token to endpoint.
30 *
31 * @returns 0 If successful.
32 * <0 if error:
33 * TS_ERR If an error happened.
34 * TS_EOS If end of stream happened.
35 */
36 int TokenWrite(uint8_t token);
37
38 /** Read token from endpoint.
39 *
40 * @returns >=0 Token value, if successful.
41 * <0 if error:
42 * TS_ERR If an error happened.
43 * TS_EOS If end of stream happened.
44 */
45 int TokenRead();
46
47 /** Explicit close function.
48 */
49 void Close();
50
51 /** Return whether endpoint is open.
52 */
53 bool IsOpen() { return m_fd != -1; }
54
55 // Move-only class.
56 TokenPipeEnd(TokenPipeEnd&& other)
57 {
58 m_fd = other.m_fd;
59 other.m_fd = -1;
60 }
61 TokenPipeEnd& operator=(TokenPipeEnd&& other)
62 {
63 Close();
64 m_fd = other.m_fd;
65 other.m_fd = -1;
66 return *this;
67 }
68 TokenPipeEnd(const TokenPipeEnd&) = delete;
69 TokenPipeEnd& operator=(const TokenPipeEnd&) = delete;
70 };
71
72 /** An interprocess or interthread pipe for sending tokens (one-byte values)
73 * over.
74 */
75 class TokenPipe
76 {
77 private:
78 int m_fds[2] = {-1, -1};
79
80 TokenPipe(int fds[2]) : m_fds{fds[0], fds[1]} {}
81
82 public:
83 ~TokenPipe();
84
85 /** Create a new pipe.
86 * @returns The created TokenPipe, or an empty std::nullopt in case of error.
87 */
88 static std::optional<TokenPipe> Make();
89
90 /** Take the read end of this pipe. This can only be called once,
91 * as the object will be moved out.
92 */
93 TokenPipeEnd TakeReadEnd();
94
95 /** Take the write end of this pipe. This should only be called once,
96 * as the object will be moved out.
97 */
98 TokenPipeEnd TakeWriteEnd();
99
100 /** Close and end of the pipe that hasn't been moved out.
101 */
102 void Close();
103
104 // Move-only class.
105 TokenPipe(TokenPipe&& other)
106 {
107 for (int i = 0; i < 2; ++i) {
108 m_fds[i] = other.m_fds[i];
109 other.m_fds[i] = -1;
110 }
111 }
112 TokenPipe& operator=(TokenPipe&& other)
113 {
114 Close();
115 for (int i = 0; i < 2; ++i) {
116 m_fds[i] = other.m_fds[i];
117 other.m_fds[i] = -1;
118 }
119 return *this;
120 }
121 TokenPipe(const TokenPipe&) = delete;
122 TokenPipe& operator=(const TokenPipe&) = delete;
123 };
124
125 #endif // WIN32
126
127 #endif // BITCOIN_UTIL_TOKENPIPE_H
128