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 : 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 2 : TokenPipeEnd& operator=(TokenPipeEnd&& other) 62 : { 63 2 : Close(); 64 2 : m_fd = other.m_fd; 65 2 : other.m_fd = -1; 66 2 : 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 1 : int m_fds[2] = {-1, -1}; 79 : 80 1 : 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 1 : TokenPipe(TokenPipe&& other) 106 : { 107 3 : for (int i = 0; i < 2; ++i) { 108 2 : m_fds[i] = other.m_fds[i]; 109 2 : other.m_fds[i] = -1; 110 2 : } 111 1 : } 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