From 24eabbf345e1784c890c381a9dd24d2d592ff9f6 Mon Sep 17 00:00:00 2001 From: Richard Allen Date: Mon, 2 Dec 2024 14:35:20 -0600 Subject: [PATCH] fix(websocket): release client-lock during WEBSOCKET_EVENT_DATA This resolves: 1) Deadlock when trying to reserve a lock in WEBSOCKET_EVENT_DATA, but lock is held by a thread trying to send a websocket message. 2) High latency caused by writers serialized with WEBSOCKET_EVENT_DATA while calling esp_websocket_client_send(), even when TCP window has enough space for the entire message being queued to send. Multiple writers are still serialized at fragment boundaries, but only with other writers and websocket error updates. Fixes #625 --- .../esp_websocket_client/esp_websocket_client.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/components/esp_websocket_client/esp_websocket_client.c b/components/esp_websocket_client/esp_websocket_client.c index f943a86895..2e937f5d2a 100644 --- a/components/esp_websocket_client/esp_websocket_client.c +++ b/components/esp_websocket_client/esp_websocket_client.c @@ -1044,12 +1044,6 @@ static void esp_websocket_client_task(void *pv) break; } client->ping_tick_ms = _tick_get_ms(); - - if (esp_websocket_client_recv(client) == ESP_FAIL) { - ESP_LOGE(TAG, "Error receive data"); - esp_websocket_client_abort_connection(client, WEBSOCKET_ERROR_TYPE_TCP_TRANSPORT); - break; - } break; case WEBSOCKET_STATE_WAIT_TIMEOUT: @@ -1086,6 +1080,14 @@ static void esp_websocket_client_task(void *pv) xSemaphoreTakeRecursive(client->lock, lock_timeout); esp_websocket_client_abort_connection(client, WEBSOCKET_ERROR_TYPE_TCP_TRANSPORT); xSemaphoreGiveRecursive(client->lock); + } else if (read_select > 0) { + if (esp_websocket_client_recv(client) == ESP_FAIL) { + ESP_LOGE(TAG, "Error receive data"); + xSemaphoreTakeRecursive(client->lock, lock_timeout); + esp_websocket_client_abort_connection(client, WEBSOCKET_ERROR_TYPE_TCP_TRANSPORT); + xSemaphoreGiveRecursive(client->lock); + break; + } } } else if (WEBSOCKET_STATE_WAIT_TIMEOUT == client->state) { // waiting for reconnecting...