diff --git a/radio/src/os/task.h b/radio/src/os/task.h index f4cfb0839..491f17cd8 100644 --- a/radio/src/os/task.h +++ b/radio/src/os/task.h @@ -43,14 +43,74 @@ bool mutex_lock(mutex_handle_t* h); void mutex_unlock(mutex_handle_t* h); bool mutex_trylock(mutex_handle_t* h); + +// this helper class is only to be used on the stack and never to be shared outside the scope where it was created +/* example usage + * + * void doWork() + * { + * MutexLock lock = MutexLock::MakeInstance(mutex); + * while(!queue.isEmpty) + * { + * lock.unlock(); + * auto item = queue.pop(); + * + * lock.lock(); + * } + * } // auto mutex unlock, because lock is destructed here + * + * int sendMessage() + * { + * MutexLock lock = MutexLock::MakeInstance(busMutex); + * if(busSendData(...) != OK) + * return ERROR; // auto mutex unlock, because lock is destructed here + * + * lock.unlock(); + * + * if() + * return ERROR; // no auto mutex unlock, because already unlocked + * lock.lock() + * if(busSendData(...) != OK) + * return ERROR; // auto mutex unlock, because lock is destructed here + * + * return OK; + * } // auto mutex unlock here, because lock is destructed here + * + * int doSomething() + * { + * + * + * if() + * { + * MutexLock lock = MutexLock::MakeInstance(busMutex); + * if(busSendData(...) != OK) + * return ERROR; // auto mutex unlock, because lock is destructed here + * } // auto mutex unlock here, because lock is destructed here + * + * + * + * return OK; + * } + */ + class MutexLock { public: - MutexLock(mutex_handle_t* mtx):mutex(mtx),locked(false) {mutex_lock(mutex); locked = true;} + static MutexLock MakeInstance(mutex_handle_t* mtx) {return MutexLock(mtx);} ~MutexLock() {if(locked) mutex_unlock(mutex);} void lock() {if(!locked) mutex_lock(mutex); locked=true;} void unlock() {if(locked) mutex_unlock(mutex); locked=false;} + + MutexLock(const MutexLock&) = delete; + MutexLock(MutexLock&&) = delete; + MutexLock& operator =(const MutexLock&) = delete; + MutexLock& operator =(MutexLock&&) = delete; + static void* operator new (size_t) = delete; + static void* operator new[] (size_t) = delete; + static void operator delete (void*) = delete; + static void operator delete[](void*) = delete; private: + MutexLock(mutex_handle_t* mtx):mutex(mtx),locked(false) {mutex_lock(mutex); locked = true;} mutex_handle_t* mutex; bool locked; }; diff --git a/radio/src/targets/common/arm/stm32/stm32_i2c_driver.cpp b/radio/src/targets/common/arm/stm32/stm32_i2c_driver.cpp index 6b58a3f05..2a8ae2b56 100644 --- a/radio/src/targets/common/arm/stm32/stm32_i2c_driver.cpp +++ b/radio/src/targets/common/arm/stm32/stm32_i2c_driver.cpp @@ -55,7 +55,7 @@ static I2C_HandleTypeDef* i2c_get_handle(uint8_t bus) } #if !defined(BOOT) -#define I2CMutex(bus) MutexLock mutexLock(&i2c_get_device(bus)->mutex) +#define I2CMutex(bus) MutexLock mutexLock = MutexLock::MakeInstance(&i2c_get_device(bus)->mutex) #else #define I2CMutex(bus) #endif