Files
MeshCore-mqtt-observer/src/helpers/ObserverMailbox.h
T
agessaman 6124f3c139 feat(observer): add cross-task handoff primitives
Host-testable building blocks for the single-owner runtime model: a
value mailbox, a coalescing configuration mailbox, an async job handle,
an SDK event channel with its slot transition, a completion-driven NTP
schedule, a durable-preference commit and slot stats JSON emission.
2026-09-21 16:05:17 -07:00

62 lines
1.2 KiB
C++

#pragma once
#include <type_traits>
#ifdef ESP_PLATFORM
#include <freertos/FreeRTOS.h>
#include <freertos/portmacro.h>
#else
#include <mutex>
#endif
// Only bounded value copies belong under this lock, never allocation or I/O.
class ObserverLock {
public:
void lock() {
#ifdef ESP_PLATFORM
portENTER_CRITICAL(&_mux);
#else
_mux.lock();
#endif
}
void unlock() {
#ifdef ESP_PLATFORM
portEXIT_CRITICAL(&_mux);
#else
_mux.unlock();
#endif
}
private:
#ifdef ESP_PLATFORM
portMUX_TYPE _mux = portMUX_INITIALIZER_UNLOCKED;
#else
std::mutex _mux;
#endif
};
class ObserverGuard {
public:
explicit ObserverGuard(ObserverLock& lock) : _lock(lock) { _lock.lock(); }
~ObserverGuard() { _lock.unlock(); }
ObserverGuard(const ObserverGuard&) = delete;
ObserverGuard& operator=(const ObserverGuard&) = delete;
private:
ObserverLock& _lock;
};
template<class T>
class ObserverMailbox {
static_assert(std::is_trivially_copyable<T>::value, "mailbox requires value records");
public:
void publish(const T& value) {
ObserverGuard guard(_lock);
_value = value;
}
T read() const {
ObserverGuard guard(_lock);
return _value;
}
private:
mutable ObserverLock _lock;
T _value{};
};