@@ -38,7 +38,14 @@ static void doSaveState() {
3838 bool persist = (presetToSave < 251 );
3939 const char *filename = getFileName (persist);
4040
41- if (!requestJSONBufferLock (10 )) return ; // will set fileDoc
41+ if (!requestJSONBufferLock (10 )) return ; // will set fileDoc // async write
42+
43+ // WLEDMM Acquire file mutex before writing presets.json or tmp.json
44+ if (esp32SemTake (presetFileMux, 2500 ) != pdTRUE) {
45+ USER_PRINTLN (F (" doSaveState(): preset file busy, cannot write" ));
46+ releaseJSONBufferLock ();
47+ return ;
48+ }
4249
4350 initPresetsFile (); // just in case if someone deleted presets.json using /edit
4451 JsonObject sObj = doc.to <JsonObject>();
@@ -82,6 +89,8 @@ static void doSaveState() {
8289 writeObjectToFileUsingId (filename, presetToSave, fileDoc);
8390
8491 if (persist) presetsModifiedTime = toki.second (); // unix time
92+
93+ esp32SemGive (presetFileMux); // Release file mutex
8594 releaseJSONBufferLock ();
8695 updateFSInfo ();
8796
@@ -316,7 +325,14 @@ void savePreset(byte index, const char* pname, JsonObject sObj)
316325 } else {
317326 // this is a playlist or API call
318327 if (sObj [F (" playlist" )].isNull ()) {
319- // we will save API call immediately (often causes presets.json corruption)
328+ // we will save API call immediately (often causes presets.json corruption in the past)
329+
330+ // WLEDMM Acquire file mutex before writing presets.json, to prevent presets.json corruption
331+ if (esp32SemTake (presetFileMux, 2500 ) != pdTRUE) {
332+ USER_PRINTLN (F (" doSaveState(): preset file busy, cannot write" ));
333+ return ; // early exit, no change
334+ }
335+
320336 presetToSave = 0 ;
321337 if (index > 250 || !fileDoc) return ; // cannot save API calls to temporary preset (255)
322338 sObj .remove (" o" );
@@ -325,8 +341,11 @@ void savePreset(byte index, const char* pname, JsonObject sObj)
325341 sObj .remove (F (" error" ));
326342 sObj .remove (F (" psave" ));
327343 if (sObj [" n" ].isNull ()) sObj [" n" ] = saveName;
344+
328345 initPresetsFile (); // just in case if someone deleted presets.json using /edit
329346 writeObjectToFileUsingId (getFileName (index<255 ), index, fileDoc);
347+
348+ esp32SemGive (presetFileMux); // Release file mutex
330349 presetsModifiedTime = toki.second (); // unix time
331350 updateFSInfo ();
332351 } else {
0 commit comments