From e657b3572059e55988432cdb6a423a4a3fafbe5f Mon Sep 17 00:00:00 2001 From: zhaohaiyang1 Date: Thu, 16 Jan 2025 20:52:19 +0800 Subject: [PATCH] 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 --- drivers/can/Kconfig | 7 ---- drivers/can/can.c | 72 +++++++++++++++++++++++------------------ include/nuttx/can/can.h | 2 +- 3 files changed, 41 insertions(+), 40 deletions(-) diff --git a/drivers/can/Kconfig b/drivers/can/Kconfig index a612d519c5..9d6a4183ee 100644 --- a/drivers/can/Kconfig +++ b/drivers/can/Kconfig @@ -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 diff --git a/drivers/can/can.c b/drivers/can/can.c index b262e6985d..628eb584ec 100644 --- a/drivers/can/can.c +++ b/drivers/can/can.c @@ -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? */ diff --git a/include/nuttx/can/can.h b/include/nuttx/can/can.h index 7651cc8d4f..1a82ca3560 100644 --- a/include/nuttx/can/can.h +++ b/include/nuttx/can/can.h @@ -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 */