mirror of
https://github.com/esphome/esphome.git
synced 2026-05-24 09:56:46 +08:00
[usb_cdc_acm] Fix EventPool/LockFreeQueue sizing off-by-one (#14894)
This commit is contained in:
@@ -26,16 +26,13 @@ void USBCDCACMInstance::queue_line_state_event(bool dtr, bool rts) {
|
||||
event->data.line_state.dtr = dtr;
|
||||
event->data.line_state.rts = rts;
|
||||
|
||||
if (!this->event_queue_.push(event)) {
|
||||
ESP_LOGW(TAG, "Event queue full, line state event dropped (itf=%d)", this->itf_);
|
||||
// Return event to pool since we couldn't queue it
|
||||
this->event_pool_.release(event);
|
||||
} else {
|
||||
// Wake main loop immediately to process event
|
||||
// Push always succeeds: pool is sized to queue capacity (SIZE-1), so if
|
||||
// allocate() returned non-null, the queue cannot be full.
|
||||
this->event_queue_.push(event);
|
||||
|
||||
#if defined(USE_SOCKET_SELECT_SUPPORT) && defined(USE_WAKE_LOOP_THREADSAFE)
|
||||
App.wake_loop_threadsafe();
|
||||
App.wake_loop_threadsafe();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void USBCDCACMInstance::queue_line_coding_event(uint32_t bit_rate, uint8_t stop_bits, uint8_t parity,
|
||||
@@ -53,16 +50,13 @@ void USBCDCACMInstance::queue_line_coding_event(uint32_t bit_rate, uint8_t stop_
|
||||
event->data.line_coding.parity = parity;
|
||||
event->data.line_coding.data_bits = data_bits;
|
||||
|
||||
if (!this->event_queue_.push(event)) {
|
||||
ESP_LOGW(TAG, "Event queue full, line coding event dropped (itf=%d)", this->itf_);
|
||||
// Return event to pool since we couldn't queue it
|
||||
this->event_pool_.release(event);
|
||||
} else {
|
||||
// Wake main loop immediately to process event
|
||||
// Push always succeeds: pool is sized to queue capacity (SIZE-1), so if
|
||||
// allocate() returned non-null, the queue cannot be full.
|
||||
this->event_queue_.push(event);
|
||||
|
||||
#if defined(USE_SOCKET_SELECT_SUPPORT) && defined(USE_WAKE_LOOP_THREADSAFE)
|
||||
App.wake_loop_threadsafe();
|
||||
App.wake_loop_threadsafe();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void USBCDCACMInstance::process_events_() {
|
||||
|
||||
@@ -102,7 +102,11 @@ class USBCDCACMInstance : public uart::UARTComponent, public Parented<USBCDCACMC
|
||||
LineStateCallback line_state_callback_{nullptr};
|
||||
|
||||
// Lock-free queue and event pool for cross-task event passing
|
||||
EventPool<CDCEvent, EVENT_QUEUE_SIZE> event_pool_;
|
||||
// Pool sized to queue capacity (SIZE-1) because LockFreeQueue<T,N> is a ring
|
||||
// buffer that holds N-1 elements. This guarantees allocate() returns nullptr
|
||||
// before push() can fail, preventing both a pool slot leak and an SPSC
|
||||
// violation on the pool's internal free list.
|
||||
EventPool<CDCEvent, EVENT_QUEUE_SIZE - 1> event_pool_;
|
||||
LockFreeQueue<CDCEvent, EVENT_QUEUE_SIZE> event_queue_;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user