fix(esp_netif): Avoid socket to stay in closing state in l2tap closing

This commit is contained in:
Euripedes Rocha Filho
2026-07-14 11:00:36 +02:00
committed by Euripedes Rocha
parent 5a4288e8ff
commit f5607d1737

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -314,14 +314,16 @@ static int l2tap_close(int fd)
if ((s_l2tap_sockets[fd].close_done_sem = xSemaphoreCreateBinary()) == NULL) {
ESP_LOGE(TAG, "create close_done_sem failed");
return -1;
goto close_failed;
}
// If one task is blocked in I/O operation and another task tries to close the fd, the first task is
// unblocked by pushing empty queue in low priority task (to ensure context switch to the first task).
// The first's task read operation then ends with error and the low priority task frees the queue resources.
if (xTaskCreate(l2tap_clean_task, "l2tap_clean_task", 1024, &s_l2tap_sockets[fd], tskIDLE_PRIORITY, NULL) == pdFAIL) {
ESP_LOGE(TAG, "create l2tap_clean_task failed");
return -1;
vSemaphoreDelete(s_l2tap_sockets[fd].close_done_sem);
s_l2tap_sockets[fd].close_done_sem = NULL;
goto close_failed;
}
// wait for the low priority close task & then delete the semaphore
@@ -331,6 +333,14 @@ static int l2tap_close(int fd)
// indicate that socket is ready to be used again
atomic_store(&s_l2tap_sockets[fd].state, L2TAP_SOCK_STATE_READY);
return 0;
close_failed:
flush_rx_queue(&s_l2tap_sockets[fd]);
(void)push_rx_queue(&s_l2tap_sockets[fd], NULL, 0);
delete_rx_queue(&s_l2tap_sockets[fd]);
atomic_store(&s_l2tap_sockets[fd].state, L2TAP_SOCK_STATE_READY);
errno = ENOMEM;
return -1;
}
// used to find a netif with the attached driver matching the argument