mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-07-24 15:27:41 +08:00
fix(parameters): initialize the recursive param mutex in param_init()
The param access mutex must be recursive because a layered param lookup re-enters the lock on the same thread (Layer::get() -> _parent->get()). Initialize it in param_init() - which runs once before any thread accesses parameters - via pthread_mutexattr_settype(PTHREAD_MUTEX_RECURSIVE), replacing the previous pthread_once lazy init. This avoids the non-portable glibc static initializer PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, which is unavailable on QURT and gated behind _GNU_SOURCE elsewhere (broke the voxl2 and SITL builds).
This commit is contained in:
@@ -34,10 +34,18 @@
|
||||
#include "atomic_transaction.h"
|
||||
|
||||
#ifdef __PX4_POSIX
|
||||
// The mutex is recursive because a param lookup walks the layered param stack
|
||||
// holding the lock and delegates to the parent layer (Layer::get() ->
|
||||
// _parent->get()), which takes the same mutex again on the same thread.
|
||||
//
|
||||
// The recursive attribute is set at runtime rather than via a static initializer:
|
||||
// PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP is a glibc extension that is not portable
|
||||
// (unavailable on e.g. QURT, and gated behind _GNU_SOURCE elsewhere). initialize()
|
||||
// is called from param_init(), before any thread accesses parameters, so there is
|
||||
// no lazy-init race.
|
||||
static pthread_mutex_t _param_mutex;
|
||||
static pthread_once_t _param_mutex_once = PTHREAD_ONCE_INIT;
|
||||
|
||||
static void _init_param_mutex()
|
||||
void AtomicTransaction::initialize()
|
||||
{
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
@@ -48,7 +56,6 @@ static void _init_param_mutex()
|
||||
|
||||
pthread_mutex_t *AtomicTransaction::_get_mutex()
|
||||
{
|
||||
pthread_once(&_param_mutex_once, _init_param_mutex);
|
||||
return &_param_mutex;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -54,6 +54,12 @@ private:
|
||||
#endif
|
||||
|
||||
public:
|
||||
#ifdef __PX4_POSIX
|
||||
// Initialize the recursive param mutex. Must be called once before any thread
|
||||
// accesses parameters (done from param_init()).
|
||||
static void initialize();
|
||||
#endif
|
||||
|
||||
AtomicTransaction()
|
||||
{
|
||||
lock();
|
||||
|
||||
@@ -130,6 +130,11 @@ static pthread_mutex_t file_mutex =
|
||||
void
|
||||
param_init()
|
||||
{
|
||||
#ifdef __PX4_POSIX
|
||||
// Set up the recursive param mutex before any thread can access parameters.
|
||||
AtomicTransaction::initialize();
|
||||
#endif
|
||||
|
||||
param_export_perf = perf_alloc(PC_ELAPSED, "param: export");
|
||||
param_find_perf = perf_alloc(PC_COUNT, "param: find");
|
||||
param_get_perf = perf_alloc(PC_COUNT, "param: get");
|
||||
|
||||
Reference in New Issue
Block a user