mirror of
https://github.com/trapexit/mergerfs.git
synced 2026-10-26 19:01:56 -04:00
The old macro expanded to two statements (mutex_lock + DEFER unlock). In an unbraced if/else only the lock would be conditional while the DEFER always executed — a latent double-unlock / unbalanced-unlock bug. Add ScopedMutexLock to both debug and ndebug headers: - debug: stores __FILE__/__func__/__LINE__ from the call site and passes them to _mutex_lock/_mutex_unlock for diagnostics - ndebug: lightweight wrapper around mutex_lock/mutex_unlock Redefine mutex_lockguard to create a single uniquely-named ScopedMutexLock variable (via __COUNTER__), making it safe in any statement context. Remove the now-unused scope_guard include. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
68 lines
1.2 KiB
C++
68 lines
1.2 KiB
C++
#pragma once
|
|
|
|
#ifdef DEBUG
|
|
#include "mutex_debug.hpp"
|
|
#else
|
|
#include "mutex_ndebug.hpp"
|
|
#endif
|
|
|
|
typedef pthread_mutex_t mutex_t;
|
|
|
|
// Simple mutex_t wrapper to provide RAII
|
|
// Because macros are needed to get location in the code a lock is
|
|
// called not making it std::mutex compatible.
|
|
class Mutex
|
|
{
|
|
private:
|
|
mutex_t _mutex;
|
|
|
|
public:
|
|
Mutex()
|
|
{
|
|
mutex_init(_mutex);
|
|
}
|
|
|
|
~Mutex()
|
|
{
|
|
mutex_destroy(_mutex);
|
|
}
|
|
|
|
operator mutex_t&()
|
|
{
|
|
return _mutex;
|
|
}
|
|
};
|
|
|
|
class LockGuard
|
|
{
|
|
private:
|
|
mutex_t &_mutex;
|
|
|
|
public:
|
|
LockGuard(mutex_t &mutex_)
|
|
: _mutex(mutex_)
|
|
{
|
|
mutex_lock(_mutex);
|
|
}
|
|
|
|
~LockGuard()
|
|
{
|
|
mutex_unlock(_mutex);
|
|
}
|
|
};
|
|
|
|
// RAII mutex guard macro. Expands to a single variable declaration,
|
|
// so it is safe in unbraced if/else/for/while.
|
|
// In debug builds the call-site __FILE__/__func__/__LINE__ are
|
|
// forwarded to _mutex_lock/_mutex_unlock for diagnostics.
|
|
#define MUTEX_LOCKGUARD_CONCAT_(a,b) a##b
|
|
#define MUTEX_LOCKGUARD_CONCAT(a,b) MUTEX_LOCKGUARD_CONCAT_(a,b)
|
|
|
|
#ifdef DEBUG
|
|
#define mutex_lockguard(m) \
|
|
ScopedMutexLock MUTEX_LOCKGUARD_CONCAT(_mtx_guard_,__COUNTER__) \
|
|
((m),__FILE__,__func__,__LINE__)
|
|
#else
|
|
#define mutex_lockguard(m) \
|
|
ScopedMutexLock MUTEX_LOCKGUARD_CONCAT(_mtx_guard_,__COUNTER__)(m)
|
|
#endif
|