/Users/eugenesiegel/btc/bitcoin/src/util/tokenpipe.h
| Line | Count | Source (jump to first uncovered line) | 
| 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 | 0 |     { | 
| 58 | 0 |         m_fd = other.m_fd; | 
| 59 | 0 |         other.m_fd = -1; | 
| 60 | 0 |     } | 
| 61 |  |     TokenPipeEnd& operator=(TokenPipeEnd&& other) | 
| 62 | 102k |     { | 
| 63 | 102k |         Close(); | 
| 64 | 102k |         m_fd = other.m_fd; | 
| 65 | 102k |         other.m_fd = -1; | 
| 66 | 102k |         return *this; | 
| 67 | 102k |     } | 
| 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 | 51.2k |     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 | 51.2k |     { | 
| 107 | 153k |         for (int i = 0; i < 2; ++i102k) { | 
| 108 | 102k |             m_fds[i] = other.m_fds[i]; | 
| 109 | 102k |             other.m_fds[i] = -1; | 
| 110 | 102k |         } | 
| 111 | 51.2k |     } | 
| 112 |  |     TokenPipe& operator=(TokenPipe&& other) | 
| 113 | 0 |     { | 
| 114 | 0 |         Close(); | 
| 115 | 0 |         for (int i = 0; i < 2; ++i) { | 
| 116 | 0 |             m_fds[i] = other.m_fds[i]; | 
| 117 | 0 |             other.m_fds[i] = -1; | 
| 118 | 0 |         } | 
| 119 | 0 |         return *this; | 
| 120 | 0 |     } | 
| 121 |  |     TokenPipe(const TokenPipe&) = delete; | 
| 122 |  |     TokenPipe& operator=(const TokenPipe&) = delete; | 
| 123 |  | }; | 
| 124 |  |  | 
| 125 |  | #endif // WIN32 | 
| 126 |  |  | 
| 127 |  | #endif // BITCOIN_UTIL_TOKENPIPE_H |