diff options
Diffstat (limited to 'Source/cmServer.cxx')
-rw-r--r-- | Source/cmServer.cxx | 101 |
1 files changed, 48 insertions, 53 deletions
diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx index e923c22..1b04ca2 100644 --- a/Source/cmServer.cxx +++ b/Source/cmServer.cxx @@ -18,17 +18,19 @@ #include <cstdint> #include <iostream> #include <memory> +#include <mutex> #include <utility> void on_signal(uv_signal_t* signal, int signum) { - auto conn = reinterpret_cast<cmServerBase*>(signal->data); + auto conn = static_cast<cmServerBase*>(signal->data); conn->OnSignal(signum); } static void on_walk_to_shutdown(uv_handle_t* handle, void* arg) { (void)arg; + assert(uv_is_closing(handle)); if (!uv_is_closing(handle)) { uv_close(handle, &cmEventBasedConnection::on_close); } @@ -58,6 +60,8 @@ cmServer::cmServer(cmConnection* conn, bool supportExperimental) cmServer::~cmServer() { + Close(); + for (cmServerProtocol* p : this->SupportedProtocols) { delete p; } @@ -245,11 +249,10 @@ cmFileMonitor* cmServer::FileMonitor() const void cmServer::WriteJsonObject(const Json::Value& jsonValue, const DebugInfo* debug) const { - uv_rwlock_rdlock(&ConnectionsMutex); + cm::shared_lock<cm::shared_mutex> lock(ConnectionsMutex); for (auto& connection : this->Connections) { WriteJsonObject(connection.get(), jsonValue, debug); } - uv_rwlock_rdunlock(&ConnectionsMutex); } void cmServer::WriteJsonObject(cmConnection* connection, @@ -410,7 +413,7 @@ void cmServer::StartShutDown() static void __start_thread(void* arg) { - auto server = reinterpret_cast<cmServerBase*>(arg); + auto server = static_cast<cmServerBase*>(arg); std::string error; bool success = server->Serve(&error); if (!success || error.empty() == false) { @@ -418,22 +421,19 @@ static void __start_thread(void* arg) } } -static void __shutdownThread(uv_async_t* arg) -{ - auto server = reinterpret_cast<cmServerBase*>(arg->data); - on_walk_to_shutdown(reinterpret_cast<uv_handle_t*>(arg), nullptr); - server->StartShutDown(); -} - bool cmServerBase::StartServeThread() { ServeThreadRunning = true; - uv_async_init(&Loop, &this->ShutdownSignal, __shutdownThread); - this->ShutdownSignal.data = this; uv_thread_create(&ServeThread, __start_thread, this); return true; } +static void __shutdownThread(uv_async_t* arg) +{ + auto server = static_cast<cmServerBase*>(arg->data); + server->StartShutDown(); +} + bool cmServerBase::Serve(std::string* errorMessage) { #ifndef NDEBUG @@ -444,26 +444,23 @@ bool cmServerBase::Serve(std::string* errorMessage) errorMessage->clear(); - uv_signal_init(&Loop, &this->SIGINTHandler); - uv_signal_init(&Loop, &this->SIGHUPHandler); + ShutdownSignal.init(Loop, __shutdownThread, this); - this->SIGINTHandler.data = this; - this->SIGHUPHandler.data = this; + SIGINTHandler.init(Loop, this); + SIGHUPHandler.init(Loop, this); - uv_signal_start(&this->SIGINTHandler, &on_signal, SIGINT); - uv_signal_start(&this->SIGHUPHandler, &on_signal, SIGHUP); + SIGINTHandler.start(&on_signal, SIGINT); + SIGHUPHandler.start(&on_signal, SIGHUP); OnServeStart(); { - uv_rwlock_rdlock(&ConnectionsMutex); + cm::shared_lock<cm::shared_mutex> lock(ConnectionsMutex); for (auto& connection : Connections) { if (!connection->OnServeStart(errorMessage)) { - uv_rwlock_rdunlock(&ConnectionsMutex); return false; } } - uv_rwlock_rdunlock(&ConnectionsMutex); } if (uv_run(&Loop, UV_RUN_DEFAULT) != 0) { @@ -476,7 +473,6 @@ bool cmServerBase::Serve(std::string* errorMessage) return false; } - ServeThreadRunning = false; return true; } @@ -490,23 +486,16 @@ void cmServerBase::OnServeStart() void cmServerBase::StartShutDown() { - if (!uv_is_closing( - reinterpret_cast<const uv_handle_t*>(&this->SIGINTHandler))) { - uv_signal_stop(&this->SIGINTHandler); - } - - if (!uv_is_closing( - reinterpret_cast<const uv_handle_t*>(&this->SIGHUPHandler))) { - uv_signal_stop(&this->SIGHUPHandler); - } + ShutdownSignal.reset(); + SIGINTHandler.reset(); + SIGHUPHandler.reset(); { - uv_rwlock_wrlock(&ConnectionsMutex); + std::unique_lock<cm::shared_mutex> lock(ConnectionsMutex); for (auto& connection : Connections) { connection->OnConnectionShuttingDown(); } Connections.clear(); - uv_rwlock_wrunlock(&ConnectionsMutex); } uv_walk(&Loop, on_walk_to_shutdown, nullptr); @@ -523,31 +512,35 @@ cmServerBase::cmServerBase(cmConnection* connection) { auto err = uv_loop_init(&Loop); (void)err; - assert(err == 0); - - err = uv_rwlock_init(&ConnectionsMutex); + Loop.data = this; assert(err == 0); AddNewConnection(connection); } -cmServerBase::~cmServerBase() +void cmServerBase::Close() { + if (Loop.data) { + if (ServeThreadRunning) { + this->ShutdownSignal.send(); + uv_thread_join(&ServeThread); + } - if (ServeThreadRunning) { - uv_async_send(&this->ShutdownSignal); - uv_thread_join(&ServeThread); + uv_loop_close(&Loop); + Loop.data = nullptr; } - - uv_loop_close(&Loop); - uv_rwlock_destroy(&ConnectionsMutex); +} +cmServerBase::~cmServerBase() +{ + Close(); } void cmServerBase::AddNewConnection(cmConnection* ownedConnection) { - uv_rwlock_wrlock(&ConnectionsMutex); - Connections.emplace_back(ownedConnection); - uv_rwlock_wrunlock(&ConnectionsMutex); + { + std::unique_lock<cm::shared_mutex> lock(ConnectionsMutex); + Connections.emplace_back(ownedConnection); + } ownedConnection->SetServer(this); } @@ -561,12 +554,14 @@ void cmServerBase::OnDisconnect(cmConnection* pConnection) auto pred = [pConnection](const std::unique_ptr<cmConnection>& m) { return m.get() == pConnection; }; - uv_rwlock_wrlock(&ConnectionsMutex); - Connections.erase( - std::remove_if(Connections.begin(), Connections.end(), pred), - Connections.end()); - uv_rwlock_wrunlock(&ConnectionsMutex); + { + std::unique_lock<cm::shared_mutex> lock(ConnectionsMutex); + Connections.erase( + std::remove_if(Connections.begin(), Connections.end(), pred), + Connections.end()); + } + if (Connections.empty()) { - StartShutDown(); + this->ShutdownSignal.send(); } } |