mirror of
https://github.com/trapexit/mergerfs.git
synced 2026-10-25 18:40:18 -04:00
Replace two-statement mutex_lockguard macro with single RAII declaration
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>
This commit is contained in:
parent
13fc1b27df
commit
8baf274cde
3 changed files with 62 additions and 7 deletions
|
|
@ -6,8 +6,6 @@
|
|||
#include "mutex_ndebug.hpp"
|
||||
#endif
|
||||
|
||||
#include "scope_guard/scope_guard.hpp"
|
||||
|
||||
typedef pthread_mutex_t mutex_t;
|
||||
|
||||
// Simple mutex_t wrapper to provide RAII
|
||||
|
|
@ -53,9 +51,18 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
// Single-line mutex guard using scope_guard
|
||||
// Expands to mutex_lock() followed by DEFER mutex_unlock()
|
||||
// Both lock and unlock capture __FILE__/__func__/__LINE__ from the call site
|
||||
// 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) \
|
||||
mutex_lock(m); \
|
||||
DEFER { mutex_unlock(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
|
||||
|
|
|
|||
|
|
@ -130,3 +130,30 @@ _mutex_unlock(pthread_mutex_t &mutex_,
|
|||
if(rv != 0)
|
||||
_print_error_and_abort(__func__,rv,file_,func_,linenum_);
|
||||
}
|
||||
|
||||
class ScopedMutexLock
|
||||
{
|
||||
private:
|
||||
pthread_mutex_t &_mutex;
|
||||
const char *_file;
|
||||
const char *_func;
|
||||
int _line;
|
||||
|
||||
public:
|
||||
ScopedMutexLock(pthread_mutex_t &mutex_,
|
||||
const char *file_,
|
||||
const char *func_,
|
||||
int line_)
|
||||
: _mutex(mutex_), _file(file_), _func(func_), _line(line_)
|
||||
{
|
||||
_mutex_lock(_mutex,_file,_func,_line);
|
||||
}
|
||||
|
||||
~ScopedMutexLock()
|
||||
{
|
||||
_mutex_unlock(_mutex,_file,_func,_line);
|
||||
}
|
||||
|
||||
ScopedMutexLock(const ScopedMutexLock&) = delete;
|
||||
ScopedMutexLock& operator=(const ScopedMutexLock&) = delete;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -62,3 +62,24 @@ mutex_destroy(pthread_mutex_t &mutex_)
|
|||
if(rv != 0)
|
||||
std::abort();
|
||||
}
|
||||
|
||||
class ScopedMutexLock
|
||||
{
|
||||
private:
|
||||
pthread_mutex_t &_mutex;
|
||||
|
||||
public:
|
||||
ScopedMutexLock(pthread_mutex_t &mutex_)
|
||||
: _mutex(mutex_)
|
||||
{
|
||||
mutex_lock(_mutex);
|
||||
}
|
||||
|
||||
~ScopedMutexLock()
|
||||
{
|
||||
mutex_unlock(_mutex);
|
||||
}
|
||||
|
||||
ScopedMutexLock(const ScopedMutexLock&) = delete;
|
||||
ScopedMutexLock& operator=(const ScopedMutexLock&) = delete;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue