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 : 793 : 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 : 1604 : { # 63 : 1604 : Close(); # 64 : 1604 : m_fd = other.m_fd; # 65 : 1604 : other.m_fd = -1; # 66 : 1604 : return *this; # 67 : 1604 : } # 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 : 802 : 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 : 802 : { # 107 [ + + ]: 2406 : for (int i = 0; i < 2; ++i) { # 108 : 1604 : m_fds[i] = other.m_fds[i]; # 109 : 1604 : other.m_fds[i] = -1; # 110 : 1604 : } # 111 : 802 : } # 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