From: Remi Gacogne Date: Wed, 3 Jul 2024 12:25:39 +0000 (+0200) Subject: dnsdist: Use a recursive mutex for the Lua lock X-Git-Tag: dnsdist-1.9.6~2^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6cc4d3c048b48c7ebce4251efa002e1fe8e35832;p=thirdparty%2Fpdns.git dnsdist: Use a recursive mutex for the Lua lock (cherry picked from commit c16a1d43163235e883c13392964b5833c9acac4e) --- diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 4849a679ff..cc1bb74305 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -897,7 +897,7 @@ catch (...) { } } -LockGuarded g_lua{LuaContext()}; +RecursiveLockGuarded g_lua{LuaContext()}; ComboAddress g_serverControl{"127.0.0.1:5199"}; diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index 777b27aaf7..333a480072 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -1026,7 +1026,7 @@ public: using servers_t = vector>; void responderThread(std::shared_ptr state); -extern LockGuarded g_lua; +extern RecursiveLockGuarded g_lua; extern std::string g_outputBuffer; // locking for this is ok, as locked by g_luamutex class DNSRule diff --git a/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc b/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc index 401108ffe1..4fc5e7b84f 100644 --- a/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc @@ -15,7 +15,7 @@ uint16_t g_maxOutstanding{std::numeric_limits::max()}; #include "ext/luawrapper/include/LuaContext.hpp" -LockGuarded g_lua{LuaContext()}; +RecursiveLockGuarded g_lua{LuaContext()}; bool g_snmpEnabled{false}; bool g_snmpTrapsEnabled{false}; diff --git a/pdns/lock.hh b/pdns/lock.hh index 611d8ada02..3602a81a05 100644 --- a/pdns/lock.hh +++ b/pdns/lock.hh @@ -297,6 +297,111 @@ private: T d_value; }; +template +class RecursiveLockGuardedHolder +{ +public: + explicit RecursiveLockGuardedHolder(T& value, std::recursive_mutex& mutex) : + d_lock(mutex), d_value(value) + { + } + + T& operator*() const noexcept + { + return d_value; + } + + T* operator->() const noexcept + { + return &d_value; + } + +private: + std::lock_guard d_lock; + T& d_value; +}; + +template +class RecursiveLockGuardedTryHolder +{ +public: + explicit RecursiveLockGuardedTryHolder(T& value, std::recursive_mutex& mutex) : + d_lock(mutex, std::try_to_lock), d_value(value) + { + } + + T& operator*() const + { + if (!owns_lock()) { + throw std::runtime_error("Trying to access data protected by a mutex while the lock has not been acquired"); + } + return d_value; + } + + T* operator->() const + { + if (!owns_lock()) { + throw std::runtime_error("Trying to access data protected by a mutex while the lock has not been acquired"); + } + return &d_value; + } + + operator bool() const noexcept + { + return d_lock.owns_lock(); + } + + [[nodiscard]] bool owns_lock() const noexcept + { + return d_lock.owns_lock(); + } + + void lock() + { + d_lock.lock(); + } + +private: + std::unique_lock d_lock; + T& d_value; +}; + +template +class RecursiveLockGuarded +{ +public: + explicit RecursiveLockGuarded(const T& value) : + d_value(value) + { + } + + explicit RecursiveLockGuarded(T&& value) : + d_value(std::move(value)) + { + } + + explicit RecursiveLockGuarded() = default; + + RecursiveLockGuardedTryHolder try_lock() + { + return RecursiveLockGuardedTryHolder(d_value, d_mutex); + } + + RecursiveLockGuardedHolder lock() + { + return RecursiveLockGuardedHolder(d_value, d_mutex); + } + + RecursiveLockGuardedHolder read_only_lock() + { + return RecursiveLockGuardedHolder(d_value, d_mutex); + } + +private: + std::recursive_mutex d_mutex; + T d_value; +}; + template class SharedLockGuardedHolder {