diff --git a/esp-wifi/src/wifi/mod.rs b/esp-wifi/src/wifi/mod.rs index 58f4c90c..15f20672 100644 --- a/esp-wifi/src/wifi/mod.rs +++ b/esp-wifi/src/wifi/mod.rs @@ -645,23 +645,27 @@ unsafe extern "C" fn recv_cb( len: u16, eb: *mut c_types::c_void, ) -> esp_err_t { - critical_section::with(|cs| { + let result = critical_section::with(|cs| { let packet = EspWifiPacketBuffer { buffer, len, eb }; - match DATA_QUEUE_RX.borrow_ref_mut(cs).enqueue(packet) { - Ok(_) => { - #[cfg(feature = "embassy-net")] - embassy::RECEIVE_WAKER.wake(); + DATA_QUEUE_RX.borrow_ref_mut(cs).enqueue(packet) + }); - include::ESP_OK as esp_err_t - } + // We must handle the result outside of the critical section because + // EspWifiPacketBuffer::drop must not be called in a critical section + match result { + Ok(_) => { + #[cfg(feature = "embassy-net")] + embassy::RECEIVE_WAKER.wake(); - _ => { - debug!("RX QUEUE FULL"); - include::ESP_ERR_NO_MEM as esp_err_t - } + include::ESP_OK as esp_err_t + } + + Err(_) => { + debug!("RX QUEUE FULL"); + include::ESP_ERR_NO_MEM as esp_err_t } - }) + } } pub(crate) static WIFI_TX_INFLIGHT: AtomicUsize = AtomicUsize::new(0); @@ -1026,18 +1030,21 @@ fn rx_token_consume(f: F) -> R where F: FnOnce(&mut [u8]) -> R, { - critical_section::with(|cs| { + let mut data = critical_section::with(|cs| { let mut queue = DATA_QUEUE_RX.borrow_ref_mut(cs); - let mut data = unwrap!( + unwrap!( queue.dequeue(), "unreachable: transmit()/receive() ensures there is a packet to process" - ); - let buffer = data.as_slice_mut(); - dump_packet_info(&buffer); + ) + }); + + // We handle the received data outside of the critical section because + // EspWifiPacketBuffer::drop must not be called in a critical section + let buffer = data.as_slice_mut(); + dump_packet_info(&buffer); - f(buffer) - }) + f(buffer) } fn tx_token_consume(len: usize, f: F) -> R