mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-05 05:39:57 -05:00
Merge topic 'server-refactor'
39c2feafmisc: Added utility method to allow working with stacksf5d2988eserver: Swapped to cm_thread impl2636d86cutility: Added minimal std::thread drop-ind46b4ba8server: Updated server tests to try various communication channels08dca583Tests: reworked server tests to allow other operation modes Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !1230
This commit is contained in:
@@ -593,6 +593,7 @@ set(SRCS
|
||||
cm_utf8.c
|
||||
cm_codecvt.hxx
|
||||
cm_codecvt.cxx
|
||||
cm_thread.hxx
|
||||
)
|
||||
|
||||
SET_PROPERTY(SOURCE cmProcessOutput.cxx APPEND PROPERTY COMPILE_DEFINITIONS
|
||||
|
||||
@@ -438,6 +438,19 @@ void cmListFileBacktrace::PrintCallStack(std::ostream& out) const
|
||||
}
|
||||
}
|
||||
|
||||
size_t cmListFileBacktrace::Depth() const
|
||||
{
|
||||
size_t depth = 0;
|
||||
if (this->Cur == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (Entry* i = this->Cur->Up; i; i = i->Up) {
|
||||
depth++;
|
||||
}
|
||||
return depth;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, cmListFileContext const& lfc)
|
||||
{
|
||||
os << lfc.FilePath;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include <iosfwd>
|
||||
#include <stddef.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -138,6 +139,9 @@ public:
|
||||
// Print the call stack below the top of the backtrace.
|
||||
void PrintCallStack(std::ostream& out) const;
|
||||
|
||||
// Get the number of 'frames' in this backtrace
|
||||
size_t Depth() const;
|
||||
|
||||
private:
|
||||
struct Entry;
|
||||
|
||||
|
||||
+14
-19
@@ -245,11 +245,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,
|
||||
@@ -456,14 +455,12 @@ bool cmServerBase::Serve(std::string* errorMessage)
|
||||
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) {
|
||||
@@ -501,12 +498,11 @@ void cmServerBase::StartShutDown()
|
||||
}
|
||||
|
||||
{
|
||||
uv_rwlock_wrlock(&ConnectionsMutex);
|
||||
cm::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);
|
||||
@@ -525,9 +521,6 @@ cmServerBase::cmServerBase(cmConnection* connection)
|
||||
(void)err;
|
||||
assert(err == 0);
|
||||
|
||||
err = uv_rwlock_init(&ConnectionsMutex);
|
||||
assert(err == 0);
|
||||
|
||||
AddNewConnection(connection);
|
||||
}
|
||||
|
||||
@@ -540,14 +533,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);
|
||||
{
|
||||
cm::unique_lock<cm::shared_mutex> lock(ConnectionsMutex);
|
||||
Connections.emplace_back(ownedConnection);
|
||||
}
|
||||
ownedConnection->SetServer(this);
|
||||
}
|
||||
|
||||
@@ -561,11 +554,13 @@ 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);
|
||||
{
|
||||
cm::unique_lock<cm::shared_mutex> lock(ConnectionsMutex);
|
||||
Connections.erase(
|
||||
std::remove_if(Connections.begin(), Connections.end(), pred),
|
||||
Connections.end());
|
||||
}
|
||||
|
||||
if (Connections.empty()) {
|
||||
StartShutDown();
|
||||
}
|
||||
|
||||
+2
-1
@@ -5,6 +5,7 @@
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include "cm_jsoncpp_value.h"
|
||||
#include "cm_thread.hxx"
|
||||
#include "cm_uv.h"
|
||||
|
||||
#include <memory> // IWYU pragma: keep
|
||||
@@ -61,7 +62,7 @@ public:
|
||||
void OnDisconnect(cmConnection* pConnection);
|
||||
|
||||
protected:
|
||||
mutable uv_rwlock_t ConnectionsMutex;
|
||||
mutable cm::shared_mutex ConnectionsMutex;
|
||||
std::vector<std::unique_ptr<cmConnection>> Connections;
|
||||
|
||||
bool ServeThreadRunning = false;
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#ifndef CM_THREAD_HXX
|
||||
#define CM_THREAD_HXX
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
#include "cm_uv.h"
|
||||
|
||||
namespace cm {
|
||||
class mutex
|
||||
{
|
||||
uv_mutex_t _M_;
|
||||
|
||||
public:
|
||||
mutex() { uv_mutex_init(&_M_); }
|
||||
~mutex() { uv_mutex_destroy(&_M_); }
|
||||
|
||||
void lock() { uv_mutex_lock(&_M_); }
|
||||
|
||||
void unlock() { uv_mutex_unlock(&_M_); }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class lock_guard
|
||||
{
|
||||
T& _mutex;
|
||||
|
||||
public:
|
||||
lock_guard(T& m)
|
||||
: _mutex(m)
|
||||
{
|
||||
_mutex.lock();
|
||||
}
|
||||
~lock_guard() { _mutex.unlock(); }
|
||||
};
|
||||
|
||||
class shared_mutex
|
||||
{
|
||||
uv_rwlock_t _M_;
|
||||
|
||||
public:
|
||||
shared_mutex() { uv_rwlock_init(&_M_); }
|
||||
~shared_mutex() { uv_rwlock_destroy(&_M_); }
|
||||
|
||||
void lock() { uv_rwlock_wrlock(&_M_); }
|
||||
|
||||
void unlock() { uv_rwlock_wrunlock(&_M_); }
|
||||
|
||||
void lock_shared() { uv_rwlock_rdlock(&_M_); }
|
||||
|
||||
void unlock_shared() { uv_rwlock_rdunlock(&_M_); }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class shared_lock
|
||||
{
|
||||
T& _mutex;
|
||||
|
||||
public:
|
||||
shared_lock(T& m)
|
||||
: _mutex(m)
|
||||
{
|
||||
_mutex.lock_shared();
|
||||
}
|
||||
~shared_lock() { _mutex.unlock_shared(); }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class unique_lock : public lock_guard<T>
|
||||
{
|
||||
public:
|
||||
unique_lock(T& m)
|
||||
: lock_guard<T>(m)
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user