This is an automated email from the ASF dual-hosted git repository.

jerpelea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 4d3c5cac467232b985f48c29fab664f4f4543325
Author: Felipe Moura <[email protected]>
AuthorDate: Sat Aug 1 12:37:00 2026 -0300

    drivers/sensors/sensor: always report POLLIN for fetch only sensor
    
    A fetch() only lower half reads the device on demand, so its data is
    always available and there is never anything to wait for. The upper half
    did not reflect that: poll() only reported POLLIN when the descriptor was
    opened O_NONBLOCK, and a blocking read() waited on buffersem, which is
    only posted when the lower half drives notify_event from an interrupt of
    its own.
    
    A fetch() only sensor with no interrupt therefore never satisfied
    poll()/read() at all. This is not hypothetical: in the in tree
    nucleo-h563zi:dts configuration CONFIG_STM32_DTS_TRIGGER defaults to 0,
    which selects stm32_dts_fetch(), and no CONFIG_STM32_DTS_ITEN_* option is
    enabled, so the DTS interrupt never fires. A blocking read() on that
    sensor waits forever, even though stm32_dts_fetch() performs a complete
    software triggered measurement on its own and needs no interrupt at all.
    Applications had to work around this by forcing O_NONBLOCK on the
    descriptor themselves, see apache/nuttx-apps#3686.
    
    Drop the O_NONBLOCK special case in both paths: sensor_poll() now always
    reports POLLIN for a fetch only sensor and sensor_read() calls fetch()
    directly instead of waiting. Update the sensor_ops_s::fetch
    documentation, which described the old contract.
    
    With the wait gone, buffersem has no waiters left. Its only two readers
    were the ones removed here, both in the fetch path: the wait in
    sensor_read() and the nxsem_get_value() in sensor_poll(). The remaining
    nxsem_post() calls in sensor_push_event() and sensor_notify_event() had
    nothing left to wake, so drop the semaphore and those posts as well.
    
    Assisted-by: Claude:claude-sonnet-5
    
    Signed-off-by: Felipe Moura <[email protected]>
---
 drivers/sensors/sensor.c       | 54 +++++++++---------------------------------
 include/nuttx/sensors/sensor.h |  8 +++----
 2 files changed, 15 insertions(+), 47 deletions(-)

diff --git a/drivers/sensors/sensor.c b/drivers/sensors/sensor.c
index cb88cb33e17..ef08737ae82 100644
--- a/drivers/sensors/sensor.c
+++ b/drivers/sensors/sensor.c
@@ -101,7 +101,6 @@ struct sensor_user_s
                                 */
   unsigned int     event;      /* The event of this sensor, eg: 
SENSOR_EVENT_FLUSH_COMPLETE. */
   bool             flushing;   /* The is used to indicate user is flushing */
-  sem_t            buffersem;  /* Wakeup user waiting for data in circular 
buffer */
   size_t           bufferpos;  /* The index of user generation in buffer */
 
   /* The subscriber info
@@ -774,7 +773,6 @@ static int sensor_open(FAR struct file *filep)
   user->state.interval = UINT32_MAX;
   user->state.esize = upper->state.esize;
   user->state.nonwakeup = true;
-  nxsem_init(&user->buffersem, 0, 0);
   list_add_tail(&upper->userlist, &user->node);
 
   /* The new user generation, notify to other users */
@@ -835,7 +833,6 @@ static int sensor_close(FAR struct file *filep)
     }
 
   list_delete(&user->node);
-  nxsem_destroy(&user->buffersem);
 
   /* The user is closed, notify to other users */
 
@@ -871,24 +868,18 @@ static ssize_t sensor_read(FAR struct file *filep, FAR 
char *buffer,
           return -EINVAL;
         }
 
-      if (!(filep->f_oflags & O_NONBLOCK))
-        {
-          nxrmutex_unlock(&upper->lock);
-          ret = nxsem_wait_uninterruptible(&user->buffersem);
-          if (ret < 0)
-            {
-              return ret;
-            }
+      /* Fetch the data from the device directly, there is nothing to wait
+       * for. This matches the POLLIN sensor_poll() always reports for a
+       * fetch only sensor.
+       */
 
-          nxrmutex_lock(&upper->lock);
-        }
-      else if (!upper->state.nsubscribers)
+      if (!upper->state.nsubscribers)
         {
           ret = -EAGAIN;
           goto out;
         }
 
-        ret = lower->ops->fetch(lower, filep, buffer, len);
+      ret = lower->ops->fetch(lower, filep, buffer, len);
     }
   else if (circbuf_is_empty(&upper->buffer))
     {
@@ -1166,7 +1157,6 @@ static int sensor_poll(FAR struct file *filep,
   FAR struct sensor_lowerhalf_s *lower = upper->lower;
   FAR struct sensor_user_s *user = filep->f_priv;
   pollevent_t eventset = 0;
-  int semcount;
   int ret = 0;
 
   nxrmutex_lock(&upper->lock);
@@ -1184,20 +1174,12 @@ static int sensor_poll(FAR struct file *filep,
       fds->priv = filep;
       if (lower->ops->fetch)
         {
-          /* Always return POLLIN for fetch data directly(non-block) */
+          /* Always return POLLIN for fetch only sensor: the data is read
+           * from the device on demand by sensor_read(), so there is never
+           * anything to wait for.
+           */
 
-          if (filep->f_oflags & O_NONBLOCK)
-            {
-              eventset |= POLLIN;
-            }
-          else
-            {
-              nxsem_get_value(&user->buffersem, &semcount);
-              if (semcount > 0)
-                {
-                  eventset |= POLLIN;
-                }
-            }
+          eventset |= POLLIN;
         }
       else if (sensor_is_updated(upper, user))
         {
@@ -1229,7 +1211,6 @@ static ssize_t sensor_push_event(FAR void *priv, FAR 
const void *data,
   FAR struct sensor_lowerhalf_s *lower = upper->lower;
   FAR struct sensor_user_s *user;
   unsigned long envcount;
-  int semcount;
   int ret;
 
   nxrmutex_lock(&upper->lock);
@@ -1287,12 +1268,6 @@ static ssize_t sensor_push_event(FAR void *priv, FAR 
const void *data,
     {
       if (sensor_is_updated(upper, user))
         {
-          nxsem_get_value(&user->buffersem, &semcount);
-          if (semcount < 1)
-            {
-              nxsem_post(&user->buffersem);
-            }
-
           sensor_pollnotify_one(user, POLLIN, SENSOR_ROLE_RD);
         }
     }
@@ -1305,17 +1280,10 @@ static void sensor_notify_event(FAR void *priv)
 {
   FAR struct sensor_upperhalf_s *upper = priv;
   FAR struct sensor_user_s *user;
-  int semcount;
 
   nxrmutex_lock(&upper->lock);
   list_for_every_entry(&upper->userlist, user, struct sensor_user_s, node)
     {
-      nxsem_get_value(&user->buffersem, &semcount);
-      if (semcount < 1)
-        {
-          nxsem_post(&user->buffersem);
-        }
-
       sensor_pollnotify_one(user, POLLIN, SENSOR_ROLE_RD);
     }
 
diff --git a/include/nuttx/sensors/sensor.h b/include/nuttx/sensors/sensor.h
index e675be50a67..f266eb8cdd3 100644
--- a/include/nuttx/sensors/sensor.h
+++ b/include/nuttx/sensors/sensor.h
@@ -353,10 +353,10 @@ struct sensor_ops_s
    * If fetch isn't NULL, upper half driver will disable intermediate
    * buffer and userspace can't set buffer size by ioctl.
    *
-   * You can call this function to read sensor register data by I2C/SPI bus
-   * when open mode is non-block, and poll are always successful.
-   * When you call this function and open mode is block, you will wait
-   * until sensor data ready, then read sensor data.
+   * You can call this function to read sensor register data by I2C/SPI
+   * bus. The data is read from the device on demand, so it is always
+   * available: poll() always reports POLLIN and read() never blocks,
+   * whether or not the open mode is non-block.
    *
    * Input Parameters:
    *   lower      - The instance of lower half sensor driver.

Reply via email to