From c185f3779180e7e288b859ecef6153b3a268446f Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Tue, 23 Dec 2025 00:33:28 +0100 Subject: [PATCH] improved mutex error handling - debug message in case of "unexpected" mutex errors - removed experimental delay() in requestJSONBufferLock --- wled00/json.cpp | 8 +++++++- wled00/util.cpp | 1 - wled00/wled.cpp | 2 ++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/wled00/json.cpp b/wled00/json.cpp index 025c70db..96a84d4a 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -100,6 +100,9 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId) id = strip.getSegmentsNum()-1; // segments are added at the end of list newSeg = true; esp32SemGive(segmentMux); + } else { + USER_PRINTLN(F("deserializeSegment(): segment not added - failed to acquire segmentMux.")); + return false; } } @@ -358,6 +361,7 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId) strip.waitUntilIdle(); } // WLEDMM protect against parallel drawing + bool drawSuccess = false; if (esp32SemTake(busDrawMux, 250) == pdTRUE) { // WLEDMM first acquire draw mutex, start of critical section seg.startFrame(); @@ -409,11 +413,13 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId) set = 0; } } + drawSuccess = true; esp32SemGive(busDrawMux); // release lock } // end of critical section seg.map1D2D = oldMap1D2D; // restore mapping - strip.trigger(); // force segment update + if (drawSuccess) strip.trigger(); // force segment update + else USER_PRINTLN(F("deserializeSegment() image drawing failed, cannot not to acquire busDrawMux.")); // log failure messaage suspendStripService = oldLock; // restore previous lock status } // send UDP/WS if segment options changed (except selection; will also deselect current preset) diff --git a/wled00/util.cpp b/wled00/util.cpp index d9862bc7..be93ef1d 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -239,7 +239,6 @@ bool requestJSONBufferLock(uint8_t module) 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(")"); diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 02287064..789f7ce3 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -480,6 +480,8 @@ void WLED::setup() busDrawMux = xSemaphoreCreateRecursiveMutex(); // WLEDMM prevent concurrent running of strip.show and strip.service segmentMux = xSemaphoreCreateRecursiveMutex(); // WLEDMM prevent segment changes while effects are running jsonBufferLockMutex = xSemaphoreCreateRecursiveMutex(); // WLEDMM prevent concurrent JSON buffer writing + if ((busDrawMux == nullptr) || (segmentMux == nullptr) || (jsonBufferLockMutex == nullptr)) + USER_PRINTLN(F("setup error: xSemaphoreCreateRecursiveMutex failed.")); // should never happen. xSemaphoreGiveRecursive(busDrawMux); // init semaphores to initially allow drawing xSemaphoreGiveRecursive(segmentMux); xSemaphoreGiveRecursive(jsonBufferLockMutex);