[usb_host] Implement disable_loop/enable_loop pattern for USB components (#14163)

This commit is contained in:
J. Nick Koston
2026-02-20 19:21:14 -06:00
committed by GitHub
parent 35037d1a5b
commit a3f279c1cf
3 changed files with 38 additions and 11 deletions
+10 -1
View File
@@ -172,11 +172,12 @@ bool USBUartChannel::read_array(uint8_t *data, size_t len) {
}
void USBUartComponent::setup() { USBClient::setup(); }
void USBUartComponent::loop() {
USBClient::loop();
bool had_work = this->process_usb_events_();
// Process USB data from the lock-free queue
UsbDataChunk *chunk;
while ((chunk = this->usb_data_queue_.pop()) != nullptr) {
had_work = true;
auto *channel = chunk->channel;
#ifdef USE_UART_DEBUGGER
@@ -198,6 +199,11 @@ void USBUartComponent::loop() {
if (dropped > 0) {
ESP_LOGW(TAG, "Dropped %u USB data chunks due to buffer overflow", dropped);
}
// Disable loop when idle. Callbacks re-enable via enable_loop_soon_any_context().
if (!had_work) {
this->disable_loop();
}
}
void USBUartComponent::dump_config() {
USBClient::dump_config();
@@ -264,6 +270,9 @@ void USBUartComponent::start_input(USBUartChannel *channel) {
// Push always succeeds because pool size == queue size
this->usb_data_queue_.push(chunk);
// Re-enable component loop to process the queued data
this->enable_loop_soon_any_context();
// Wake main loop immediately to process USB data instead of waiting for select() timeout
#if defined(USE_SOCKET_SELECT_SUPPORT) && defined(USE_WAKE_LOOP_THREADSAFE)
App.wake_loop_threadsafe();