From 54c8a2d223dd5f4d5f13186f2c4fa9eb1a528377 Mon Sep 17 00:00:00 2001 From: gurux13 Date: Fri, 10 Apr 2020 12:46:28 +0100 Subject: [PATCH 1/3] Add locks --- RCSwitch.cpp | 32 ++++++++++++++++++++++++++++++++ RCSwitch.h | 20 ++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/RCSwitch.cpp b/RCSwitch.cpp index ac55acb..9f535bd 100644 --- a/RCSwitch.cpp +++ b/RCSwitch.cpp @@ -33,6 +33,7 @@ */ #include "RCSwitch.h" +#include #ifdef RaspberryPi // PROGMEM and _P functions are for AVR based microprocessors, @@ -103,6 +104,9 @@ const unsigned int RCSwitch::nSeparationLimit = 4300; // according to discussion on issue #14 it might be more suitable to set the separation // limit to the same time as the 'low' part of the sync signal for the current protocol. unsigned int RCSwitch::timings[RCSWITCH_MAX_CHANGES]; +volatile bool RCSwitch::useLocks = false; +std::mutex RCSwitch::mutex; +std::condition_variable RCSwitch::receiveGuard; #endif RCSwitch::RCSwitch() { @@ -601,6 +605,22 @@ static inline unsigned int diff(int A, int B) { return abs(A - B); } +#if defined(WITH_LOCKS) +void RCSwitch::enableLocks() { + this->useLocks = true; +} +void RCSwitch::wait() { + assert(useLocks); + if (!useLocks) { + return; + } + while (!available()) { + std::unique_lock lock(this->mutex); + receiveGuard.wait(lock); + } +} +#endif + /** * */ @@ -653,10 +673,22 @@ bool RECEIVE_ATTR RCSwitch::receiveProtocol(const int p, unsigned int changeCoun } if (changeCount > 7) { // ignore very short transmissions: no device sends them, so this must be noise + #if defined(WITH_LOCKS) + std::unique_lock lock(mutex, std::defer_lock); + if (useLocks) { + lock.lock(); + } + #endif + // The following code is lock-guarded when using locks. RCSwitch::nReceivedValue = code; RCSwitch::nReceivedBitlength = (changeCount - 1) / 2; RCSwitch::nReceivedDelay = delay; RCSwitch::nReceivedProtocol = p; + #if defined(WITH_LOCKS) + if (useLocks) { + receiveGuard.notify_all(); + } + #endif return true; } diff --git a/RCSwitch.h b/RCSwitch.h index b7755e0..deec010 100644 --- a/RCSwitch.h +++ b/RCSwitch.h @@ -47,6 +47,11 @@ #include "WProgram.h" #endif +#if defined(WITH_LOCKS) + #include + #include +#endif + #include @@ -148,6 +153,14 @@ class RCSwitch { void setProtocol(int nProtocol); void setProtocol(int nProtocol, int nPulseLength); + #if defined(WITH_LOCKS) + // Enabled the handling of locks. + // If enabled, the caller can use the wait() function to wait for data. + void enableLocks(); + void wait(); + #endif + + private: char* getCodeWordA(const char* sGroup, const char* sDevice, bool bStatus); char* getCodeWordB(int nGroupNumber, int nSwitchNumber, bool bStatus); @@ -160,6 +173,13 @@ class RCSwitch { static bool receiveProtocol(const int p, unsigned int changeCount); int nReceiverInterrupt; #endif + + #if defined(WITH_LOCKS) + static std::mutex mutex; + static std::condition_variable receiveGuard; + static volatile bool useLocks; + #endif + int nTransmitterPin; int nRepeatTransmit; From 6b6ff04d871a0c032ec7c9576af0e19e9e08356d Mon Sep 17 00:00:00 2001 From: gurux13 Date: Sat, 11 Apr 2020 10:32:33 +0100 Subject: [PATCH 2/3] Fix build for Arduino and add an error when locks are used outside Raspberry Pi. --- RCSwitch.cpp | 2 +- RCSwitch.h | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/RCSwitch.cpp b/RCSwitch.cpp index 9f535bd..a67b743 100644 --- a/RCSwitch.cpp +++ b/RCSwitch.cpp @@ -33,7 +33,7 @@ */ #include "RCSwitch.h" -#include +#include #ifdef RaspberryPi // PROGMEM and _P functions are for AVR based microprocessors, diff --git a/RCSwitch.h b/RCSwitch.h index deec010..9a346d0 100644 --- a/RCSwitch.h +++ b/RCSwitch.h @@ -47,6 +47,10 @@ #include "WProgram.h" #endif +#if defined(WITH_LOCKS) && !defined(RaspberryPi) + #error "Locks are not supported outside Raspberry Pi!" +#endif + #if defined(WITH_LOCKS) #include #include From 0b87ed045ccc2a93d46d8329a399b5013d815f95 Mon Sep 17 00:00:00 2001 From: gurux13 Date: Sat, 11 Apr 2020 10:35:55 +0100 Subject: [PATCH 3/3] Move statics under conditional compilation. --- RCSwitch.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/RCSwitch.cpp b/RCSwitch.cpp index a67b743..26f56ac 100644 --- a/RCSwitch.cpp +++ b/RCSwitch.cpp @@ -104,10 +104,13 @@ const unsigned int RCSwitch::nSeparationLimit = 4300; // according to discussion on issue #14 it might be more suitable to set the separation // limit to the same time as the 'low' part of the sync signal for the current protocol. unsigned int RCSwitch::timings[RCSWITCH_MAX_CHANGES]; +#if defined(WITH_LOCKS) volatile bool RCSwitch::useLocks = false; std::mutex RCSwitch::mutex; std::condition_variable RCSwitch::receiveGuard; -#endif +#endif // WITH_LOCKS + +#endif // !RCSwitchDisableReceiving RCSwitch::RCSwitch() { this->nTransmitterPin = -1;