From d5ad9dc0fb41beed00580ae6c02d0510d2bb8f9c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 23 Sep 2025 21:58:01 -0500 Subject: [PATCH] fix --- .../components/usb_host/usb_host_client.cpp | 19 ++++++++++--------- esphome/components/usb_uart/usb_uart.cpp | 5 ++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/esphome/components/usb_host/usb_host_client.cpp b/esphome/components/usb_host/usb_host_client.cpp index d294520568..1abc260bbf 100644 --- a/esphome/components/usb_host/usb_host_client.cpp +++ b/esphome/components/usb_host/usb_host_client.cpp @@ -307,6 +307,14 @@ void USBClient::on_removed(usb_device_handle_t handle) { } } +// Helper to queue transfer cleanup to main loop +static void queue_transfer_cleanup(TransferRequest *trq, EventType type) { + UsbEvent event; + event.type = type; + event.data.transfer.trq = trq; + xQueueSend(trq->client->get_event_queue(), &event, portMAX_DELAY); +} + // CALLBACK CONTEXT: USB task (called from usb_host_client_handle_events in USB task) static void control_callback(const usb_transfer_t *xfer) { auto *trq = static_cast(xfer->context); @@ -322,10 +330,7 @@ static void control_callback(const usb_transfer_t *xfer) { } // Queue cleanup to main loop - UsbEvent event; - event.type = EVENT_CONTROL_COMPLETE; - event.data.transfer.trq = trq; - xQueueSend(trq->client->get_event_queue(), &event, portMAX_DELAY); + queue_transfer_cleanup(trq, EVENT_CONTROL_COMPLETE); } TransferRequest *USBClient::get_trq_() { @@ -402,11 +407,7 @@ static void transfer_callback(usb_transfer_t *xfer) { } // Queue cleanup to main loop - UsbEvent event; - event.type = EVENT_TRANSFER_COMPLETE; - event.data.transfer.trq = trq; - event.data.transfer.callback_executed = true; - xQueueSend(trq->client->get_event_queue(), &event, portMAX_DELAY); + queue_transfer_cleanup(trq, EVENT_TRANSFER_COMPLETE); } /** * Performs a transfer input operation. diff --git a/esphome/components/usb_uart/usb_uart.cpp b/esphome/components/usb_uart/usb_uart.cpp index b485397214..5aa9f65f12 100644 --- a/esphome/components/usb_uart/usb_uart.cpp +++ b/esphome/components/usb_uart/usb_uart.cpp @@ -266,12 +266,11 @@ void USBUartComponent::start_output(USBUartChannel *channel) { return; } const auto *ep = channel->cdc_dev_.out_ep; - // CALLBACK CONTEXT: This lambda is stored in TransferRequest and will be executed - // in MAIN LOOP after being queued by transfer_callback in USB task + // CALLBACK CONTEXT: This lambda is executed in USB task via transfer_callback auto callback = [this, channel](const usb_host::TransferStatus &status) { ESP_LOGV(TAG, "Output Transfer result: length: %u; status %X", status.data_len, status.error_code); channel->output_started_ = false; - // DEFERRED CONTEXT: Main loop (restart output in main loop) + // Defer restart to main loop (defer is thread-safe) this->defer([this, channel] { this->start_output(channel); }); }; channel->output_started_ = true;