aboutsummaryrefslogtreecommitdiff
path: root/src/util/tokenpipe.h
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@protonmail.com>2021-01-26 19:36:41 +0100
committerWladimir J. van der Laan <laanwj@protonmail.com>2021-03-04 18:24:00 +0100
commit612f746a8ffa265b6877bedbbe21fcbb392f1516 (patch)
tree0d9f1e994cd718b698ee03bd63be422d268129cc /src/util/tokenpipe.h
parent2e8116149ca45316e7cdd8ed25ea9a130afd0130 (diff)
util: Add RAII TokenPipe
Diffstat (limited to 'src/util/tokenpipe.h')
-rw-r--r--src/util/tokenpipe.h127
1 files changed, 127 insertions, 0 deletions
diff --git a/src/util/tokenpipe.h b/src/util/tokenpipe.h
new file mode 100644
index 0000000000..f56be93a38
--- /dev/null
+++ b/src/util/tokenpipe.h
@@ -0,0 +1,127 @@
+// Copyright (c) 2021 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_UTIL_TOKENPIPE_H
+#define BITCOIN_UTIL_TOKENPIPE_H
+
+#ifndef WIN32
+
+#include <cstdint>
+#include <optional>
+
+/** One end of a token pipe. */
+class TokenPipeEnd
+{
+private:
+ int m_fd = -1;
+
+public:
+ TokenPipeEnd(int fd = -1);
+ ~TokenPipeEnd();
+
+ /** Return value constants for TokenWrite and TokenRead. */
+ enum Status {
+ TS_ERR = -1, //!< I/O error
+ TS_EOS = -2, //!< Unexpected end of stream
+ };
+
+ /** Write token to endpoint.
+ *
+ * @returns 0 If successful.
+ * <0 if error:
+ * TS_ERR If an error happened.
+ * TS_EOS If end of stream happened.
+ */
+ int TokenWrite(uint8_t token);
+
+ /** Read token from endpoint.
+ *
+ * @returns >=0 Token value, if successful.
+ * <0 if error:
+ * TS_ERR If an error happened.
+ * TS_EOS If end of stream happened.
+ */
+ int TokenRead();
+
+ /** Explicit close function.
+ */
+ void Close();
+
+ /** Return whether endpoint is open.
+ */
+ bool IsOpen() { return m_fd != -1; }
+
+ // Move-only class.
+ TokenPipeEnd(TokenPipeEnd&& other)
+ {
+ m_fd = other.m_fd;
+ other.m_fd = -1;
+ }
+ TokenPipeEnd& operator=(TokenPipeEnd&& other)
+ {
+ Close();
+ m_fd = other.m_fd;
+ other.m_fd = -1;
+ return *this;
+ }
+ TokenPipeEnd(const TokenPipeEnd&) = delete;
+ TokenPipeEnd& operator=(const TokenPipeEnd&) = delete;
+};
+
+/** An interprocess or interthread pipe for sending tokens (one-byte values)
+ * over.
+ */
+class TokenPipe
+{
+private:
+ int m_fds[2] = {-1, -1};
+
+ TokenPipe(int fds[2]) : m_fds{fds[0], fds[1]} {}
+
+public:
+ ~TokenPipe();
+
+ /** Create a new pipe.
+ * @returns The created TokenPipe, or an empty std::nullopt in case of error.
+ */
+ static std::optional<TokenPipe> Make();
+
+ /** Take the read end of this pipe. This can only be called once,
+ * as the object will be moved out.
+ */
+ TokenPipeEnd TakeReadEnd();
+
+ /** Take the write end of this pipe. This should only be called once,
+ * as the object will be moved out.
+ */
+ TokenPipeEnd TakeWriteEnd();
+
+ /** Close and end of the pipe that hasn't been moved out.
+ */
+ void Close();
+
+ // Move-only class.
+ TokenPipe(TokenPipe&& other)
+ {
+ for (int i = 0; i < 2; ++i) {
+ m_fds[i] = other.m_fds[i];
+ other.m_fds[i] = -1;
+ }
+ }
+ TokenPipe& operator=(TokenPipe&& other)
+ {
+ Close();
+ for (int i = 0; i < 2; ++i) {
+ m_fds[i] = other.m_fds[i];
+ other.m_fds[i] = -1;
+ }
+ return *this;
+ }
+ TokenPipe(const TokenPipe&) = delete;
+ TokenPipe& operator=(const TokenPipe&) = delete;
+};
+
+#endif // WIN32
+
+#endif // BITCOIN_UTIL_TOKENPIPE_H