]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Use a recursive mutex for the Lua lock
authorRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 3 Jul 2024 12:25:39 +0000 (14:25 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 9 Jul 2024 09:21:34 +0000 (11:21 +0200)
(cherry picked from commit c16a1d43163235e883c13392964b5833c9acac4e)

pdns/dnsdist.cc
pdns/dnsdist.hh
pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc
pdns/lock.hh

index 4849a679ff809c30116b208827c987f0b3c44ca6..cc1bb74305ab9db9c5378b05d85e3ffae917753e 100644 (file)
@@ -897,7 +897,7 @@ catch (...) {
 }
 }
 
-LockGuarded<LuaContext> g_lua{LuaContext()};
+RecursiveLockGuarded<LuaContext> g_lua{LuaContext()};
 ComboAddress g_serverControl{"127.0.0.1:5199"};
 
 
index 777b27aaf75ed46ac627042c55900baab8019fb1..333a48007248a8bf02894db06da1e53190174a5d 100644 (file)
@@ -1026,7 +1026,7 @@ public:
 using servers_t = vector<std::shared_ptr<DownstreamState>>;
 
 void responderThread(std::shared_ptr<DownstreamState> state);
-extern LockGuarded<LuaContext> g_lua;
+extern RecursiveLockGuarded<LuaContext> g_lua;
 extern std::string g_outputBuffer; // locking for this is ok, as locked by g_luamutex
 
 class DNSRule
index 401108ffe114dcea804ef1a403773774449fbe0a..4fc5e7b84f5851cde22d919d1c0b92e911290f86 100644 (file)
@@ -15,7 +15,7 @@
 uint16_t g_maxOutstanding{std::numeric_limits<uint16_t>::max()};
 
 #include "ext/luawrapper/include/LuaContext.hpp"
-LockGuarded<LuaContext> g_lua{LuaContext()};
+RecursiveLockGuarded<LuaContext> g_lua{LuaContext()};
 
 bool g_snmpEnabled{false};
 bool g_snmpTrapsEnabled{false};
index 611d8ada02a7cecac3956c7488fc602a174dee19..3602a81a050b6fdbb8660b0d272024bbe461ac7c 100644 (file)
@@ -297,6 +297,111 @@ private:
   T d_value;
 };
 
+template <typename T>
+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<std::recursive_mutex> d_lock;
+  T& d_value;
+};
+
+template <typename T>
+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<std::recursive_mutex> d_lock;
+  T& d_value;
+};
+
+template <typename T>
+class RecursiveLockGuarded
+{
+public:
+  explicit RecursiveLockGuarded(const T& value) :
+    d_value(value)
+  {
+  }
+
+  explicit RecursiveLockGuarded(T&& value) :
+    d_value(std::move(value))
+  {
+  }
+
+  explicit RecursiveLockGuarded() = default;
+
+  RecursiveLockGuardedTryHolder<T> try_lock()
+  {
+    return RecursiveLockGuardedTryHolder<T>(d_value, d_mutex);
+  }
+
+  RecursiveLockGuardedHolder<T> lock()
+  {
+    return RecursiveLockGuardedHolder<T>(d_value, d_mutex);
+  }
+
+  RecursiveLockGuardedHolder<const T> read_only_lock()
+  {
+    return RecursiveLockGuardedHolder<const T>(d_value, d_mutex);
+  }
+
+private:
+  std::recursive_mutex d_mutex;
+  T d_value;
+};
+
 template <typename T>
 class SharedLockGuardedHolder
 {