serial: Prevent RX stall

Re-check RX queue status after uart_enablerxint() and before blocking
the reading task on the receive semaphore. cdcacm (and maybe other UART
drivers) can push buffered data into the receive queue during
uart_enablerxint(), leading to a blocked task while data is already
available.

Signed-off-by: Tido Klaassen <tido@4gh.eu>
This commit is contained in:
Tido Klaassen 2020-11-19 12:19:46 +01:00 committed by Xiang Xiao
parent 96c29e75b7
commit 93ff68e75a

View File

@ -924,6 +924,20 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
/* Re-enable UART Rx interrupts */
uart_enablerxint(dev);
/* Check again if the RX buffer is empty. The UART driver
* might have buffered data received between disabling the
* RX interrupt and entering the critical section. Some
* drivers (looking at you, cdcacm...) will push the buffer
* to the receive queue during uart_enablerxint().
* Just continue processing the RX queue if this happens.
*/
if (rxbuf->head != rxbuf->tail)
{
leave_critical_section(flags);
continue;
}
#endif
#ifdef CONFIG_SERIAL_REMOVABLE