The code for rte_eal_alarm_cancel was using two loops and duplicate
code to handle cancel at the start of the list. Introduce the
LIST_FOREACH_SAFE() macro from FreeBsd which makes writing
the loop cleaner and simpler.

Signed-off-by: Stephen Hemminger <step...@networkplumber.org>
---
 lib/eal/linux/eal_alarm.c | 51 +++++++++++++++------------------------
 1 file changed, 19 insertions(+), 32 deletions(-)

diff --git a/lib/eal/linux/eal_alarm.c b/lib/eal/linux/eal_alarm.c
index eeb096213b..3f3b722421 100644
--- a/lib/eal/linux/eal_alarm.c
+++ b/lib/eal/linux/eal_alarm.c
@@ -53,6 +53,13 @@ static struct rte_intr_handle *intr_handle;
 static int handler_registered = 0;
 static void eal_alarm_callback(void *arg);
 
+#ifndef LIST_FOREACH_SAFE
+#define LIST_FOREACH_SAFE(var, head, field, tvar)                      \
+       for ((var) = LIST_FIRST((head));                                \
+           (var) && ((tvar) = LIST_NEXT((var), field), 1);             \
+           (var) = (tvar))
+#endif
+
 void
 rte_eal_alarm_cleanup(void)
 {
@@ -194,7 +201,7 @@ rte_eal_alarm_set(uint64_t us, rte_eal_alarm_callback 
cb_fn, void *cb_arg)
 int
 rte_eal_alarm_cancel(rte_eal_alarm_callback cb_fn, void *cb_arg)
 {
-       struct alarm_entry *ap, *ap_prev;
+       struct alarm_entry *ap, *tmp;
        int count = 0;
        int err = 0;
        int executing;
@@ -207,46 +214,26 @@ rte_eal_alarm_cancel(rte_eal_alarm_callback cb_fn, void 
*cb_arg)
        do {
                executing = 0;
                rte_spinlock_lock(&alarm_list_lk);
-               /* remove any matches at the start of the list */
-               while ((ap = LIST_FIRST(&alarm_list)) != NULL &&
-                               cb_fn == ap->cb_fn &&
-                               (cb_arg == (void *)-1 || cb_arg == ap->cb_arg)) 
{
-
-                       if (ap->executing == 0) {
-                               LIST_REMOVE(ap, next);
-                               free(ap);
-                               count++;
-                       } else {
-                               /* If calling from other context, mark that 
alarm is executing
-                                * so loop can spin till it finish. Otherwise 
we are trying to
-                                * cancel our self - mark it by EINPROGRESS */
-                               if (pthread_equal(ap->executing_id, 
pthread_self()) == 0)
-                                       executing++;
-                               else
-                                       err = EINPROGRESS;
-
-                               break;
-                       }
-               }
-               ap_prev = ap;
 
-               /* now go through list, removing entries not at start */
-               LIST_FOREACH(ap, &alarm_list, next) {
+               LIST_FOREACH_SAFE(ap, &alarm_list, next, tmp) {
                        /* this won't be true first time through */
                        if (cb_fn == ap->cb_fn &&
                                        (cb_arg == (void *)-1 || cb_arg == 
ap->cb_arg)) {
-
                                if (ap->executing == 0) {
                                        LIST_REMOVE(ap, next);
                                        free(ap);
                                        count++;
-                                       ap = ap_prev;
-                               } else if (pthread_equal(ap->executing_id, 
pthread_self()) == 0)
-                                       executing++;
-                               else
-                                       err = EINPROGRESS;
+                               } else {
+                                       /* If calling from other context, mark 
that alarm is executing
+                                        * so loop can spin till it finish. 
Otherwise we are trying to
+                                        * cancel our self - mark it by 
EINPROGRESS
+                                        */
+                                       if (pthread_equal(ap->executing_id, 
pthread_self()) == 0)
+                                               executing++;
+                                       else
+                                               err = EINPROGRESS;
+                               }
                        }
-                       ap_prev = ap;
                }
                rte_spinlock_unlock(&alarm_list_lk);
        } while (executing != 0);
-- 
2.43.0

Reply via email to