parameters: fix TSAN issue with AtomicTransaction

This fixes TSAN issues on destruction of AtomicTransaction happening
during the unit tests.

The static _MutexHolder instance wraps a pthread_mutex_t in a C++ class,
creating a destructor ordering problem during process exit when worker
threads may still hold the lock. Replace with a raw pthread_mutex_t
initialized via pthread_once, eliminating the C++ destructor entirely.
This commit is contained in:
Julian Oes
2026-02-18 21:03:38 +13:00
parent b56f2dbcbd
commit 2c833f5ae2
2 changed files with 20 additions and 23 deletions
+17 -1
View File
@@ -34,5 +34,21 @@
#include "atomic_transaction.h"
#ifdef __PX4_POSIX
_MutexHolder AtomicTransaction::_mutex_holder = _MutexHolder {};
static pthread_mutex_t _param_mutex;
static pthread_once_t _param_mutex_once = PTHREAD_ONCE_INIT;
static void _init_param_mutex()
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&_param_mutex, &attr);
pthread_mutexattr_destroy(&attr);
}
pthread_mutex_t *AtomicTransaction::_get_mutex()
{
pthread_once(&_param_mutex_once, _init_param_mutex);
return &_param_mutex;
}
#endif
+3 -22
View File
@@ -39,25 +39,6 @@
#ifdef __PX4_POSIX
#include <pthread.h>
class _MutexHolder
{
public:
pthread_mutex_t _mutex;
pthread_mutexattr_t _mutex_attr;
_MutexHolder()
{
pthread_mutexattr_init(&_mutex_attr);
pthread_mutexattr_settype(&_mutex_attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&_mutex, &_mutex_attr);
}
~_MutexHolder()
{
pthread_mutex_destroy(&_mutex);
}
};
#endif
@@ -69,7 +50,7 @@ private:
#endif
#ifdef __PX4_POSIX
static _MutexHolder _mutex_holder;
static pthread_mutex_t *_get_mutex();
#endif
public:
@@ -89,7 +70,7 @@ public:
_irq_state = px4_enter_critical_section();
#endif
#ifdef __PX4_POSIX
pthread_mutex_lock(&_mutex_holder._mutex);
pthread_mutex_lock(_get_mutex());
#endif
}
@@ -99,7 +80,7 @@ public:
px4_leave_critical_section(_irq_state);
#endif
#ifdef __PX4_POSIX
pthread_mutex_unlock(&_mutex_holder._mutex);
pthread_mutex_unlock(_get_mutex());
#endif
}
};