Lockable renamed to Lock (#219)

Also changed usage from unique_ptr to class value.
This commit is contained in:
Ken Van Hoeylandt 2025-02-12 22:28:22 +01:00 committed by GitHub
parent 2e86d4774b
commit 55bfb9fe3b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 257 additions and 263 deletions

View File

@ -73,7 +73,7 @@ const tt::hal::Configuration cyd_2432S024c_config = {
.initMode = tt::hal::spi::InitMode::ByTactility, .initMode = tt::hal::spi::InitMode::ByTactility,
.canReinit = false, .canReinit = false,
.hasMutableConfiguration = false, .hasMutableConfiguration = false,
.lock = tt::lvgl::getLvglSyncLockable() // esp_lvgl_port owns the lock for the display .lock = tt::lvgl::getLvglSyncLock() // esp_lvgl_port owns the lock for the display
}, },
tt::hal::spi::Configuration { tt::hal::spi::Configuration {
.device = SPI3_HOST, .device = SPI3_HOST,

View File

@ -78,7 +78,7 @@ extern const tt::hal::Configuration lilygo_tdeck = {
.initMode = tt::hal::spi::InitMode::ByTactility, .initMode = tt::hal::spi::InitMode::ByTactility,
.canReinit = false, .canReinit = false,
.hasMutableConfiguration = false, .hasMutableConfiguration = false,
.lock = tt::lvgl::getLvglSyncLockable() // esp_lvgl_port owns the lock for the display .lock = tt::lvgl::getLvglSyncLock() // esp_lvgl_port owns the lock for the display
} }
}, },
.uart { .uart {

View File

@ -18,7 +18,7 @@ std::shared_ptr<SdCardDevice> createTdeckSdCard() {
GPIO_NUM_NC, GPIO_NUM_NC,
GPIO_NUM_NC, GPIO_NUM_NC,
SdCardDevice::MountBehaviour::AtBoot, SdCardDevice::MountBehaviour::AtBoot,
tt::lvgl::getLvglSyncLockable(), tt::lvgl::getLvglSyncLock(),
{ {
TDECK_RADIO_PIN_CS, TDECK_RADIO_PIN_CS,
TDECK_LCD_PIN_CS TDECK_LCD_PIN_CS

View File

@ -75,7 +75,7 @@ extern const tt::hal::Configuration m5stack_core2 = {
.initMode = tt::hal::spi::InitMode::ByTactility, .initMode = tt::hal::spi::InitMode::ByTactility,
.canReinit = false, .canReinit = false,
.hasMutableConfiguration = false, .hasMutableConfiguration = false,
.lock = tt::lvgl::getLvglSyncLockable() // esp_lvgl_port owns the lock for the display .lock = tt::lvgl::getLvglSyncLock() // esp_lvgl_port owns the lock for the display
} }
} }
}; };

View File

@ -17,7 +17,7 @@ std::shared_ptr<SdCardDevice> createSdCard() {
GPIO_NUM_NC, GPIO_NUM_NC,
GPIO_NUM_NC, GPIO_NUM_NC,
SdCardDevice::MountBehaviour::AtBoot, SdCardDevice::MountBehaviour::AtBoot,
tt::lvgl::getLvglSyncLockable(), tt::lvgl::getLvglSyncLock(),
{ {
CORE2_LCD_PIN_CS CORE2_LCD_PIN_CS
} }

View File

@ -74,7 +74,7 @@ const tt::hal::Configuration m5stack_cores3 = {
.initMode = tt::hal::spi::InitMode::ByTactility, .initMode = tt::hal::spi::InitMode::ByTactility,
.canReinit = false, .canReinit = false,
.hasMutableConfiguration = false, .hasMutableConfiguration = false,
.lock = tt::lvgl::getLvglSyncLockable() // esp_lvgl_port owns the lock for the display .lock = tt::lvgl::getLvglSyncLock() // esp_lvgl_port owns the lock for the display
} }
} }
}; };

View File

@ -17,7 +17,7 @@ std::shared_ptr<SdCardDevice> createSdCard() {
GPIO_NUM_NC, GPIO_NUM_NC,
GPIO_NUM_NC, GPIO_NUM_NC,
SdCardDevice::MountBehaviour::AtBoot, SdCardDevice::MountBehaviour::AtBoot,
tt::lvgl::getLvglSyncLockable(), tt::lvgl::getLvglSyncLock(),
{ {
CORES3_LCD_PIN_CS CORES3_LCD_PIN_CS
}, },

View File

@ -11,14 +11,14 @@ class SimulatorSdCard final : public SdCardDevice {
private: private:
State state; State state;
std::shared_ptr<tt::Lockable> lockable; std::shared_ptr<tt::Lock> lock;
std::string mountPath; std::string mountPath;
public: public:
SimulatorSdCard() : SdCardDevice(MountBehaviour::AtBoot), SimulatorSdCard() : SdCardDevice(MountBehaviour::AtBoot),
state(State::Unmounted), state(State::Unmounted),
lockable(std::make_shared<tt::Mutex>()) lock(std::make_shared<tt::Mutex>())
{} {}
std::string getName() const final { return "Mock SD Card"; } std::string getName() const final { return "Mock SD Card"; }
@ -38,8 +38,7 @@ public:
std::string getMountPath() const final { return mountPath; }; std::string getMountPath() const final { return mountPath; };
std::shared_ptr<tt::Lockable> getLockable() const final { return lockable; } tt::Lock& getLock() const final { return *lock; }
State getState() const override { return state; } State getState() const override { return state; }
}; };

View File

@ -76,7 +76,7 @@ extern const tt::hal::Configuration unPhone = {
.initMode = tt::hal::spi::InitMode::ByTactility, .initMode = tt::hal::spi::InitMode::ByTactility,
.canReinit = false, .canReinit = false,
.hasMutableConfiguration = false, .hasMutableConfiguration = false,
.lock = tt::lvgl::getLvglSyncLockable() // esp_lvgl_port owns the lock for the display .lock = tt::lvgl::getLvglSyncLock() // esp_lvgl_port owns the lock for the display
} }
} }
}; };

View File

@ -19,7 +19,7 @@ std::shared_ptr<SdCardDevice> createUnPhoneSdCard() {
GPIO_NUM_NC, GPIO_NUM_NC,
GPIO_NUM_NC, GPIO_NUM_NC,
SdCardDevice::MountBehaviour::AtBoot, SdCardDevice::MountBehaviour::AtBoot,
tt::lvgl::getLvglSyncLockable(), tt::lvgl::getLvglSyncLock(),
{ {
UNPHONE_LORA_PIN_CS, UNPHONE_LORA_PIN_CS,
UNPHONE_LCD_PIN_CS, UNPHONE_LCD_PIN_CS,

View File

@ -51,8 +51,8 @@ public:
bool hasResult() const { return resultHolder != nullptr; } bool hasResult() const { return resultHolder != nullptr; }
void setResult(Result result, std::unique_ptr<Bundle> resultData = nullptr) { void setResult(Result result, std::unique_ptr<Bundle> resultData = nullptr) {
auto lockable = getMutex().scoped(); auto lock = getMutex().asScopedLock();
lockable->lock(portMAX_DELAY); lock.lock();
resultHolder = std::make_unique<ResultHolder>(result, std::move(resultData)); resultHolder = std::make_unique<ResultHolder>(result, std::move(resultData));
} }
@ -61,8 +61,8 @@ public:
* Note that this removes the data from the class! * Note that this removes the data from the class!
*/ */
bool moveResult(Result& outResult, std::unique_ptr<Bundle>& outBundle) { bool moveResult(Result& outResult, std::unique_ptr<Bundle>& outBundle) {
auto lockable = getMutex().scoped(); auto lock = getMutex().asScopedLock();
lockable->lock(portMAX_DELAY); lock.lock();
if (resultHolder != nullptr) { if (resultHolder != nullptr) {
outResult = resultHolder->result; outResult = resultHolder->result;

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <Tactility/Lockable.h> #include <Tactility/Lock.h>
#include <memory> #include <memory>
@ -25,6 +25,6 @@ void syncSet(LvglLock lock, LvglUnlock unlock);
bool lock(TickType_t timeout); bool lock(TickType_t timeout);
void unlock(); void unlock();
std::shared_ptr<Lockable> getLvglSyncLockable(); std::shared_ptr<Lock> getLvglSyncLock();
} // namespace } // namespace

View File

@ -32,8 +32,8 @@ std::string State::getSelectedChildPath() const {
} }
bool State::setEntriesForPath(const std::string& path) { bool State::setEntriesForPath(const std::string& path) {
auto scoped_lock = mutex.scoped(); auto lock = mutex.asScopedLock();
if (!scoped_lock->lock(100)) { if (!lock.lock(100)) {
TT_LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED_FMT, "setEntriesForPath"); TT_LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED_FMT, "setEntriesForPath");
return false; return false;
} }
@ -102,8 +102,8 @@ bool State::setEntriesForChildPath(const std::string& child_path) {
} }
bool State::getDirent(uint32_t index, dirent& dirent) { bool State::getDirent(uint32_t index, dirent& dirent) {
auto scoped_mutex = mutex.scoped(); auto lock = mutex.asScopedLock();
if (!scoped_mutex->lock(50 / portTICK_PERIOD_MS)) { if (!lock.lock(50 / portTICK_PERIOD_MS)) {
return false; return false;
} }

View File

@ -228,7 +228,7 @@ void View::showActionsForFile() {
} }
void View::update() { void View::update() {
auto scoped_lockable = lvgl::getLvglSyncLockable()->scoped(); auto scoped_lockable = lvgl::getLvglSyncLock()->scoped();
if (scoped_lockable->lock(100 / portTICK_PERIOD_MS)) { if (scoped_lockable->lock(100 / portTICK_PERIOD_MS)) {
lv_obj_clean(dir_entry_list); lv_obj_clean(dir_entry_list);
@ -277,14 +277,14 @@ void View::init(lv_obj_t* parent) {
} }
void View::onDirEntryListScrollBegin() { void View::onDirEntryListScrollBegin() {
auto scoped_lockable = lvgl::getLvglSyncLockable()->scoped(); auto scoped_lockable = lvgl::getLvglSyncLock()->scoped();
if (scoped_lockable->lock(100 / portTICK_PERIOD_MS)) { if (scoped_lockable->lock(100 / portTICK_PERIOD_MS)) {
lv_obj_add_flag(action_list, LV_OBJ_FLAG_HIDDEN); lv_obj_add_flag(action_list, LV_OBJ_FLAG_HIDDEN);
} }
} }
void View::onNavigate() { void View::onNavigate() {
auto scoped_lockable = lvgl::getLvglSyncLockable()->scoped(); auto scoped_lockable = lvgl::getLvglSyncLock()->scoped();
if (scoped_lockable->lock(100 / portTICK_PERIOD_MS)) { if (scoped_lockable->lock(100 / portTICK_PERIOD_MS)) {
lv_obj_add_flag(action_list, LV_OBJ_FLAG_HIDDEN); lv_obj_add_flag(action_list, LV_OBJ_FLAG_HIDDEN);
} }

View File

@ -49,9 +49,9 @@ void GpioApp::updatePinStates() {
} }
void GpioApp::updatePinWidgets() { void GpioApp::updatePinWidgets() {
auto scoped_lvgl_lock = lvgl::getLvglSyncLockable()->scoped(); auto scoped_lvgl_lock = lvgl::getLvglSyncLock()->scoped();
auto scoped_gpio_lock = mutex.scoped(); auto scoped_gpio_lock = mutex.asScopedLock();
if (scoped_gpio_lock->lock() && scoped_lvgl_lock->lock(100)) { if (scoped_gpio_lock.lock() && scoped_lvgl_lock->lock(100)) {
for (int j = 0; j < GPIO_NUM_MAX; ++j) { for (int j = 0; j < GPIO_NUM_MAX; ++j) {
int level = pinStates[j]; int level = pinStates[j];
lv_obj_t* label = lvPins[j]; lv_obj_t* label = lvPins[j];

View File

@ -90,7 +90,7 @@ ScreenshotApp::~ScreenshotApp() {
} }
void ScreenshotApp::onTimerTick() { void ScreenshotApp::onTimerTick() {
auto lvgl_lock = lvgl::getLvglSyncLockable()->scoped(); auto lvgl_lock = lvgl::getLvglSyncLock()->scoped();
if (lvgl_lock->lock(50 / portTICK_PERIOD_MS)) { if (lvgl_lock->lock(50 / portTICK_PERIOD_MS)) {
updateScreenshotMode(); updateScreenshotMode();
} }

View File

@ -36,7 +36,7 @@ void unlock() {
unlock_singleton(); unlock_singleton();
} }
class LvglSync : public Lockable { class LvglSync : public Lock {
public: public:
~LvglSync() override = default; ~LvglSync() override = default;
@ -50,9 +50,9 @@ public:
} }
}; };
static std::shared_ptr<Lockable> lvglSync = std::make_shared<LvglSync>(); static std::shared_ptr<Lock> lvglSync = std::make_shared<LvglSync>();
std::shared_ptr<Lockable> getLvglSyncLockable() { std::shared_ptr<Lock> getLvglSyncLock() {
return lvglSync; return lvglSync;
} }

View File

@ -147,8 +147,8 @@ static LoaderStatus startAppWithManifestInternal(
TT_LOG_I(TAG, "Start with manifest %s", manifest->id.c_str()); TT_LOG_I(TAG, "Start with manifest %s", manifest->id.c_str());
auto scoped_lock = loader_singleton->mutex.scoped(); auto lock = loader_singleton->mutex.asScopedLock();
if (!scoped_lock->lock(50 / portTICK_PERIOD_MS)) { if (!lock.lock(50 / portTICK_PERIOD_MS)) {
return LoaderStatus::ErrorInternal; return LoaderStatus::ErrorInternal;
} }
@ -202,8 +202,8 @@ static LoaderStatus startAppInternal(
static void stopAppInternal() { static void stopAppInternal() {
tt_check(loader_singleton != nullptr); tt_check(loader_singleton != nullptr);
auto scoped_lock = loader_singleton->mutex.scoped(); auto lock = loader_singleton->mutex.asScopedLock();
if (!scoped_lock->lock(50 / portTICK_PERIOD_MS)) { if (!lock.lock(50 / portTICK_PERIOD_MS)) {
return; return;
} }
@ -257,7 +257,7 @@ static void stopAppInternal() {
} }
// Unlock so that we can send results to app and they can also start/stop new apps while processing these results // Unlock so that we can send results to app and they can also start/stop new apps while processing these results
scoped_lock->unlock(); lock.unlock();
// WARNING: After this point we cannot change the app states from this method directly anymore as we don't have a lock! // WARNING: After this point we cannot change the app states from this method directly anymore as we don't have a lock!
LoaderEvent event_external = { .type = LoaderEventTypeApplicationStopped }; LoaderEvent event_external = { .type = LoaderEventTypeApplicationStopped };

View File

@ -20,8 +20,8 @@ std::shared_ptr<ScreenshotService> _Nullable optScreenshotService() {
} }
void ScreenshotService::startApps(const std::string& path) { void ScreenshotService::startApps(const std::string& path) {
auto scoped_lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
if (!scoped_lockable->lock(50 / portTICK_PERIOD_MS)) { if (!lock.lock(50 / portTICK_PERIOD_MS)) {
TT_LOG_W(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED); TT_LOG_W(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return; return;
} }
@ -36,8 +36,8 @@ void ScreenshotService::startApps(const std::string& path) {
} }
void ScreenshotService::startTimed(const std::string& path, uint8_t delayInSeconds, uint8_t amount) { void ScreenshotService::startTimed(const std::string& path, uint8_t delayInSeconds, uint8_t amount) {
auto scoped_lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
if (!scoped_lockable->lock(50 / portTICK_PERIOD_MS)) { if (!lock.lock(50 / portTICK_PERIOD_MS)) {
TT_LOG_W(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED); TT_LOG_W(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return; return;
} }
@ -52,8 +52,8 @@ void ScreenshotService::startTimed(const std::string& path, uint8_t delayInSecon
} }
void ScreenshotService::stop() { void ScreenshotService::stop() {
auto scoped_lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
if (!scoped_lockable->lock(50 / portTICK_PERIOD_MS)) { if (!lock.lock(50 / portTICK_PERIOD_MS)) {
TT_LOG_W(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED); TT_LOG_W(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return; return;
} }
@ -67,8 +67,8 @@ void ScreenshotService::stop() {
} }
Mode ScreenshotService::getMode() const { Mode ScreenshotService::getMode() const {
auto scoped_lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
if (!scoped_lockable->lock(50 / portTICK_PERIOD_MS)) { if (!lock.lock(50 / portTICK_PERIOD_MS)) {
TT_LOG_W(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED); TT_LOG_W(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return Mode::None; return Mode::None;
} }

View File

@ -23,8 +23,8 @@ ScreenshotTask::~ScreenshotTask() {
} }
bool ScreenshotTask::isInterrupted() { bool ScreenshotTask::isInterrupted() {
auto scoped_lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
if (!scoped_lockable->lock(50 / portTICK_PERIOD_MS)) { if (!lock.lock(50 / portTICK_PERIOD_MS)) {
TT_LOG_W(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED); TT_LOG_W(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return true; return true;
} }
@ -32,8 +32,8 @@ bool ScreenshotTask::isInterrupted() {
} }
bool ScreenshotTask::isFinished() { bool ScreenshotTask::isFinished() {
auto scoped_lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
if (!scoped_lockable->lock(50 / portTICK_PERIOD_MS)) { if (!lock.lock(50 / portTICK_PERIOD_MS)) {
TT_LOG_W(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED); TT_LOG_W(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return false; return false;
} }
@ -41,8 +41,8 @@ bool ScreenshotTask::isFinished() {
} }
void ScreenshotTask::setFinished() { void ScreenshotTask::setFinished() {
auto scoped_lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
scoped_lockable->lock(); lock.lock();
finished = true; finished = true;
} }
@ -106,8 +106,8 @@ void ScreenshotTask::taskMain() {
} }
void ScreenshotTask::taskStart() { void ScreenshotTask::taskStart() {
auto scoped_lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
if (!scoped_lockable->lock(50 / portTICK_PERIOD_MS)) { if (!lock.lock(50 / portTICK_PERIOD_MS)) {
TT_LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED); TT_LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return; return;
} }
@ -123,8 +123,8 @@ void ScreenshotTask::taskStart() {
} }
void ScreenshotTask::startApps(const std::string& path) { void ScreenshotTask::startApps(const std::string& path) {
auto scoped_lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
if (!scoped_lockable->lock(50 / portTICK_PERIOD_MS)) { if (!lock.lock(50 / portTICK_PERIOD_MS)) {
TT_LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED); TT_LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return; return;
} }
@ -140,8 +140,8 @@ void ScreenshotTask::startApps(const std::string& path) {
} }
void ScreenshotTask::startTimed(const std::string& path, uint8_t delay_in_seconds, uint8_t amount) { void ScreenshotTask::startTimed(const std::string& path, uint8_t delay_in_seconds, uint8_t amount) {
auto scoped_lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
if (!scoped_lockable->lock(50 / portTICK_PERIOD_MS)) { if (!lock.lock(50 / portTICK_PERIOD_MS)) {
TT_LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED); TT_LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return; return;
} }

View File

@ -8,14 +8,14 @@
namespace tt { namespace tt {
class ScopedLockableUsage; class ScopedLock;
/** Represents a lock/mutex */ /** Represents a lock/mutex */
class Lockable { class Lock {
public: public:
virtual ~Lockable() = default; virtual ~Lock() = default;
virtual bool lock(TickType_t timeout) const = 0; virtual bool lock(TickType_t timeout) const = 0;
@ -44,30 +44,29 @@ public:
void withLock(const std::function<void()>& onLockAcquired, const std::function<void()>& onLockFailed) const { withLock(portMAX_DELAY, onLockAcquired, onLockFailed); } void withLock(const std::function<void()>& onLockAcquired, const std::function<void()>& onLockFailed) const { withLock(portMAX_DELAY, onLockAcquired, onLockFailed); }
[[deprecated("use asScopedLock()")]] [[deprecated("use asScopedLock()")]]
std::unique_ptr<ScopedLockableUsage> scoped() const; std::unique_ptr<ScopedLock> scoped() const;
ScopedLockableUsage asScopedLock() const; ScopedLock asScopedLock() const;
}; };
/** /**
* Represents a lockable instance that is scoped to a specific lifecycle. * Represents a lockable instance that is scoped to a specific lifecycle.
* Once the ScopedLockableUsage is destroyed, unlock() is called automatically. * Once the ScopedLock is destroyed, unlock() is called automatically.
* *
* In other words: * In other words:
* You have to lock() this object manually, but unlock() happens automatically on destruction. * You have to lock() this object manually, but unlock() happens automatically on destruction.
*/ */
class ScopedLockableUsage final : public Lockable { class ScopedLock final : public Lock {
const Lockable& lockable; const Lock& lockable;
public: public:
using Lockable::lock; using Lock::lock;
explicit ScopedLockableUsage(const Lockable& lockable) : lockable(lockable) {} explicit ScopedLock(const Lock& lockable) : lockable(lockable) {}
~ScopedLockableUsage() final { ~ScopedLock() final {
lockable.unlock(); // We don't care whether it succeeded or not lockable.unlock(); // We don't care whether it succeeded or not
} }

View File

@ -4,10 +4,10 @@
*/ */
#pragma once #pragma once
#include "Thread.h"
#include "RtosCompatSemaphore.h"
#include "Check.h" #include "Check.h"
#include "Lockable.h" #include "Lock.h"
#include "RtosCompatSemaphore.h"
#include "Thread.h"
#include "kernel/Kernel.h" #include "kernel/Kernel.h"
#include <memory> #include <memory>
@ -17,7 +17,7 @@ namespace tt {
* Wrapper for FreeRTOS xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex * Wrapper for FreeRTOS xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex
* Cannot be used in IRQ mode (within ISR context) * Cannot be used in IRQ mode (within ISR context)
*/ */
class Mutex final : public Lockable { class Mutex final : public Lock {
public: public:
@ -40,7 +40,7 @@ private:
public: public:
using Lockable::lock; using Lock::lock;
explicit Mutex(Type type = Type::Normal); explicit Mutex(Type type = Type::Normal);
~Mutex() final = default; ~Mutex() final = default;

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "Lock.h"
#include "kernel/Kernel.h" #include "kernel/Kernel.h"
#include "Lockable.h"
#include <cassert> #include <cassert>
#include <memory> #include <memory>
@ -19,7 +19,7 @@ namespace tt {
* Wrapper for xSemaphoreCreateBinary (max count == 1) and xSemaphoreCreateCounting (max count > 1) * Wrapper for xSemaphoreCreateBinary (max count == 1) and xSemaphoreCreateCounting (max count > 1)
* Can be used from IRQ/ISR mode, but cannot be created/destroyed from such a context. * Can be used from IRQ/ISR mode, but cannot be created/destroyed from such a context.
*/ */
class Semaphore final : public Lockable { class Semaphore final : public Lock {
private: private:
@ -34,7 +34,7 @@ private:
public: public:
using Lockable::lock; using Lock::lock;
/** /**
* Cannot be called from IRQ/ISR mode. * Cannot be called from IRQ/ISR mode.

View File

@ -0,0 +1,13 @@
#include "Tactility/Lock.h"
namespace tt {
std::unique_ptr<ScopedLock> Lock::scoped() const {
return std::make_unique<ScopedLock>(*this);
}
ScopedLock Lock::asScopedLock() const {
return ScopedLock(*this);
}
}

View File

@ -1,13 +0,0 @@
#include "Tactility/Lockable.h"
namespace tt {
std::unique_ptr<ScopedLockableUsage> Lockable::scoped() const {
return std::make_unique<ScopedLockableUsage>(*this);
}
ScopedLockableUsage Lockable::asScopedLock() const {
return ScopedLockableUsage(*this);
}
}

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "./I2cCompat.h" #include "./I2cCompat.h"
#include "Tactility/Lockable.h" #include "Tactility/Lock.h"
#include <Tactility/RtosCompat.h> #include <Tactility/RtosCompat.h>
@ -89,6 +89,6 @@ bool masterHasDeviceAtAddress(i2c_port_t port, uint8_t address, TickType_t timeo
* The lock for the specified bus. * The lock for the specified bus.
* This can be used when calling native I2C functionality outside of Tactility. * This can be used when calling native I2C functionality outside of Tactility.
*/ */
Lockable& getLock(i2c_port_t port); Lock& getLock(i2c_port_t port);
} // namespace } // namespace

View File

@ -29,7 +29,7 @@ private:
public: public:
explicit SdCardDevice(MountBehaviour mountBehaviour) : mountBehaviour(mountBehaviour) {} explicit SdCardDevice(MountBehaviour mountBehaviour) : mountBehaviour(mountBehaviour) {}
virtual ~SdCardDevice() override = default; ~SdCardDevice() override = default;
Type getType() const final { return Type::SdCard; }; Type getType() const final { return Type::SdCard; };
@ -39,7 +39,7 @@ public:
/** Return empty string when not mounted or the mount path if mounted */ /** Return empty string when not mounted or the mount path if mounted */
virtual std::string getMountPath() const = 0; virtual std::string getMountPath() const = 0;
virtual std::shared_ptr<Lockable> getLockable() const = 0; virtual Lock& getLock() const = 0;
virtual MountBehaviour getMountBehaviour() const { return mountBehaviour; } virtual MountBehaviour getMountBehaviour() const { return mountBehaviour; }
bool isMounted() const { return getState() == State::Mounted; } bool isMounted() const { return getState() == State::Mounted; }
@ -55,10 +55,9 @@ std::shared_ptr<SdCardDevice> _Nullable find(const std::string& path);
template<typename ReturnType> template<typename ReturnType>
inline ReturnType withSdCardLock(const std::string& path, std::function<ReturnType()> fn) { inline ReturnType withSdCardLock(const std::string& path, std::function<ReturnType()> fn) {
auto sdcard = find(path); auto sdcard = find(path);
std::unique_ptr<ScopedLockableUsage> scoped_lockable;
if (sdcard != nullptr) { if (sdcard != nullptr) {
scoped_lockable = sdcard->getLockable()->scoped(); auto scoped_lockable = sdcard->getLock().asScopedLock();
scoped_lockable->lock(portMAX_DELAY); scoped_lockable.lock(portMAX_DELAY);
} }
return fn(); return fn();

View File

@ -26,7 +26,7 @@ public:
gpio_num_t spiPinWp, gpio_num_t spiPinWp,
gpio_num_t spiPinInt, gpio_num_t spiPinInt,
MountBehaviour mountBehaviourAtBoot, MountBehaviour mountBehaviourAtBoot,
std::shared_ptr<Lockable> lockable = std::make_shared<Mutex>(), std::shared_ptr<Lock> lockable = std::make_shared<Mutex>(),
std::vector<gpio_num_t> csPinWorkAround = std::vector<gpio_num_t>(), std::vector<gpio_num_t> csPinWorkAround = std::vector<gpio_num_t>(),
spi_host_device_t spiHost = SPI2_HOST, spi_host_device_t spiHost = SPI2_HOST,
int spiFrequencyKhz = SDMMC_FREQ_DEFAULT int spiFrequencyKhz = SDMMC_FREQ_DEFAULT
@ -49,7 +49,7 @@ public:
gpio_num_t spiPinWp; // Write-protect gpio_num_t spiPinWp; // Write-protect
gpio_num_t spiPinInt; // Interrupt gpio_num_t spiPinInt; // Interrupt
SdCardDevice::MountBehaviour mountBehaviourAtBoot; SdCardDevice::MountBehaviour mountBehaviourAtBoot;
std::shared_ptr<Lockable> _Nullable lockable; std::shared_ptr<Lock> _Nullable lockable;
std::vector<gpio_num_t> csPinWorkAround; std::vector<gpio_num_t> csPinWorkAround;
spi_host_device_t spiHost; spi_host_device_t spiHost;
bool formatOnMountFailed = false; bool formatOnMountFailed = false;
@ -80,7 +80,7 @@ public:
bool unmount() final; bool unmount() final;
std::string getMountPath() const final { return mountPath; } std::string getMountPath() const final { return mountPath; }
std::shared_ptr<Lockable> getLockable() const final { return config->lockable; } Lock& getLock() const final { return *config->lockable; }
State getState() const override; State getState() const override;

View File

@ -2,7 +2,7 @@
#include "SpiCompat.h" #include "SpiCompat.h"
#include <Tactility/Lockable.h> #include <Tactility/Lock.h>
#include <Tactility/RtosCompat.h> #include <Tactility/RtosCompat.h>
namespace tt::hal::spi { namespace tt::hal::spi {
@ -26,7 +26,7 @@ struct Configuration {
/** Whether configuration can be changed. */ /** Whether configuration can be changed. */
bool hasMutableConfiguration; bool hasMutableConfiguration;
/** Optional custom lock */ /** Optional custom lock */
std::shared_ptr<Lockable> _Nullable lock; std::shared_ptr<Lock> _Nullable lock;
}; };
enum class Status { enum class Status {
@ -45,6 +45,6 @@ bool stop(spi_host_device_t device);
bool isStarted(spi_host_device_t device); bool isStarted(spi_host_device_t device);
/** @return the lock that represents the specified device. Can be used with third party SPI implementations or native API calls (e.g. ESP-IDF). */ /** @return the lock that represents the specified device. Can be used with third party SPI implementations or native API calls (e.g. ESP-IDF). */
Lockable& getLock(spi_host_device_t device); Lock& getLock(spi_host_device_t device);
} // namespace tt::hal::spi } // namespace tt::hal::spi

View File

@ -3,7 +3,7 @@
#include <Tactility/RtosCompat.h> #include <Tactility/RtosCompat.h>
#include "../Gpio.h" #include "../Gpio.h"
#include "Tactility/Lockable.h" #include "Tactility/Lock.h"
#include "UartCompat.h" #include "UartCompat.h"
#include <memory> #include <memory>
@ -59,7 +59,7 @@ bool stop(uart_port_t port);
bool isStarted(uart_port_t port); bool isStarted(uart_port_t port);
/** @return a lock that is usable for using ESP-IDF directly, or for use with third party APIs */ /** @return a lock that is usable for using ESP-IDF directly, or for use with third party APIs */
Lockable& getLock(uart_port_t port); Lock& getLock(uart_port_t port);
/** /**
* Read up to a specified amount of bytes * Read up to a specified amount of bytes

View File

@ -19,56 +19,55 @@ auto toVector(RangeType&& range) {
} }
void registerDevice(const std::shared_ptr<Device>& device) { void registerDevice(const std::shared_ptr<Device>& device) {
auto scoped_mutex = mutex.scoped(); auto scoped_mutex = mutex.asScopedLock();
if (scoped_mutex->lock()) { scoped_mutex.lock();
if (findDevice(device->getId()) == nullptr) {
devices.push_back(device); if (findDevice(device->getId()) == nullptr) {
TT_LOG_I(TAG, "Registered %s with id %lu", device->getName().c_str(), device->getId()); devices.push_back(device);
} else { TT_LOG_I(TAG, "Registered %s with id %lu", device->getName().c_str(), device->getId());
TT_LOG_W(TAG, "Device %s with id %lu was already registered", device->getName().c_str(), device->getId()); } else {
} TT_LOG_W(TAG, "Device %s with id %lu was already registered", device->getName().c_str(), device->getId());
} }
} }
void deregisterDevice(const std::shared_ptr<Device>& device) { void deregisterDevice(const std::shared_ptr<Device>& device) {
auto scoped_mutex = mutex.scoped(); auto scoped_mutex = mutex.asScopedLock();
scoped_mutex.lock();
auto id_to_remove = device->getId(); auto id_to_remove = device->getId();
if (scoped_mutex->lock()) { auto remove_iterator = std::remove_if(devices.begin(), devices.end(), [id_to_remove](const auto& device) {
auto remove_iterator = std::remove_if(devices.begin(), devices.end(), [id_to_remove](const auto& device) { return device->getId() == id_to_remove;
return device->getId() == id_to_remove; });
}); if (remove_iterator != devices.end()) {
if (remove_iterator != devices.end()) { TT_LOG_I(TAG, "Deregistering %s with id %lu", device->getName().c_str(), device->getId());
TT_LOG_I(TAG, "Deregistering %s with id %lu", device->getName().c_str(), device->getId()); devices.erase(remove_iterator);
devices.erase(remove_iterator); } else {
} else { TT_LOG_W(TAG, "Deregistering %s with id %lu failed: not found", device->getName().c_str(), device->getId());
TT_LOG_W(TAG, "Deregistering %s with id %lu failed: not found", device->getName().c_str(), device->getId());
}
} }
} }
std::vector<std::shared_ptr<Device>> findDevices(const std::function<bool(const std::shared_ptr<Device>&)>& filterFunction) { std::vector<std::shared_ptr<Device>> findDevices(const std::function<bool(const std::shared_ptr<Device>&)>& filterFunction) {
auto scoped_mutex = mutex.scoped(); auto scoped_mutex = mutex.asScopedLock();
if (scoped_mutex->lock()) { scoped_mutex.lock();
auto devices_view = devices | std::views::filter([&filterFunction](auto& device) {
return filterFunction(device); auto devices_view = devices | std::views::filter([&filterFunction](auto& device) {
}); return filterFunction(device);
return toVector(devices_view); });
} return toVector(devices_view);
return {};
} }
std::shared_ptr<Device> _Nullable findDevice(const std::function<bool(const std::shared_ptr<Device>&)>& filterFunction) { std::shared_ptr<Device> _Nullable findDevice(const std::function<bool(const std::shared_ptr<Device>&)>& filterFunction) {
auto scoped_mutex = mutex.scoped(); auto scoped_mutex = mutex.asScopedLock();
if (scoped_mutex->lock()) { scoped_mutex.lock();
auto result_set = devices | std::views::filter([&filterFunction](auto& device) {
return filterFunction(device);
});
if (!result_set.empty()) {
return result_set.front();
}
}
return nullptr; auto result_set = devices | std::views::filter([&filterFunction](auto& device) {
return filterFunction(device);
});
if (!result_set.empty()) {
return result_set.front();
} else {
return nullptr;
}
} }
std::shared_ptr<Device> _Nullable findDevice(std::string name) { std::shared_ptr<Device> _Nullable findDevice(std::string name) {

View File

@ -75,8 +75,8 @@ int32_t GpsDevice::threadMain() {
} }
bool GpsDevice::start() { bool GpsDevice::start() {
auto scoped_lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
scoped_lockable->lock(portMAX_DELAY); lock.lock();
if (thread != nullptr && thread->getState() != Thread::State::Stopped) { if (thread != nullptr && thread->getState() != Thread::State::Stopped) {
TT_LOG_W(TAG, "Already started"); TT_LOG_W(TAG, "Already started");
@ -108,8 +108,8 @@ bool GpsDevice::start() {
} }
bool GpsDevice::stop() { bool GpsDevice::stop() {
auto scoped_lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
scoped_lockable->lock(); lock.lock(portMAX_DELAY);
if (thread != nullptr) { if (thread != nullptr) {
threadInterrupted = true; threadInterrupted = true;
@ -119,11 +119,11 @@ bool GpsDevice::stop() {
if (old_thread->getState() != Thread::State::Stopped) { if (old_thread->getState() != Thread::State::Stopped) {
// Unlock so thread can lock // Unlock so thread can lock
scoped_lockable->unlock(); lock.unlock();
// Wait for thread to finish // Wait for thread to finish
old_thread->join(); old_thread->join();
// Re-lock to continue logic below // Re-lock to continue logic below
scoped_lockable->lock(); lock.lock();
} }
} }
@ -138,14 +138,14 @@ bool GpsDevice::stop() {
} }
bool GpsDevice::isStarted() const { bool GpsDevice::isStarted() const {
auto scoped_lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
scoped_lockable->lock(portMAX_DELAY); lock.lock();
return thread != nullptr && thread->getState() != Thread::State::Stopped; return thread != nullptr && thread->getState() != Thread::State::Stopped;
} }
bool GpsDevice::isThreadInterrupted() const { bool GpsDevice::isThreadInterrupted() const {
auto scoped_lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
scoped_lockable->lock(portMAX_DELAY); lock.lock(portMAX_DELAY);
return threadInterrupted; return threadInterrupted;
} }

View File

@ -23,8 +23,8 @@ SatelliteStorage::SatelliteRecord* SatelliteStorage::findRecord(int number) {
} }
SatelliteStorage::SatelliteRecord* SatelliteStorage::findUnusedRecord() { SatelliteStorage::SatelliteRecord* SatelliteStorage::findUnusedRecord() {
auto lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
lockable->lock(); lock.lock();
auto result = records | std::views::filter([](auto& record) { auto result = records | std::views::filter([](auto& record) {
return !record.inUse; return !record.inUse;
@ -41,8 +41,8 @@ SatelliteStorage::SatelliteRecord* SatelliteStorage::findUnusedRecord() {
} }
SatelliteStorage::SatelliteRecord* SatelliteStorage::findRecordToRecycle() { SatelliteStorage::SatelliteRecord* SatelliteStorage::findRecordToRecycle() {
auto lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
lockable->lock(); lock.lock();
int candidate_index = -1; int candidate_index = -1;
auto candidate_age = portMAX_DELAY; auto candidate_age = portMAX_DELAY;
@ -72,8 +72,8 @@ SatelliteStorage::SatelliteRecord* SatelliteStorage::findRecordToRecycle() {
} }
SatelliteStorage::SatelliteRecord* SatelliteStorage::findWithFallback(int number) { SatelliteStorage::SatelliteRecord* SatelliteStorage::findWithFallback(int number) {
auto lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
lockable->lock(); lock.lock();
if (auto* found_record = findRecord(number)) { if (auto* found_record = findRecord(number)) {
return found_record; return found_record;
@ -85,8 +85,8 @@ SatelliteStorage::SatelliteRecord* SatelliteStorage::findWithFallback(int number
} }
void SatelliteStorage::notify(const minmea_sat_info& data) { void SatelliteStorage::notify(const minmea_sat_info& data) {
auto lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
lockable->lock(); lock.lock();
auto* record = findWithFallback(data.nr); auto* record = findWithFallback(data.nr);
if (record != nullptr) { if (record != nullptr) {
@ -98,8 +98,8 @@ void SatelliteStorage::notify(const minmea_sat_info& data) {
} }
void SatelliteStorage::getRecords(const std::function<void(const minmea_sat_info&)>& onRecord) const { void SatelliteStorage::getRecords(const std::function<void(const minmea_sat_info&)>& onRecord) const {
auto lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
lockable->lock(); lock.lock();
TickType_t expire_duration = kernel::secondsToTicks(recentTimeSeconds); TickType_t expire_duration = kernel::secondsToTicks(recentTimeSeconds);
TickType_t now = kernel::getTicks(); TickType_t now = kernel::getTicks();

View File

@ -76,8 +76,8 @@ bool init(const std::vector<i2c::Configuration>& configurations) {
} }
bool configure(i2c_port_t port, const i2c_config_t& configuration) { bool configure(i2c_port_t port, const i2c_config_t& configuration) {
auto lockable = getLock(port).asScopedLock(); auto lock = getLock(port).asScopedLock();
lockable.lock(); lock.lock();
Data& data = dataArray[port]; Data& data = dataArray[port];
if (data.isStarted) { if (data.isStarted) {
@ -93,8 +93,8 @@ bool configure(i2c_port_t port, const i2c_config_t& configuration) {
} }
bool start(i2c_port_t port) { bool start(i2c_port_t port) {
auto lockable = getLock(port).asScopedLock(); auto lock = getLock(port).asScopedLock();
lockable.lock(); lock.lock();
Data& data = dataArray[port]; Data& data = dataArray[port];
printInfo(data); printInfo(data);
@ -131,8 +131,8 @@ bool start(i2c_port_t port) {
} }
bool stop(i2c_port_t port) { bool stop(i2c_port_t port) {
auto lockable = getLock(port).asScopedLock(); auto lock = getLock(port).asScopedLock();
lockable.lock(); lock.lock();
Data& data = dataArray[port]; Data& data = dataArray[port];
Configuration& config = data.configuration; Configuration& config = data.configuration;
@ -162,14 +162,14 @@ bool stop(i2c_port_t port) {
} }
bool isStarted(i2c_port_t port) { bool isStarted(i2c_port_t port) {
auto lockable = getLock(port).asScopedLock(); auto lock = getLock(port).asScopedLock();
lockable.lock(); lock.lock();
return dataArray[port].isStarted; return dataArray[port].isStarted;
} }
bool masterRead(i2c_port_t port, uint8_t address, uint8_t* data, size_t dataSize, TickType_t timeout) { bool masterRead(i2c_port_t port, uint8_t address, uint8_t* data, size_t dataSize, TickType_t timeout) {
auto lockable = getLock(port).asScopedLock(); auto lock = getLock(port).asScopedLock();
if (!lockable.lock(timeout)) { if (!lock.lock(timeout)) {
TT_LOG_E(TAG, "(%d) Mutex timeout", port); TT_LOG_E(TAG, "(%d) Mutex timeout", port);
return false; return false;
} }
@ -184,8 +184,8 @@ bool masterRead(i2c_port_t port, uint8_t address, uint8_t* data, size_t dataSize
} }
bool masterReadRegister(i2c_port_t port, uint8_t address, uint8_t reg, uint8_t* data, size_t dataSize, TickType_t timeout) { bool masterReadRegister(i2c_port_t port, uint8_t address, uint8_t reg, uint8_t* data, size_t dataSize, TickType_t timeout) {
auto lockable = getLock(port).asScopedLock(); auto lock = getLock(port).asScopedLock();
if (!lockable.lock(timeout)) { if (!lock.lock(timeout)) {
TT_LOG_E(TAG, "(%d) Mutex timeout", port); TT_LOG_E(TAG, "(%d) Mutex timeout", port);
return false; return false;
} }
@ -217,8 +217,8 @@ bool masterReadRegister(i2c_port_t port, uint8_t address, uint8_t reg, uint8_t*
} }
bool masterWrite(i2c_port_t port, uint8_t address, const uint8_t* data, uint16_t dataSize, TickType_t timeout) { bool masterWrite(i2c_port_t port, uint8_t address, const uint8_t* data, uint16_t dataSize, TickType_t timeout) {
auto lockable = getLock(port).asScopedLock(); auto lock = getLock(port).asScopedLock();
if (!lockable.lock(timeout)) { if (!lock.lock(timeout)) {
TT_LOG_E(TAG, "(%d) Mutex timeout", port); TT_LOG_E(TAG, "(%d) Mutex timeout", port);
return false; return false;
} }
@ -235,8 +235,8 @@ bool masterWrite(i2c_port_t port, uint8_t address, const uint8_t* data, uint16_t
bool masterWriteRegister(i2c_port_t port, uint8_t address, uint8_t reg, const uint8_t* data, uint16_t dataSize, TickType_t timeout) { bool masterWriteRegister(i2c_port_t port, uint8_t address, uint8_t reg, const uint8_t* data, uint16_t dataSize, TickType_t timeout) {
tt_check(reg != 0); tt_check(reg != 0);
auto lockable = getLock(port).asScopedLock(); auto lock = getLock(port).asScopedLock();
if (!lockable.lock(timeout)) { if (!lock.lock(timeout)) {
TT_LOG_E(TAG, "(%d) Mutex timeout", port); TT_LOG_E(TAG, "(%d) Mutex timeout", port);
return false; return false;
} }
@ -277,8 +277,8 @@ bool masterWriteRegisterArray(i2c_port_t port, uint8_t address, const uint8_t* d
} }
bool masterWriteRead(i2c_port_t port, uint8_t address, const uint8_t* writeData, size_t writeDataSize, uint8_t* readData, size_t readDataSize, TickType_t timeout) { bool masterWriteRead(i2c_port_t port, uint8_t address, const uint8_t* writeData, size_t writeDataSize, uint8_t* readData, size_t readDataSize, TickType_t timeout) {
auto lockable = getLock(port).asScopedLock(); auto lock = getLock(port).asScopedLock();
if (!lockable.lock(timeout)) { if (!lock.lock(timeout)) {
TT_LOG_E(TAG, "(%d) Mutex timeout", port); TT_LOG_E(TAG, "(%d) Mutex timeout", port);
return false; return false;
} }
@ -293,8 +293,8 @@ bool masterWriteRead(i2c_port_t port, uint8_t address, const uint8_t* writeData,
} }
bool masterHasDeviceAtAddress(i2c_port_t port, uint8_t address, TickType_t timeout) { bool masterHasDeviceAtAddress(i2c_port_t port, uint8_t address, TickType_t timeout) {
auto lockable = getLock(port).asScopedLock(); auto lock = getLock(port).asScopedLock();
if (!lockable.lock(timeout)) { if (!lock.lock(timeout)) {
TT_LOG_E(TAG, "(%d) Mutex timeout", port); TT_LOG_E(TAG, "(%d) Mutex timeout", port);
return false; return false;
} }
@ -308,7 +308,7 @@ bool masterHasDeviceAtAddress(i2c_port_t port, uint8_t address, TickType_t timeo
#endif // ESP_PLATFORM #endif // ESP_PLATFORM
} }
Lockable& getLock(i2c_port_t port) { Lock& getLock(i2c_port_t port) {
return dataArray[port].mutex; return dataArray[port].mutex;
} }

View File

@ -7,7 +7,7 @@
namespace tt::hal::spi { namespace tt::hal::spi {
struct Data { struct Data {
std::shared_ptr<Lockable> lock; std::shared_ptr<Lock> lock;
bool isConfigured = false; bool isConfigured = false;
bool isStarted = false; bool isStarted = false;
Configuration configuration; Configuration configuration;
@ -169,7 +169,7 @@ bool isStarted(spi_host_device_t device) {
return dataArray[device].isStarted; return dataArray[device].isStarted;
} }
Lockable& getLock(spi_host_device_t device) { Lock& getLock(spi_host_device_t device) {
return *dataArray[device].lock; return *dataArray[device].lock;
} }

View File

@ -180,7 +180,7 @@ bool isStarted(uart_port_t port) {
return dataArray[port].isStarted; return dataArray[port].isStarted;
} }
Lockable& getLock(uart_port_t port) { Lock& getLock(uart_port_t port) {
return dataArray[port].mutex; return dataArray[port].mutex;
} }

View File

@ -8,8 +8,8 @@ using tt::hal::gps::GpsDevice;
namespace tt::service::gps { namespace tt::service::gps {
GpsService::GpsDeviceRecord* _Nullable GpsService::findGpsRecord(const std::shared_ptr<GpsDevice>& device) { GpsService::GpsDeviceRecord* _Nullable GpsService::findGpsRecord(const std::shared_ptr<GpsDevice>& device) {
auto lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
lockable->lock(); lock.lock();
auto result = std::views::filter(deviceRecords, [&device](auto& record){ auto result = std::views::filter(deviceRecords, [&device](auto& record){
return record.device.get() == device.get(); return record.device.get() == device.get();
@ -22,8 +22,8 @@ GpsService::GpsDeviceRecord* _Nullable GpsService::findGpsRecord(const std::shar
} }
void GpsService::addGpsDevice(const std::shared_ptr<GpsDevice>& device) { void GpsService::addGpsDevice(const std::shared_ptr<GpsDevice>& device) {
auto lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
lockable->lock(); lock.lock();
GpsDeviceRecord record = { .device = device }; GpsDeviceRecord record = { .device = device };
@ -35,8 +35,8 @@ void GpsService::addGpsDevice(const std::shared_ptr<GpsDevice>& device) {
} }
void GpsService::removeGpsDevice(const std::shared_ptr<GpsDevice>& device) { void GpsService::removeGpsDevice(const std::shared_ptr<GpsDevice>& device) {
auto lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
lockable->lock(); lock.lock();
GpsDeviceRecord* record = findGpsRecord(device); GpsDeviceRecord* record = findGpsRecord(device);
@ -50,8 +50,8 @@ void GpsService::removeGpsDevice(const std::shared_ptr<GpsDevice>& device) {
} }
void GpsService::onStart(tt::service::ServiceContext &serviceContext) { void GpsService::onStart(tt::service::ServiceContext &serviceContext) {
auto lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
lockable->lock(); lock.lock();
deviceRecords.clear(); deviceRecords.clear();
@ -71,8 +71,8 @@ void GpsService::onStop(tt::service::ServiceContext &serviceContext) {
bool GpsService::startGpsDevice(GpsDeviceRecord& record) { bool GpsService::startGpsDevice(GpsDeviceRecord& record) {
TT_LOG_I(TAG, "[device %lu] starting", record.device->getId()); TT_LOG_I(TAG, "[device %lu] starting", record.device->getId());
auto lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
lockable->lock(); lock.lock();
auto device = record.device; auto device = record.device;
@ -114,8 +114,8 @@ bool GpsService::stopGpsDevice(GpsDeviceRecord& record) {
bool GpsService::startReceiving() { bool GpsService::startReceiving() {
TT_LOG_I(TAG, "Start receiving"); TT_LOG_I(TAG, "Start receiving");
auto lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
lockable->lock(); lock.lock();
bool started_one_or_more = false; bool started_one_or_more = false;
@ -131,8 +131,8 @@ bool GpsService::startReceiving() {
void GpsService::stopReceiving() { void GpsService::stopReceiving() {
TT_LOG_I(TAG, "Stop receiving"); TT_LOG_I(TAG, "Stop receiving");
auto lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
lockable->lock(); lock.lock();
for (auto& record : deviceRecords) { for (auto& record : deviceRecords) {
stopGpsDevice(record); stopGpsDevice(record);
@ -142,8 +142,8 @@ void GpsService::stopReceiving() {
} }
bool GpsService::isReceiving() { bool GpsService::isReceiving() {
auto lockable = mutex.scoped(); auto lock = mutex.asScopedLock();
lockable->lock(); lock.lock();
return receiving; return receiving;
} }

View File

@ -73,54 +73,54 @@ public:
bool connection_target_remember = false; // Whether to store the connection_target on successful connection or not bool connection_target_remember = false; // Whether to store the connection_target on successful connection or not
RadioState getRadioState() const { RadioState getRadioState() const {
auto lockable = dataMutex.scoped(); auto lock = dataMutex.asScopedLock();
lockable->lock(); lock.lock();
// TODO: Handle lock failure // TODO: Handle lock failure
return radio_state; return radio_state;
} }
void setRadioState(RadioState newState) { void setRadioState(RadioState newState) {
auto lockable = dataMutex.scoped(); auto lock = dataMutex.asScopedLock();
lockable->lock(); lock.lock();
// TODO: Handle lock failure // TODO: Handle lock failure
radio_state = newState; radio_state = newState;
} }
bool isScanning() const { bool isScanning() const {
auto lockable = dataMutex.scoped(); auto lock = dataMutex.asScopedLock();
lockable->lock(); lock.lock();
// TODO: Handle lock failure // TODO: Handle lock failure
return scan_active; return scan_active;
} }
void setScanning(bool newState) { void setScanning(bool newState) {
auto lockable = dataMutex.scoped(); auto lock = dataMutex.asScopedLock();
lockable->lock(); lock.lock();
// TODO: Handle lock failure // TODO: Handle lock failure
scan_active = newState; scan_active = newState;
} }
bool isScanActive() const { bool isScanActive() const {
auto lcokable = dataMutex.scoped(); auto lock = dataMutex.asScopedLock();
lcokable->lock(); lock.lock();
return scan_active; return scan_active;
} }
void setScanActive(bool newState) { void setScanActive(bool newState) {
auto lockable = dataMutex.scoped(); auto lock = dataMutex.asScopedLock();
lockable->lock(); lock.lock();
scan_active = newState; scan_active = newState;
} }
bool isSecureConnection() const { bool isSecureConnection() const {
auto lockable = dataMutex.scoped(); auto lock = dataMutex.asScopedLock();
lockable->lock(); lock.lock();
return secure_connection; return secure_connection;
} }
void setSecureConnection(bool newState) { void setSecureConnection(bool newState) {
auto lockable = dataMutex.scoped(); auto lock = dataMutex.asScopedLock();
lockable->lock(); lock.lock();
secure_connection = newState; secure_connection = newState;
} }
}; };
@ -191,8 +191,8 @@ void connect(const settings::WifiApSettings* ap, bool remember) {
return; return;
} }
auto lockable = wifi->dataMutex.scoped(); auto lock = wifi->dataMutex.asScopedLock();
if (!lockable->lock(10 / portTICK_PERIOD_MS)) { if (!lock.lock(10 / portTICK_PERIOD_MS)) {
return; return;
} }
@ -215,8 +215,8 @@ void disconnect() {
return; return;
} }
auto lockable = wifi->dataMutex.scoped(); auto lock = wifi->dataMutex.asScopedLock();
if (!lockable->lock(10 / portTICK_PERIOD_MS)) { if (!lock.lock(10 / portTICK_PERIOD_MS)) {
return; return;
} }
@ -237,8 +237,8 @@ void setScanRecords(uint16_t records) {
return; return;
} }
auto lockable = wifi->dataMutex.scoped(); auto lock = wifi->dataMutex.asScopedLock();
if (!lockable->lock(10 / portTICK_PERIOD_MS)) { if (!lock.lock(10 / portTICK_PERIOD_MS)) {
return; return;
} }
@ -258,8 +258,8 @@ std::vector<ApRecord> getScanResults() {
return records; return records;
} }
auto lockable = wifi->dataMutex.scoped(); auto lock = wifi->dataMutex.asScopedLock();
if (!lockable->lock(10 / portTICK_PERIOD_MS)) { if (!lock.lock(10 / portTICK_PERIOD_MS)) {
return records; return records;
} }
@ -285,8 +285,8 @@ void setEnabled(bool enabled) {
return; return;
} }
auto lockable = wifi->dataMutex.scoped(); auto lock = wifi->dataMutex.asScopedLock();
if (!lockable->lock(10 / portTICK_PERIOD_MS)) { if (!lock.lock(10 / portTICK_PERIOD_MS)) {
return; return;
} }
@ -305,8 +305,8 @@ bool isConnectionSecure() {
return false; return false;
} }
auto lockable = wifi->dataMutex.scoped(); auto lock = wifi->dataMutex.asScopedLock();
if (!lockable->lock(10 / portTICK_PERIOD_MS)) { if (!lock.lock(10 / portTICK_PERIOD_MS)) {
return false; return false;
} }
@ -326,8 +326,8 @@ int getRssi() {
// endregion Public functions // endregion Public functions
static void scan_list_alloc(std::shared_ptr<Wifi> wifi) { static void scan_list_alloc(std::shared_ptr<Wifi> wifi) {
auto lockable = wifi->dataMutex.scoped(); auto lock = wifi->dataMutex.asScopedLock();
if (lockable->lock()) { if (lock.lock()) {
assert(wifi->scan_list == nullptr); assert(wifi->scan_list == nullptr);
wifi->scan_list = static_cast<wifi_ap_record_t*>(malloc(sizeof(wifi_ap_record_t) * wifi->scan_list_limit)); wifi->scan_list = static_cast<wifi_ap_record_t*>(malloc(sizeof(wifi_ap_record_t) * wifi->scan_list_limit));
wifi->scan_list_count = 0; wifi->scan_list_count = 0;
@ -335,8 +335,8 @@ static void scan_list_alloc(std::shared_ptr<Wifi> wifi) {
} }
static void scan_list_alloc_safely(std::shared_ptr<Wifi> wifi) { static void scan_list_alloc_safely(std::shared_ptr<Wifi> wifi) {
auto lockable = wifi->dataMutex.scoped(); auto lock = wifi->dataMutex.asScopedLock();
if (lockable->lock()) { if (lock.lock()) {
if (wifi->scan_list == nullptr) { if (wifi->scan_list == nullptr) {
scan_list_alloc(wifi); scan_list_alloc(wifi);
} }
@ -344,8 +344,8 @@ static void scan_list_alloc_safely(std::shared_ptr<Wifi> wifi) {
} }
static void scan_list_free(std::shared_ptr<Wifi> wifi) { static void scan_list_free(std::shared_ptr<Wifi> wifi) {
auto lockable = wifi->dataMutex.scoped(); auto lock = wifi->dataMutex.asScopedLock();
if (lockable->lock()) { if (lock.lock()) {
assert(wifi->scan_list != nullptr); assert(wifi->scan_list != nullptr);
free(wifi->scan_list); free(wifi->scan_list);
wifi->scan_list = nullptr; wifi->scan_list = nullptr;
@ -354,8 +354,8 @@ static void scan_list_free(std::shared_ptr<Wifi> wifi) {
} }
static void scan_list_free_safely(std::shared_ptr<Wifi> wifi) { static void scan_list_free_safely(std::shared_ptr<Wifi> wifi) {
auto lockable = wifi->dataMutex.scoped(); auto lock = wifi->dataMutex.asScopedLock();
if (lockable->lock()) { if (lock.lock()) {
if (wifi->scan_list != nullptr) { if (wifi->scan_list != nullptr) {
scan_list_free(wifi); scan_list_free(wifi);
} }
@ -363,8 +363,8 @@ static void scan_list_free_safely(std::shared_ptr<Wifi> wifi) {
} }
static void publish_event_simple(std::shared_ptr<Wifi> wifi, EventType type) { static void publish_event_simple(std::shared_ptr<Wifi> wifi, EventType type) {
auto lockable = wifi->dataMutex.scoped(); auto lock = wifi->dataMutex.asScopedLock();
if (lockable->lock()) { if (lock.lock()) {
Event turning_on_event = {.type = type}; Event turning_on_event = {.type = type};
wifi->pubsub->publish(&turning_on_event); wifi->pubsub->publish(&turning_on_event);
} }
@ -380,8 +380,8 @@ static bool copy_scan_list(std::shared_ptr<Wifi> wifi) {
return false; return false;
} }
auto lockable = wifi->dataMutex.scoped(); auto lock = wifi->dataMutex.asScopedLock();
if (!lockable->lock()) { if (lock.lock()) {
return false; return false;
} }
@ -407,9 +407,9 @@ static bool copy_scan_list(std::shared_ptr<Wifi> wifi) {
static bool find_auto_connect_ap(std::shared_ptr<void> context, settings::WifiApSettings& settings) { static bool find_auto_connect_ap(std::shared_ptr<void> context, settings::WifiApSettings& settings) {
auto wifi = std::static_pointer_cast<Wifi>(context); auto wifi = std::static_pointer_cast<Wifi>(context);
auto lockable = wifi->dataMutex.scoped(); auto lock = wifi->dataMutex.asScopedLock();
if (lockable->lock(10 / portTICK_PERIOD_MS)) { if (lock.lock(10 / portTICK_PERIOD_MS)) {
TT_LOG_I(TAG, "auto_connect()"); TT_LOG_I(TAG, "auto_connect()");
for (int i = 0; i < wifi->scan_list_count; ++i) { for (int i = 0; i < wifi->scan_list_count; ++i) {
auto ssid = reinterpret_cast<const char*>(wifi->scan_list[i].ssid); auto ssid = reinterpret_cast<const char*>(wifi->scan_list[i].ssid);
@ -512,9 +512,8 @@ static void dispatchEnable(std::shared_ptr<void> context) {
return; return;
} }
auto lockable = wifi->radioMutex.scoped(); auto lock = wifi->radioMutex.asScopedLock();
if (lock.lock(50 / portTICK_PERIOD_MS)) {
if (lockable->lock(50 / portTICK_PERIOD_MS)) {
TT_LOG_I(TAG, "Enabling"); TT_LOG_I(TAG, "Enabling");
wifi->setRadioState(RadioState::OnPending); wifi->setRadioState(RadioState::OnPending);
publish_event_simple(wifi, EventType::RadioStateOnPending); publish_event_simple(wifi, EventType::RadioStateOnPending);
@ -590,9 +589,9 @@ static void dispatchEnable(std::shared_ptr<void> context) {
static void dispatchDisable(std::shared_ptr<void> context) { static void dispatchDisable(std::shared_ptr<void> context) {
TT_LOG_I(TAG, "dispatchDisable()"); TT_LOG_I(TAG, "dispatchDisable()");
auto wifi = std::static_pointer_cast<Wifi>(context); auto wifi = std::static_pointer_cast<Wifi>(context);
auto lockable = wifi->radioMutex.scoped(); auto lock = wifi->radioMutex.asScopedLock();
if (!lockable->lock(50 / portTICK_PERIOD_MS)) { if (!lock.lock(50 / portTICK_PERIOD_MS)) {
TT_LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED_FMT, "disable()"); TT_LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED_FMT, "disable()");
return; return;
} }
@ -657,9 +656,9 @@ static void dispatchDisable(std::shared_ptr<void> context) {
static void dispatchScan(std::shared_ptr<void> context) { static void dispatchScan(std::shared_ptr<void> context) {
TT_LOG_I(TAG, "dispatchScan()"); TT_LOG_I(TAG, "dispatchScan()");
auto wifi = std::static_pointer_cast<Wifi>(context); auto wifi = std::static_pointer_cast<Wifi>(context);
auto lockable = wifi->radioMutex.scoped(); auto lock = wifi->radioMutex.asScopedLock();
if (!lockable->lock(10 / portTICK_PERIOD_MS)) { if (!lock.lock(10 / portTICK_PERIOD_MS)) {
TT_LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED); TT_LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return; return;
} }
@ -691,9 +690,9 @@ static void dispatchScan(std::shared_ptr<void> context) {
static void dispatchConnect(std::shared_ptr<void> context) { static void dispatchConnect(std::shared_ptr<void> context) {
TT_LOG_I(TAG, "dispatchConnect()"); TT_LOG_I(TAG, "dispatchConnect()");
auto wifi = std::static_pointer_cast<Wifi>(context); auto wifi = std::static_pointer_cast<Wifi>(context);
auto lockable = wifi->radioMutex.scoped(); auto lock = wifi->radioMutex.asScopedLock();
if (!lockable->lock(50 / portTICK_PERIOD_MS)) { if (!lock.lock(50 / portTICK_PERIOD_MS)) {
TT_LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED_FMT, "dispatchConnect()"); TT_LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED_FMT, "dispatchConnect()");
return; return;
} }
@ -790,9 +789,9 @@ static void dispatchConnect(std::shared_ptr<void> context) {
static void dispatchDisconnectButKeepActive(std::shared_ptr<void> context) { static void dispatchDisconnectButKeepActive(std::shared_ptr<void> context) {
TT_LOG_I(TAG, "dispatchDisconnectButKeepActive()"); TT_LOG_I(TAG, "dispatchDisconnectButKeepActive()");
auto wifi = std::static_pointer_cast<Wifi>(context); auto wifi = std::static_pointer_cast<Wifi>(context);
auto lockable = wifi->radioMutex.scoped(); auto lock = wifi->radioMutex.asScopedLock();
if (!lockable->lock(50 / portTICK_PERIOD_MS)) { if (!lock.lock(50 / portTICK_PERIOD_MS)) {
TT_LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED); TT_LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return; return;
} }
@ -835,9 +834,8 @@ static void dispatchDisconnectButKeepActive(std::shared_ptr<void> context) {
} }
static bool shouldScanForAutoConnect(std::shared_ptr<Wifi> wifi) { static bool shouldScanForAutoConnect(std::shared_ptr<Wifi> wifi) {
auto lockable = wifi->dataMutex.scoped(); auto lock = wifi->dataMutex.asScopedLock();
if (!lock.lock(100)) {
if (!lockable->lock(100)) {
return false; return false;
} }

View File

@ -18,7 +18,7 @@ add_test(NAME TactilityCoreTests
COMMAND TactilityCoreTests COMMAND TactilityCoreTests
) )
target_link_libraries(TactilityCoreTests target_link_libraries(TactilityCoreTests PUBLIC
PUBLIC TactilityCore TactilityCore
freertos_kernel freertos_kernel
) )

View File

@ -1,5 +1,5 @@
#include "doctest.h" #include "doctest.h"
#include <Tactility/Lockable.h> #include <Tactility/Lock.h>
#include <Tactility/Mutex.h> #include <Tactility/Mutex.h>
#include <Tactility/Semaphore.h> #include <Tactility/Semaphore.h>