Skip to content

Commit

Permalink
serveJson: Ensure semaphore scope lasts until reply is done
Browse files Browse the repository at this point in the history
Extend the JSON response class to hold the global JSON buffer lock
until the transaction is completed.

Fixes Aircoookie#3641
  • Loading branch information
willmmiles committed Jan 6, 2024
1 parent 6382d2b commit 9d3c0f4
Showing 1 changed file with 13 additions and 3 deletions.
16 changes: 13 additions & 3 deletions wled00/json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1009,6 +1009,17 @@ void serializeModeNames(JsonArray arr)
}
}


// Global buffer locking response helper class
class GlobalBufferAsyncJsonResponse: public JSONBufferGuard, public AsyncJsonResponse {
public:
inline GlobalBufferAsyncJsonResponse(bool isArray) : JSONBufferGuard(17), AsyncJsonResponse(pDoc, isArray) {};
virtual ~GlobalBufferAsyncJsonResponse() {};

// Other members are inherited
};


static volatile bool servingClient = false;
void serveJson(AsyncWebServerRequest* request)
{
Expand Down Expand Up @@ -1050,12 +1061,12 @@ void serveJson(AsyncWebServerRequest* request)
return;
}

if (!requestJSONBufferLock(17)) {
GlobalBufferAsyncJsonResponse *response = new GlobalBufferAsyncJsonResponse(subJson==JSON_PATH_FXDATA || subJson==JSON_PATH_EFFECTS); // will clear and convert JsonDocument into JsonArray if necessary
if (!response->owns_lock()) {
serveJsonError(request, 503, ERR_NOBUF);
servingClient = false;
return;
}
AsyncJsonResponse *response = new AsyncJsonResponse(pDoc, subJson==JSON_PATH_FXDATA || subJson==JSON_PATH_EFFECTS); // will clear and convert JsonDocument into JsonArray if necessary

JsonVariant lDoc = response->getRoot();

Expand Down Expand Up @@ -1098,7 +1109,6 @@ void serveJson(AsyncWebServerRequest* request)
DEBUG_PRINT(F("JSON content length: ")); DEBUG_PRINTLN(len);

request->send(response);
releaseJSONBufferLock();
servingClient = false;
}

Expand Down

0 comments on commit 9d3c0f4

Please sign in to comment.