lockstep_scheduler: avoid pthread_cond_destroy on at_exit

The static object is destroyed on at_exit while threads might still be
inside a CS. This can lead to a hanging process.
Cleaner would be to gracefully stop the threads.

According to https://linux.die.net/man/3/pthread_cond_destroy:
Attempting to destroy a condition variable upon which other threads are
currently blocked results in undefined behavior.
This commit is contained in:
Beat Küng 2022-12-20 10:18:59 +01:00
parent f25abbc80a
commit 0687fd2689
4 changed files with 11 additions and 4 deletions

View File

@ -53,7 +53,7 @@
#if defined(ENABLE_LOCKSTEP_SCHEDULER)
#include <lockstep_scheduler/lockstep_scheduler.h>
static LockstepScheduler lockstep_scheduler {};
static LockstepScheduler lockstep_scheduler {true};
#endif
// Intervals in usec

View File

@ -46,7 +46,7 @@
class LockstepComponents
{
public:
LockstepComponents();
LockstepComponents(bool no_cleanup_on_destroy = false);
~LockstepComponents();
/**
@ -69,6 +69,7 @@ public:
void wait_for_components();
private:
const bool _no_cleanup_on_destroy;
px4_sem_t _components_sem;

View File

@ -46,6 +46,7 @@
class LockstepScheduler
{
public:
LockstepScheduler(bool no_cleanup_on_destroy = false) : _components(no_cleanup_on_destroy) {}
~LockstepScheduler();
void set_absolute_time(uint64_t time_us);

View File

@ -42,14 +42,19 @@
#include <px4_platform_common/tasks.h>
#include <limits.h>
LockstepComponents::LockstepComponents()
LockstepComponents::LockstepComponents(bool no_cleanup_on_destroy)
: _no_cleanup_on_destroy(no_cleanup_on_destroy)
{
px4_sem_init(&_components_sem, 0, 0);
}
LockstepComponents::~LockstepComponents()
{
px4_sem_destroy(&_components_sem);
// Trying to destroy a condition variable with threads currently blocked on it results in undefined behavior.
// Therefore we allow the caller not to cleanup and let the OS take care of that.
if (!_no_cleanup_on_destroy) {
px4_sem_destroy(&_components_sem);
}
}
int LockstepComponents::register_component()