summaryrefslogtreecommitdiff
path: root/Source/cmConnection.h
diff options
context:
space:
mode:
authorJustin Berger <j.david.berger@gmail.com>2017-03-24 21:38:52 -0600
committerJustin Berger <j.david.berger@gmail.com>2017-07-10 18:11:27 -0600
commitd4f5d35ca491ede92003b26a7d0eb06aea3a2bbb (patch)
tree90f665b7e1611c47ab8eaa3f069e9572d3df58fb /Source/cmConnection.h
parent5acbf08bff643ec6779464c840bfe2f02a4e65ae (diff)
downloadcmake-d4f5d35ca491ede92003b26a7d0eb06aea3a2bbb.tar.gz
server: Refactor to make the event loop owned by server object
Diffstat (limited to 'Source/cmConnection.h')
-rw-r--r--Source/cmConnection.h104
1 files changed, 104 insertions, 0 deletions
diff --git a/Source/cmConnection.h b/Source/cmConnection.h
new file mode 100644
index 0000000000..e99471657a
--- /dev/null
+++ b/Source/cmConnection.h
@@ -0,0 +1,104 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#pragma once
+
+#include "cmConfigure.h"
+
+#include "cm_uv.h"
+
+#include <cstddef>
+#include <memory>
+#include <string>
+
+class cmServerBase;
+
+/***
+ * Given a sequence of bytes with any kind of buffering, instances of this
+ * class arrange logical chunks according to whatever the use case is for
+ * the connection.
+ */
+class cmConnectionBufferStrategy
+{
+public:
+ virtual ~cmConnectionBufferStrategy();
+
+ /***
+ * Called whenever with an active raw buffer. If a logical chunk
+ * becomes available, that chunk is returned and that portion is
+ * removed from the rawBuffer
+ *
+ * @param rawBuffer in/out parameter. Receive buffer; the buffer strategy is
+ * free to manipulate this buffer anyway it needs to.
+ *
+ * @return Next chunk from the stream. Returns the empty string if a chunk
+ * isn't ready yet. Users of this interface should repeatedly call this
+ * function until an empty string is returned since its entirely possible
+ * multiple chunks come in a single raw buffer.
+ */
+ virtual std::string BufferMessage(std::string& rawBuffer) = 0;
+
+ /***
+ * Resets the internal state of the buffering
+ */
+ virtual void clear();
+
+ // TODO: There should be a callback / flag set for errors
+};
+
+/***
+ * Abstraction of a connection; ties in event callbacks from libuv and notifies
+ * the server when appropriate
+ */
+class cmConnection
+{
+ CM_DISABLE_COPY(cmConnection)
+
+public:
+ virtual ~cmConnection();
+
+ /***
+ * @param bufferStrategy If no strategy is given, it will process the raw
+ * chunks as they come in. The connection
+ * owns the pointer given.
+ */
+ cmConnection(cmConnectionBufferStrategy* bufferStrategy = nullptr);
+
+ virtual void Connect(uv_stream_t* server);
+
+ virtual void ReadData(const std::string& data);
+
+ virtual bool OnServeStart(std::string* errString);
+
+ virtual bool OnServerShuttingDown();
+
+ virtual bool IsOpen() const;
+
+ virtual void WriteData(const std::string& data);
+
+ virtual void ProcessRequest(const std::string& request);
+
+ virtual void SetServer(cmServerBase* s);
+
+ virtual void OnDisconnect(int errorCode);
+ uv_stream_t* ReadStream = nullptr;
+ cmServerBase* Server = nullptr;
+ uv_stream_t* WriteStream = nullptr;
+
+ static void on_close(uv_handle_t* handle);
+ static void on_close_delete(uv_handle_t* handle);
+
+protected:
+ std::string RawReadBuffer;
+
+ std::unique_ptr<cmConnectionBufferStrategy> BufferStrategy;
+
+ static void on_read(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf);
+
+ static void on_write(uv_write_t* req, int status);
+
+ static void on_new_connection(uv_stream_t* stream, int status);
+
+ static void on_alloc_buffer(uv_handle_t* handle, size_t suggested_size,
+ uv_buf_t* buf);
+};