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
|
||||
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) {
|
||||
if (jsonBufferLock || !haveLock) {
|
||||
if (haveLock) esp32SemGive(jsonBufferLockMutex); // we got the mutex, but jsonBufferLock says the opposite -> give up
|
||||
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(jsonBufferLock);
|
||||
USER_PRINTLN(")");
|
||||
return false; // waiting time-outed
|
||||
}
|
||||
|
||||
// success - we keep holding the mutex until releaseJSONBufferLock()
|
||||
jsonBufferLock = module ? module : 255;
|
||||
DEBUG_PRINT(F("JSON buffer locked. ("));
|
||||
DEBUG_PRINT(jsonBufferLock);
|
||||
@@ -250,6 +264,7 @@ void releaseJSONBufferLock()
|
||||
DEBUG_PRINTLN(")");
|
||||
fileDoc = nullptr;
|
||||
jsonBufferLock = 0;
|
||||
esp32SemGive(jsonBufferLockMutex); // return the mutex
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user