Branch data Line data Source code
1 : : // Copyright (c) 2021 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 [ # # ]: 0 : 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 : 1172 : TokenPipeEnd& operator=(TokenPipeEnd&& other)
62 : : {
63 [ + - + - ]: 1172 : Close();
64 : 1172 : m_fd = other.m_fd;
65 : 1172 : other.m_fd = -1;
66 : 1172 : 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 : 586 : 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 : 586 : TokenPipe(TokenPipe&& other)
106 : 586 : {
107 [ + + ]: 1758 : for (int i = 0; i < 2; ++i) {
108 : 1172 : m_fds[i] = other.m_fds[i];
109 : 1172 : 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
|