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 : : 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