diff options
author | Justin Berger <j.david.berger@gmail.com> | 2017-07-20 04:04:13 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2017-08-31 19:35:44 (GMT) |
commit | 882dcef8e02e432e6469b7fca38aff212d1541ab (patch) | |
tree | cef553d0392da5c8543a27faee7547d674934dc0 | |
parent | 7ef28843618519c222806a0df82ed8f87ad2ca0c (diff) | |
download | CMake-882dcef8e02e432e6469b7fca38aff212d1541ab.zip CMake-882dcef8e02e432e6469b7fca38aff212d1541ab.tar.gz CMake-882dcef8e02e432e6469b7fca38aff212d1541ab.tar.bz2 |
server: Made connections in a server have a mutex to avoid use after frees
-rw-r--r-- | Source/cmServer.cxx | 35 | ||||
-rw-r--r-- | Source/cmServer.h | 1 |
2 files changed, 29 insertions, 7 deletions
diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx index 6a63797..c7f8704 100644 --- a/Source/cmServer.cxx +++ b/Source/cmServer.cxx @@ -244,9 +244,11 @@ cmFileMonitor* cmServer::FileMonitor() const void cmServer::WriteJsonObject(const Json::Value& jsonValue, const DebugInfo* debug) const { + uv_rwlock_rdlock(&ConnectionsMutex); for (auto& connection : this->Connections) { WriteJsonObject(connection.get(), jsonValue, debug); } + uv_rwlock_rdunlock(&ConnectionsMutex); } void cmServer::WriteJsonObject(cmConnection* connection, @@ -443,10 +445,15 @@ bool cmServerBase::Serve(std::string* errorMessage) OnServeStart(); - for (auto& connection : Connections) { - if (!connection->OnServeStart(errorMessage)) { - return false; + { + uv_rwlock_rdlock(&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) { @@ -479,10 +486,14 @@ void cmServerBase::StartShutDown() uv_signal_stop(&this->SIGHUPHandler); } - for (auto& connection : Connections) { - connection->OnConnectionShuttingDown(); + { + uv_rwlock_wrlock(&ConnectionsMutex); + for (auto& connection : Connections) { + connection->OnConnectionShuttingDown(); + } + Connections.clear(); + uv_rwlock_wrunlock(&ConnectionsMutex); } - Connections.clear(); uv_walk(&Loop, on_walk_to_shutdown, nullptr); } @@ -496,7 +507,12 @@ bool cmServerBase::OnSignal(int signum) cmServerBase::cmServerBase(cmConnection* connection) { - uv_loop_init(&Loop); + auto err = uv_loop_init(&Loop); + (void)err; + assert(err == 0); + + err = uv_rwlock_init(&ConnectionsMutex); + assert(err == 0); AddNewConnection(connection); } @@ -510,11 +526,14 @@ cmServerBase::~cmServerBase() } uv_loop_close(&Loop); + uv_rwlock_destroy(&ConnectionsMutex); } void cmServerBase::AddNewConnection(cmConnection* ownedConnection) { + uv_rwlock_wrlock(&ConnectionsMutex); Connections.emplace_back(ownedConnection); + uv_rwlock_wrunlock(&ConnectionsMutex); ownedConnection->SetServer(this); } @@ -528,9 +547,11 @@ 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); if (Connections.empty()) { StartShutDown(); } diff --git a/Source/cmServer.h b/Source/cmServer.h index cb7df10..d8f73c1 100644 --- a/Source/cmServer.h +++ b/Source/cmServer.h @@ -61,6 +61,7 @@ public: void OnDisconnect(cmConnection* pConnection); protected: + mutable uv_rwlock_t ConnectionsMutex; std::vector<std::unique_ptr<cmConnection>> Connections; bool ServeThreadRunning = false; |