Skip to content

Commit

Permalink
dnsdist: Use a recursive mutex for the Lua lock
Browse files Browse the repository at this point in the history
  • Loading branch information
rgacogne authored and chbruyand committed Jul 3, 2024
1 parent bb202aa commit c16a1d4
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 3 deletions.
2 changes: 1 addition & 1 deletion pdns/dnsdistdist/dnsdist.cc
Original file line number Diff line number Diff line change
Expand Up @@ -888,7 +888,7 @@ void responderThread(std::shared_ptr<DownstreamState> dss)
}
}

LockGuarded<LuaContext> g_lua{LuaContext()};
RecursiveLockGuarded<LuaContext> g_lua{LuaContext()};
ComboAddress g_serverControl{"127.0.0.1:5199"};

static void spoofResponseFromString(DNSQuestion& dnsQuestion, const string& spoofContent, bool raw)
Expand Down
2 changes: 1 addition & 1 deletion pdns/dnsdistdist/dnsdist.hh
Original file line number Diff line number Diff line change
Expand Up @@ -1099,7 +1099,7 @@ public:
using servers_t = vector<std::shared_ptr<DownstreamState>>;

void responderThread(std::shared_ptr<DownstreamState> dss);
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
Expand Down
2 changes: 1 addition & 1 deletion pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
105 changes: 105 additions & 0 deletions pdns/lock.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down

0 comments on commit c16a1d4

Please sign in to comment.