nuttx/can: Modify poll logic to bind can_reader_s and pollfd.

For clearing some variables corresponding with the pollfds of the felip in can_close API, we modify poll logic by binding can_reader_s and pollfd.

Signed-off-by: zhaohaiyang1 <zhaohaiyang1@xiaomi.com>
This commit is contained in:
zhaohaiyang1 2025-01-16 20:52:19 +08:00 committed by Alan C. Assis
parent 31270a8479
commit e657b35720
3 changed files with 41 additions and 40 deletions

View file

@ -157,13 +157,6 @@ config CAN_LOOPBACK
driver does support loopback mode, the setting will enable it. (If the
driver does not, this setting will have no effect).
config CAN_NPOLLWAITERS
int "Number of poll waiters"
default 2
---help---
The maximum number of threads that may be waiting on the
poll method.
config CAN_USE_RTR
bool "Include RTR in CAN header"
default n

View file

@ -308,6 +308,21 @@ static int can_close(FAR struct file *filep)
if (((FAR struct can_reader_s *)node) ==
((FAR struct can_reader_s *)filep->f_priv))
{
FAR struct can_reader_s *reader = (FAR struct can_reader_s *)node;
FAR struct can_rxfifo_s *fifo = &reader->fifo;
/* Unlock the binary semaphore, waking up can_read if it
* is blocked.
*/
nxsem_post(&fifo->rx_sem);
/* Notify specfic poll/select waiter that they can read from the
* cd_recv buffer
*/
poll_notify(&reader->cd_fds, 1, POLLHUP);
reader->cd_fds = NULL;
list_delete(node);
kmm_free(node);
break;
@ -953,13 +968,12 @@ static int can_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
static int can_poll(FAR struct file *filep, FAR struct pollfd *fds,
bool setup)
{
FAR struct inode *inode = filep->f_inode;
FAR struct can_dev_s *dev = inode->i_private;
FAR struct can_reader_s *reader = NULL;
pollevent_t eventset = 0;
irqstate_t flags;
int ret;
int i;
FAR struct inode *inode = filep->f_inode;
FAR struct can_dev_s *dev = inode->i_private;
FAR struct can_reader_s *reader = NULL;
pollevent_t eventset = 0;
int ret = OK;
irqstate_t flags;
/* Some sanity checking */
@ -999,27 +1013,20 @@ static int can_poll(FAR struct file *filep, FAR struct pollfd *fds,
* slot for the poll structure reference.
*/
for (i = 0; i < CONFIG_CAN_NPOLLWAITERS; i++)
{
/* Find an available slot */
if (dev->cd_fds[i] == NULL)
{
/* Bind the poll structure and this slot */
dev->cd_fds[i] = fds;
fds->priv = &dev->cd_fds[i];
break;
}
}
if (i >= CONFIG_CAN_NPOLLWAITERS)
if (reader->cd_fds != NULL)
{
fds->priv = NULL;
ret = -EBUSY;
goto errout;
}
/* Have found an available slot,
* bind the poll structure and this slot
*/
reader->cd_fds = fds;
fds->priv = &reader->cd_fds;
/* Should we immediately notify on any of the requested events?
* First, check if the sender is full.
*/
@ -1268,6 +1275,11 @@ int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr,
nxsem_post(&fifo->rx_sem);
}
/* Notify specfic poll/select waiter that they can read from the
* cd_recv buffer
*/
poll_notify(&reader->cd_fds, 1, POLLIN);
ret = OK;
}
#ifdef CONFIG_CAN_ERRORS
@ -1280,15 +1292,6 @@ int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr,
#endif
}
/* Notify all poll/select waiters that they can read from the
* cd_recv buffer
*/
if (ret == OK)
{
poll_notify(dev->cd_fds, CONFIG_CAN_NPOLLWAITERS, POLLIN);
}
leave_critical_section(flags);
return ret;
}
@ -1365,6 +1368,7 @@ int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr,
int can_txdone(FAR struct can_dev_s *dev)
{
FAR struct list_node *node;
int ret = -ENOENT;
irqstate_t flags;
@ -1398,7 +1402,11 @@ int can_txdone(FAR struct can_dev_s *dev)
* buffer
*/
poll_notify(dev->cd_fds, CONFIG_CAN_NPOLLWAITERS, POLLOUT);
list_for_every(&dev->cd_readers, node)
{
FAR struct can_reader_s *reader = (FAR struct can_reader_s *)node;
poll_notify(&reader->cd_fds, 1, POLLOUT);
}
/* Are there any threads waiting for space in the sender? */

View file

@ -801,6 +801,7 @@ struct can_reader_s
{
struct list_node list;
struct can_rxfifo_s fifo; /* Describes receive FIFO */
FAR struct pollfd *cd_fds;
};
struct can_transv_s
@ -825,7 +826,6 @@ struct can_dev_s
FAR const struct can_ops_s *cd_ops; /* Arch-specific operations */
FAR void *cd_priv; /* Used by the arch-specific logic */
FAR struct can_transv_s *cd_transv; /* Describes CAN transceiver */
FAR struct pollfd *cd_fds[CONFIG_CAN_NPOLLWAITERS];
};
/* Structures used with ioctl calls */