Merge branch 'bugfix/ws_stop_deadlock_v4.1' into 'release/v4.1'

Websocket client: avoid deadlock if stop called from event handler (Backport 4.1)

See merge request espressif/esp-idf!10227
This commit is contained in:
David Čermák 2020-09-07 14:58:25 +08:00
commit 217e95d4db
2 changed files with 18 additions and 2 deletions

View File

@ -77,6 +77,7 @@ typedef enum {
struct esp_websocket_client {
esp_event_loop_handle_t event_handle;
TaskHandle_t task_handle;
esp_transport_list_handle_t transport_list;
esp_transport_handle_t transport;
websocket_config_storage_t *config;
@ -584,7 +585,7 @@ esp_err_t esp_websocket_client_start(esp_websocket_client_handle_t client)
ESP_LOGE(TAG, "The client has started");
return ESP_FAIL;
}
if (xTaskCreate(esp_websocket_client_task, "websocket_task", client->config->task_stack, client, client->config->task_prio, NULL) != pdTRUE) {
if (xTaskCreate(esp_websocket_client_task, "websocket_task", client->config->task_stack, client, client->config->task_prio, &client->task_handle) != pdTRUE) {
ESP_LOGE(TAG, "Error create websocket task");
return ESP_FAIL;
}
@ -601,6 +602,15 @@ esp_err_t esp_websocket_client_stop(esp_websocket_client_handle_t client)
ESP_LOGW(TAG, "Client was not started");
return ESP_FAIL;
}
/* A running client cannot be stopped from the websocket task/event handler */
TaskHandle_t running_task = xTaskGetCurrentTaskHandle();
if (running_task == client->task_handle) {
ESP_LOGE(TAG, "Client cannot be stopped from websocket task");
return ESP_FAIL;
}
client->run = false;
xEventGroupWaitBits(client->status_bits, STOPPED_BIT, false, true, portMAX_DELAY);
client->state = WEBSOCKET_STATE_UNKNOW;

View File

@ -124,6 +124,9 @@ esp_err_t esp_websocket_client_start(esp_websocket_client_handle_t client);
/**
* @brief Close the WebSocket connection
*
* Notes:
* - Cannot be called from the websocket event handler
*
* @param[in] client The client
*
* @return esp_err_t
@ -135,7 +138,10 @@ esp_err_t esp_websocket_client_stop(esp_websocket_client_handle_t client);
* This function must be the last function to call for an session.
* It is the opposite of the esp_websocket_client_init function and must be called with the same handle as input that a esp_websocket_client_init call returned.
* This might close all connections this handle has used.
*
*
* Notes:
* - Cannot be called from the websocket event handler
*
* @param[in] client The client
*
* @return esp_err_t