CAN driver: Fix a problem where the rx_sem count can grow without bounds
This commit is contained in:
parent
38dee32fdc
commit
320c584888
@ -10725,3 +10725,6 @@
|
||||
* drivers/lcd/ and include/nuttx/lcd: Modify the SSD1306 LCD driver to
|
||||
support either the SPI or I2C interface. From Alan Carvalho de Assis
|
||||
(2015-07-15).
|
||||
* drivers/can.c: Fix an issue in the CAN driver hwere the rx_sem
|
||||
count can grow beyond bounds (2015-07-15).
|
||||
|
||||
|
@ -326,7 +326,14 @@ static ssize_t can_read(FAR struct file *filep, FAR char *buffer,
|
||||
|
||||
/* Wait for a message to be received */
|
||||
|
||||
ret = sem_wait(&dev->cd_recv.rx_sem);
|
||||
dev->cd_nrxwaiters++;
|
||||
do
|
||||
{
|
||||
ret = sem_wait(&dev->cd_recv.rx_sem);
|
||||
}
|
||||
while (dev->cd_recv.rx_head == dev->cd_recv.rx_tail);
|
||||
dev->cd_nrxwaiters--;
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = -get_errno();
|
||||
@ -818,7 +825,11 @@ int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr,
|
||||
* message buffer.
|
||||
*/
|
||||
|
||||
sem_post(&fifo->rx_sem);
|
||||
if (dev->cd_nrxwaiters > 0)
|
||||
{
|
||||
sem_post(&fifo->rx_sem);
|
||||
}
|
||||
|
||||
err = OK;
|
||||
}
|
||||
|
||||
|
@ -206,10 +206,10 @@ struct can_rtrwait_s
|
||||
{
|
||||
sem_t cr_sem; /* Wait for RTR response */
|
||||
uint16_t cr_id; /* The ID that is waited for */
|
||||
FAR struct can_msg_s *cr_msg; /* This is where the RTR reponse goes */
|
||||
FAR struct can_msg_s *cr_msg; /* This is where the RTR response goes */
|
||||
};
|
||||
|
||||
/* This structure defines all of the operations providd by the architecture specific
|
||||
/* This structure defines all of the operations provided by the architecture specific
|
||||
* logic. All fields must be provided with non-NULL function pointers by the
|
||||
* caller of can_register().
|
||||
*/
|
||||
@ -284,6 +284,7 @@ struct can_dev_s
|
||||
uint8_t cd_ocount; /* The number of times the device has been opened */
|
||||
uint8_t cd_npendrtr; /* Number of pending RTR messages */
|
||||
uint8_t cd_ntxwaiters; /* Number of threads waiting to enqueue a message */
|
||||
volatile uint8_t cd_nrxwaiters; /* Number of threads waiting to receive a message */
|
||||
sem_t cd_closesem; /* Locks out new opens while close is in progress */
|
||||
sem_t cd_recvsem; /* Used to wakeup user waiting for space in cd_recv.buffer */
|
||||
struct can_txfifo_s cd_xmit; /* Describes transmit FIFO */
|
||||
|
Loading…
Reference in New Issue
Block a user