diff options
author | Justin Berger <j.david.berger@gmail.com> | 2017-03-25 03:38:52 (GMT) |
---|---|---|
committer | Justin Berger <j.david.berger@gmail.com> | 2017-07-11 00:11:27 (GMT) |
commit | d4f5d35ca491ede92003b26a7d0eb06aea3a2bbb (patch) | |
tree | 90f665b7e1611c47ab8eaa3f069e9572d3df58fb /Source/cmPipeConnection.cxx | |
parent | 5acbf08bff643ec6779464c840bfe2f02a4e65ae (diff) | |
download | CMake-d4f5d35ca491ede92003b26a7d0eb06aea3a2bbb.zip CMake-d4f5d35ca491ede92003b26a7d0eb06aea3a2bbb.tar.gz CMake-d4f5d35ca491ede92003b26a7d0eb06aea3a2bbb.tar.bz2 |
server: Refactor to make the event loop owned by server object
Diffstat (limited to 'Source/cmPipeConnection.cxx')
-rw-r--r-- | Source/cmPipeConnection.cxx | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/Source/cmPipeConnection.cxx b/Source/cmPipeConnection.cxx new file mode 100644 index 0000000..438719f --- /dev/null +++ b/Source/cmPipeConnection.cxx @@ -0,0 +1,81 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmPipeConnection.h" + +#include "cmConfigure.h" +#include "cmServer.h" + +cmPipeConnection::cmPipeConnection(const std::string& name, + cmConnectionBufferStrategy* bufferStrategy) + : cmConnection(bufferStrategy) + , PipeName(name) +{ +} + +void cmPipeConnection::Connect(uv_stream_t* server) +{ + if (this->ClientPipe) { + // Accept and close all pipes but the first: + uv_pipe_t* rejectPipe = new uv_pipe_t(); + + uv_pipe_init(this->Server->GetLoop(), rejectPipe, 0); + uv_accept(server, reinterpret_cast<uv_stream_t*>(rejectPipe)); + uv_close(reinterpret_cast<uv_handle_t*>(rejectPipe), &on_close_delete); + return; + } + + this->ClientPipe = new uv_pipe_t(); + uv_pipe_init(this->Server->GetLoop(), this->ClientPipe, 0); + this->ClientPipe->data = static_cast<cmConnection*>(this); + + auto client = reinterpret_cast<uv_stream_t*>(this->ClientPipe); + if (uv_accept(server, client) != 0) { + uv_close(reinterpret_cast<uv_handle_t*>(client), &on_close_delete); + this->ClientPipe = CM_NULLPTR; + return; + } + this->ReadStream = client; + this->WriteStream = client; + + uv_read_start(this->ReadStream, on_alloc_buffer, on_read); + Server->OnConnected(this); +} + +bool cmPipeConnection::OnServeStart(std::string* errorMessage) +{ + this->ServerPipe = new uv_pipe_t(); + uv_pipe_init(this->Server->GetLoop(), this->ServerPipe, 0); + this->ServerPipe->data = static_cast<cmConnection*>(this); + + int r; + if ((r = uv_pipe_bind(this->ServerPipe, this->PipeName.c_str())) != 0) { + *errorMessage = std::string("Internal Error with ") + this->PipeName + + ": " + uv_err_name(r); + return false; + } + auto serverStream = reinterpret_cast<uv_stream_t*>(this->ServerPipe); + if ((r = uv_listen(serverStream, 1, on_new_connection)) != 0) { + *errorMessage = std::string("Internal Error listening on ") + + this->PipeName + ": " + uv_err_name(r); + return false; + } + + return cmConnection::OnServeStart(errorMessage); +} + +bool cmPipeConnection::OnServerShuttingDown() +{ + if (this->ClientPipe) { + uv_close(reinterpret_cast<uv_handle_t*>(this->ClientPipe), + &on_close_delete); + this->WriteStream->data = nullptr; + } + uv_close(reinterpret_cast<uv_handle_t*>(this->ServerPipe), &on_close_delete); + + this->ClientPipe = nullptr; + this->ServerPipe = nullptr; + this->WriteStream = nullptr; + this->ReadStream = nullptr; + + return cmConnection::OnServerShuttingDown(); +} |