tokenpipe.h raw

   1  // Copyright (c) 2021-present 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      TokenPipeEnd& operator=(TokenPipeEnd&& other)
  62      {
  63          Close();
  64          m_fd = other.m_fd;
  65          other.m_fd = -1;
  66          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      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      {
 107          for (int i = 0; i < 2; ++i) {
 108              m_fds[i] = other.m_fds[i];
 109              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
 128