mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Websocket client: avoid deadlock if stop called from event handler
This commit is contained in:
parent
7e2511f8a8
commit
c2bb0762bb
@ -87,6 +87,7 @@ typedef enum {
|
|||||||
|
|
||||||
struct esp_websocket_client {
|
struct esp_websocket_client {
|
||||||
esp_event_loop_handle_t event_handle;
|
esp_event_loop_handle_t event_handle;
|
||||||
|
TaskHandle_t task_handle;
|
||||||
esp_transport_list_handle_t transport_list;
|
esp_transport_list_handle_t transport_list;
|
||||||
esp_transport_handle_t transport;
|
esp_transport_handle_t transport;
|
||||||
websocket_config_storage_t *config;
|
websocket_config_storage_t *config;
|
||||||
@ -660,7 +661,7 @@ esp_err_t esp_websocket_client_start(esp_websocket_client_handle_t client)
|
|||||||
ESP_LOGE(TAG, "The client has started");
|
ESP_LOGE(TAG, "The client has started");
|
||||||
return ESP_FAIL;
|
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");
|
ESP_LOGE(TAG, "Error create websocket task");
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
@ -677,6 +678,15 @@ esp_err_t esp_websocket_client_stop(esp_websocket_client_handle_t client)
|
|||||||
ESP_LOGW(TAG, "Client was not started");
|
ESP_LOGW(TAG, "Client was not started");
|
||||||
return ESP_FAIL;
|
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;
|
client->run = false;
|
||||||
xEventGroupWaitBits(client->status_bits, STOPPED_BIT, false, true, portMAX_DELAY);
|
xEventGroupWaitBits(client->status_bits, STOPPED_BIT, false, true, portMAX_DELAY);
|
||||||
client->state = WEBSOCKET_STATE_UNKNOW;
|
client->state = WEBSOCKET_STATE_UNKNOW;
|
||||||
@ -711,6 +721,13 @@ static esp_err_t esp_websocket_client_close_with_optional_body(esp_websocket_cli
|
|||||||
return ESP_FAIL;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
if (send_body) {
|
if (send_body) {
|
||||||
esp_websocket_client_send_close(client, code, data, len + 2, portMAX_DELAY); // len + 2 -> always sending the code
|
esp_websocket_client_send_close(client, code, data, len + 2, portMAX_DELAY); // len + 2 -> always sending the code
|
||||||
} else {
|
} else {
|
||||||
|
@ -132,6 +132,9 @@ esp_err_t esp_websocket_client_start(esp_websocket_client_handle_t client);
|
|||||||
* close frames. It is a good practice to close the connection in a clean way
|
* close frames. It is a good practice to close the connection in a clean way
|
||||||
* using esp_websocket_client_close().
|
* using esp_websocket_client_close().
|
||||||
*
|
*
|
||||||
|
* Notes:
|
||||||
|
* - Cannot be called from the websocket event handler
|
||||||
|
*
|
||||||
* @param[in] client The client
|
* @param[in] client The client
|
||||||
*
|
*
|
||||||
* @return esp_err_t
|
* @return esp_err_t
|
||||||
@ -144,6 +147,9 @@ esp_err_t esp_websocket_client_stop(esp_websocket_client_handle_t client);
|
|||||||
* 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.
|
* 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.
|
* This might close all connections this handle has used.
|
||||||
*
|
*
|
||||||
|
* Notes:
|
||||||
|
* - Cannot be called from the websocket event handler
|
||||||
|
*
|
||||||
* @param[in] client The client
|
* @param[in] client The client
|
||||||
*
|
*
|
||||||
* @return esp_err_t
|
* @return esp_err_t
|
||||||
@ -201,6 +207,9 @@ int esp_websocket_client_send_text(esp_websocket_client_handle_t client, const c
|
|||||||
* * Client waits until server closes the connection
|
* * Client waits until server closes the connection
|
||||||
* * Client is stopped the same way as by the `esp_websocket_client_stop()`
|
* * Client is stopped the same way as by the `esp_websocket_client_stop()`
|
||||||
*
|
*
|
||||||
|
* Notes:
|
||||||
|
* - Cannot be called from the websocket event handler
|
||||||
|
*
|
||||||
* @param[in] client The client
|
* @param[in] client The client
|
||||||
* @param[in] timeout Timeout in RTOS ticks for waiting
|
* @param[in] timeout Timeout in RTOS ticks for waiting
|
||||||
*
|
*
|
||||||
@ -212,6 +221,9 @@ esp_err_t esp_websocket_client_close(esp_websocket_client_handle_t client, TickT
|
|||||||
* @brief Close the WebSocket connection in a clean way with custom code/data
|
* @brief Close the WebSocket connection in a clean way with custom code/data
|
||||||
* Closing sequence is the same as for esp_websocket_client_close()
|
* Closing sequence is the same as for esp_websocket_client_close()
|
||||||
*
|
*
|
||||||
|
* Notes:
|
||||||
|
* - Cannot be called from the websocket event handler
|
||||||
|
*
|
||||||
* @param[in] client The client
|
* @param[in] client The client
|
||||||
* @param[in] code Close status code as defined in RFC6455 section-7.4
|
* @param[in] code Close status code as defined in RFC6455 section-7.4
|
||||||
* @param[in] data Additional data to closing message
|
* @param[in] data Additional data to closing message
|
||||||
|
Loading…
x
Reference in New Issue
Block a user