diff --git a/src/platforms/esp32/components/avm_builtins/network_driver.c b/src/platforms/esp32/components/avm_builtins/network_driver.c index 5c2b5fb6e5..727354bc5e 100644 --- a/src/platforms/esp32/components/avm_builtins/network_driver.c +++ b/src/platforms/esp32/components/avm_builtins/network_driver.c @@ -66,6 +66,7 @@ #include #include #include +#include #define HAVE_PPP 1 #endif #pragma GCC diagnostic pop @@ -1791,6 +1792,11 @@ static bool start_ppp(Context *ctx, term pid, term ref, struct ClientData *data, return false; } +static void ppp_rx_drained(void *arg) +{ + xSemaphoreGive((SemaphoreHandle_t) arg); +} + // Frees what start_ppp set up, once the session is dead (or never started): lwIP keeps timers // on a session until its dead phase, and the netif and its PPP control block must outlive them. static void free_ppp(struct PPPGlue *glue) @@ -1803,6 +1809,15 @@ static void free_ppp(struct PPPGlue *glue) ESP_LOGI(TAG, "PPP closed: %u bytes in, %u bytes out", (unsigned) glue->rx_bytes, (unsigned) glue->tx_bytes); glue->stop = true; xSemaphoreTake(glue->stopped, portMAX_DELAY); + // The RX task has stopped, but input it queued for the TCP/IP task still points at the + // netif. With core locking, esp_netif_destroy runs at once instead of behind that input, + // so a callback through the mailbox, which is FIFO, waits it out. Not + // esp_netif_tcpip_exec or tcpip_callback_wait: under core locking both run inline. + if (tcpip_callback(ppp_rx_drained, glue->stopped) != ERR_OK) { + ESP_LOGE(TAG, "Failed to drain PPP input, left allocated"); + return; + } + xSemaphoreTake(glue->stopped, portMAX_DELAY); } if (glue->stopped != NULL) { vSemaphoreDelete(glue->stopped); @@ -1828,7 +1843,7 @@ static void ppp_teardown_task(void *args) struct PPPGlue *glue = args; if (xSemaphoreTake(glue->died, pdMS_TO_TICKS(PPP_TEARDOWN_MS)) == pdTRUE) { free_ppp(glue); - ESP_LOGI(TAG, "PPP closed late, freed"); + ESP_LOGI(TAG, "PPP late close teardown finished"); } else { ESP_LOGE(TAG, "PPP did not close in %d ms, left allocated", PPP_TEARDOWN_MS); }