You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2022/10/31 22:59:35 UTC

[incubator-nuttx] branch master updated: sched/posix/timer: handle invaild timerid correctly

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

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


The following commit(s) were added to refs/heads/master by this push:
     new e0a3fdf982 sched/posix/timer: handle invaild timerid correctly
e0a3fdf982 is described below

commit e0a3fdf98207346fe6db3c1f7bc428ead163f893
Author: chao an <an...@xiaomi.com>
AuthorDate: Tue Nov 1 02:11:18 2022 +0800

    sched/posix/timer: handle invaild timerid correctly
    
    TIMER_SETTIME(2)
    
    NAME
           timer_settime, timer_gettime - arm/disarm and fetch state of POSIX per-process timer
    
    SYNOPSIS
           #include <time.h>
    
           int timer_settime(timer_t timerid, int flags,
                             const struct itimerspec *new_value,
                             struct itimerspec *old_value);
           int timer_gettime(timer_t timerid, struct itimerspec *curr_value);
    ...
    ERRORS
    ...
           EINVAL timerid is invalid.
    
    Signed-off-by: chao an <an...@xiaomi.com>
---
 include/nuttx/queue.h          |  2 +-
 sched/timer/timer.h            |  1 +
 sched/timer/timer_delete.c     |  2 +-
 sched/timer/timer_gettime.c    |  2 +-
 sched/timer/timer_initialize.c | 41 +++++++++++++++++++++++++++++++++++++++++
 sched/timer/timer_settime.c    | 27 ++++++++++++++-------------
 6 files changed, 59 insertions(+), 16 deletions(-)

diff --git a/include/nuttx/queue.h b/include/nuttx/queue.h
index a1665c00fe..4bf3cbcb37 100644
--- a/include/nuttx/queue.h
+++ b/include/nuttx/queue.h
@@ -156,7 +156,7 @@
   while (0)
 
 #define sq_for_every(q, p) \
-  for((p) = (q)->head; (p) != NULL; (p) = (p)->flink)
+  for ((p) = (q)->head; (p) != NULL; (p) = (p)->flink)
 
 #define sq_rem(p, q) \
   do \
diff --git a/sched/timer/timer.h b/sched/timer/timer.h
index 30ba2ecaeb..62a7940baf 100644
--- a/sched/timer/timer.h
+++ b/sched/timer/timer.h
@@ -86,6 +86,7 @@ extern volatile sq_queue_t g_alloctimers;
 void timer_initialize(void);
 void timer_deleteall(pid_t pid);
 int timer_release(FAR struct posix_timer_s *timer);
+FAR struct posix_timer_s *timer_gethandle(timer_t timerid);
 
 #endif /* CONFIG_DISABLE_POSIX_TIMERS */
 #endif /* __SCHED_TIMER_TIMER_H */
diff --git a/sched/timer/timer_delete.c b/sched/timer/timer_delete.c
index 77134000eb..d6b02c8bcd 100644
--- a/sched/timer/timer_delete.c
+++ b/sched/timer/timer_delete.c
@@ -62,7 +62,7 @@
 
 int timer_delete(timer_t timerid)
 {
-  int ret = timer_release((FAR struct posix_timer_s *)timerid);
+  int ret = timer_release(timer_gethandle(timerid));
   if (ret < 0)
     {
       set_errno(-ret);
diff --git a/sched/timer/timer_gettime.c b/sched/timer/timer_gettime.c
index 17aceb5e30..9e1da74812 100644
--- a/sched/timer/timer_gettime.c
+++ b/sched/timer/timer_gettime.c
@@ -70,7 +70,7 @@
 
 int timer_gettime(timer_t timerid, FAR struct itimerspec *value)
 {
-  FAR struct posix_timer_s *timer = (FAR struct posix_timer_s *)timerid;
+  FAR struct posix_timer_s *timer = timer_gethandle(timerid);
   sclock_t ticks;
 
   if (!timer || !value)
diff --git a/sched/timer/timer_initialize.c b/sched/timer/timer_initialize.c
index 5502295154..5dc296bb41 100644
--- a/sched/timer/timer_initialize.c
+++ b/sched/timer/timer_initialize.c
@@ -143,4 +143,45 @@ void timer_deleteall(pid_t pid)
   leave_critical_section(flags);
 }
 
+/****************************************************************************
+ * Name: timer_gethandle
+ *
+ * Description:
+ *   Returns the posix timer in the activity from the corresponding timerid
+ *
+ * Input Parameters:
+ *   timerid - The pre-thread timer, previously created by the call to
+ *     timer_create(), to be be set.
+ *
+ * Returned Value:
+ *   On success, timer_gethandle() returns pointer to the posix_timer_s;
+ *   On error, NULL is returned.
+ *
+ ****************************************************************************/
+
+FAR struct posix_timer_s *timer_gethandle(timer_t timerid)
+{
+  FAR struct posix_timer_s *timer = NULL;
+  FAR sq_entry_t *entry;
+  irqstate_t intflags;
+
+  if (timerid != NULL)
+    {
+      intflags = enter_critical_section();
+
+      sq_for_every(&g_alloctimers, entry)
+        {
+          if (entry == timerid)
+            {
+              timer = (FAR struct posix_timer_s *)timerid;
+              break;
+            }
+        }
+
+      leave_critical_section(intflags);
+    }
+
+  return timer;
+}
+
 #endif /* CONFIG_DISABLE_POSIX_TIMERS */
diff --git a/sched/timer/timer_settime.c b/sched/timer/timer_settime.c
index 7ee035c5c4..706335be8b 100644
--- a/sched/timer/timer_settime.c
+++ b/sched/timer/timer_settime.c
@@ -122,7 +122,12 @@ static inline void timer_restart(FAR struct posix_timer_s *timer,
 
 static void timer_timeout(wdparm_t itimer)
 {
-  FAR struct posix_timer_s *timer = (FAR struct posix_timer_s *)itimer;
+  FAR struct posix_timer_s *timer = timer_gethandle((timer_t)itimer);
+
+  if (timer == NULL)
+    {
+      return;
+    }
 
   /* Send the specified signal to the specified task.   Increment the
    * reference count on the timer first so that will not be deleted until
@@ -216,7 +221,7 @@ int timer_settime(timer_t timerid, int flags,
                   FAR const struct itimerspec *value,
                   FAR struct itimerspec *ovalue)
 {
-  FAR struct posix_timer_s *timer = (FAR struct posix_timer_s *)timerid;
+  FAR struct posix_timer_s *timer = timer_gethandle(timerid);
   irqstate_t intflags;
   sclock_t delay;
   int ret = OK;
@@ -301,8 +306,6 @@ int timer_settime(timer_t timerid, int flags,
 
   if (ret < 0)
     {
-      set_errno(-ret);
-      ret = ERROR;
       goto errout;
     }
 
@@ -320,19 +323,17 @@ int timer_settime(timer_t timerid, int flags,
   if (delay >= 0)
     {
       ret = wd_start(&timer->pt_wdog, delay, timer_timeout, (wdparm_t)timer);
-      if (ret < 0)
-        {
-          set_errno(-ret);
-          ret = ERROR;
-        }
-      else
-        {
-          ret = OK;
-        }
     }
 
 errout:
   leave_critical_section(intflags);
+
+  if (ret < 0)
+    {
+      set_errno(-ret);
+      ret = ERROR;
+    }
+
   return ret;
 }