use a mutex to make requestJSONBufferLock / releaseJSONBufferLock robust
similar to upstream https://github.com/wled/WLED/pull/4089, but with slightly different "failure" logic.
This commit is contained in:
@@ -222,17 +222,31 @@ bool isAsterisksOnly(const char* str, byte maxLen)
|
|||||||
//threading/network callback details: https://github.com/Aircoookie/WLED/pull/2336#discussion_r762276994
|
//threading/network callback details: https://github.com/Aircoookie/WLED/pull/2336#discussion_r762276994
|
||||||
bool requestJSONBufferLock(uint8_t module)
|
bool requestJSONBufferLock(uint8_t module)
|
||||||
{
|
{
|
||||||
unsigned long now = millis();
|
bool haveLock = false;
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
// We use a recursive mutex to prevent parallel JSON writes from parallel tasks.
|
||||||
|
// This also fixes hanging up for the full timeout interval in cases when the contention is from the same task.
|
||||||
|
// see https://github.com/wled/WLED/pull/4089 for more details.
|
||||||
|
if (esp32SemTake(jsonBufferLockMutex, 1800) == pdTRUE) haveLock = true; // WLEDMM must wait longer than suspendStripService timeout = 1500ms
|
||||||
|
#else
|
||||||
|
// 8266: only wait in case that can_yield() tells us we can yield and delay
|
||||||
|
if (can_yield()) {
|
||||||
|
unsigned long now = millis();
|
||||||
|
while (jsonBufferLock && millis()-now < 1800) delay(1); // wait for fraction for buffer lock // WLEDMM must wait longer than suspendStripService timeout = 1500ms
|
||||||
|
if (!jsonBufferLock) haveLock = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
while (jsonBufferLock && millis()-now < 1100) delay(1); // wait for fraction for buffer lock
|
if (jsonBufferLock || !haveLock) {
|
||||||
|
if (haveLock) esp32SemGive(jsonBufferLockMutex); // we got the mutex, but jsonBufferLock says the opposite -> give up
|
||||||
if (jsonBufferLock) {
|
delay(10); // WLEDMM experimental: small extra wait, in case that esp32 cores temporarily disagree on the value of jsonBufferLock
|
||||||
USER_PRINT(F("ERROR: Locking JSON buffer failed! (still locked by "));
|
USER_PRINT(F("ERROR: Locking JSON buffer failed! (still locked by "));
|
||||||
USER_PRINT(jsonBufferLock);
|
USER_PRINT(jsonBufferLock);
|
||||||
USER_PRINTLN(")");
|
USER_PRINTLN(")");
|
||||||
return false; // waiting time-outed
|
return false; // waiting time-outed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// success - we keep holding the mutex until releaseJSONBufferLock()
|
||||||
jsonBufferLock = module ? module : 255;
|
jsonBufferLock = module ? module : 255;
|
||||||
DEBUG_PRINT(F("JSON buffer locked. ("));
|
DEBUG_PRINT(F("JSON buffer locked. ("));
|
||||||
DEBUG_PRINT(jsonBufferLock);
|
DEBUG_PRINT(jsonBufferLock);
|
||||||
@@ -250,6 +264,7 @@ void releaseJSONBufferLock()
|
|||||||
DEBUG_PRINTLN(")");
|
DEBUG_PRINTLN(")");
|
||||||
fileDoc = nullptr;
|
fileDoc = nullptr;
|
||||||
jsonBufferLock = 0;
|
jsonBufferLock = 0;
|
||||||
|
esp32SemGive(jsonBufferLockMutex); // return the mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user