[ovs-dev] [PATCH v2] lib/list: Add LIST_FOR_EACH_POP.

Jarno Rajahalme jrajahalme at nicira.com
Mon Apr 6 20:50:36 UTC 2015


Makes popping each member of the list a bit easier.

Signed-off-by: Jarno Rajahalme <jrajahalme at nicira.com>
---
 lib/dp-packet.c              |    5 ++---
 lib/list.h                   |    3 +++
 lib/lldp/lldpd-structs.c     |    5 ++---
 lib/lldp/lldpd.c             |    5 ++---
 lib/mcast-snooping.c         |    5 ++---
 lib/ofp-util.c               |    5 ++---
 lib/ofpbuf.c                 |    5 ++---
 lib/ovs-lldp.c               |    8 ++------
 lib/ovs-numa.c               |    5 ++---
 lib/ovs-rcu.c                |    5 ++---
 lib/vconn.c                  |    6 ++----
 ofproto/bundles.c            |    5 ++---
 ofproto/connmgr.c            |   16 ++++++----------
 ofproto/ofproto-dpif-rid.c   |    5 ++---
 ofproto/ofproto-dpif-xlate.c |    5 ++---
 ofproto/ofproto-dpif.c       |   15 ++++++---------
 ofproto/ofproto.c            |    5 ++---
 tests/library.at             |    2 +-
 tests/test-list.c            |   26 ++++++++++++++++++++++++++
 19 files changed, 70 insertions(+), 66 deletions(-)

diff --git a/lib/dp-packet.c b/lib/dp-packet.c
index 88b5708..8a4cf43 100644
--- a/lib/dp-packet.c
+++ b/lib/dp-packet.c
@@ -465,10 +465,9 @@ dp_packet_to_string(const struct dp_packet *b, size_t maxbytes)
 void
 dp_packet_list_delete(struct ovs_list *list)
 {
-    struct dp_packet *b, *next;
+    struct dp_packet *b;
 
-    LIST_FOR_EACH_SAFE (b, next, list_node, list) {
-        list_remove(&b->list_node);
+    LIST_FOR_EACH_POP (b, list_node, list) {
         dp_packet_delete(b);
     }
 }
diff --git a/lib/list.h b/lib/list.h
index b40bbef..7ba1e35 100644
--- a/lib/list.h
+++ b/lib/list.h
@@ -73,6 +73,9 @@ static inline bool list_is_short(const struct ovs_list *);
           ? INIT_CONTAINER(NEXT, (ITER)->MEMBER.next, MEMBER), 1   \
           : 0);                                                    \
          (ITER) = (NEXT))
+#define LIST_FOR_EACH_POP(ITER, MEMBER, LIST)                      \
+    while (!list_is_empty(LIST)                                    \
+           && (INIT_CONTAINER(ITER, list_pop_front(LIST), MEMBER), 1))
 
 /* Inline implementations. */
 
diff --git a/lib/lldp/lldpd-structs.c b/lib/lldp/lldpd-structs.c
index e2f8f22..b78c2e1 100644
--- a/lib/lldp/lldpd-structs.c
+++ b/lib/lldp/lldpd-structs.c
@@ -28,13 +28,12 @@ VLOG_DEFINE_THIS_MODULE(lldpd_structs);
 void
 lldpd_chassis_mgmt_cleanup(struct lldpd_chassis *chassis)
 {
-    struct lldpd_mgmt *mgmt, *mgmt_next;
+    struct lldpd_mgmt *mgmt;
 
     VLOG_DBG("cleanup management addresses for chassis %s",
              chassis->c_name ? chassis->c_name : "(unknown)");
 
-    LIST_FOR_EACH_SAFE (mgmt, mgmt_next, m_entries, &chassis->c_mgmt) {
-       list_remove(&mgmt->m_entries);
+    LIST_FOR_EACH_POP (mgmt, m_entries, &chassis->c_mgmt) {
        free(mgmt);
     }
 
diff --git a/lib/lldp/lldpd.c b/lib/lldp/lldpd.c
index 7f6e348..71d3938 100644
--- a/lib/lldp/lldpd.c
+++ b/lib/lldp/lldpd.c
@@ -164,7 +164,7 @@ static void
 lldpd_move_chassis(struct lldpd_chassis *ochassis,
     struct lldpd_chassis *chassis)
 {
-    struct lldpd_mgmt *mgmt, *mgmt_next;
+    struct lldpd_mgmt *mgmt;
     int refcount = ochassis->c_refcount;
     int index = ochassis->c_index;
     struct ovs_list listcopy;
@@ -182,8 +182,7 @@ lldpd_move_chassis(struct lldpd_chassis *ochassis,
     list_init(&ochassis->c_mgmt);
 
     /* Copy of management addresses */
-    LIST_FOR_EACH_SAFE (mgmt, mgmt_next, m_entries, &chassis->c_mgmt) {
-        list_remove(&mgmt->m_entries);
+    LIST_FOR_EACH_POP (mgmt, m_entries, &chassis->c_mgmt) {
         list_insert(&ochassis->c_mgmt, &mgmt->m_entries);
     }
 
diff --git a/lib/mcast-snooping.c b/lib/mcast-snooping.c
index 6fe3890..c3ffd6b 100644
--- a/lib/mcast-snooping.c
+++ b/lib/mcast-snooping.c
@@ -307,10 +307,9 @@ static void
 mcast_snooping_flush_group(struct mcast_snooping *ms, struct mcast_group *grp)
     OVS_REQ_WRLOCK(ms->rwlock)
 {
-    struct mcast_group_bundle *b, *next_b;
+    struct mcast_group_bundle *b;
 
-    LIST_FOR_EACH_SAFE (b, next_b, bundle_node, &grp->bundle_lru) {
-        list_remove(&b->bundle_node);
+    LIST_FOR_EACH_POP (b, bundle_node, &grp->bundle_lru) {
         free(b);
     }
     mcast_snooping_flush_group__(ms, grp);
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index a0da289..277fdfe 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -6886,10 +6886,9 @@ ofputil_decode_port_stats_request(const struct ofp_header *request,
 void
 ofputil_bucket_list_destroy(struct ovs_list *buckets)
 {
-    struct ofputil_bucket *bucket, *next_bucket;
+    struct ofputil_bucket *bucket;
 
-    LIST_FOR_EACH_SAFE (bucket, next_bucket, list_node, buckets) {
-        list_remove(&bucket->list_node);
+    LIST_FOR_EACH_POP (bucket, list_node, buckets) {
         free(bucket->ofpacts);
         free(bucket);
     }
diff --git a/lib/ofpbuf.c b/lib/ofpbuf.c
index 7510edb..c27c552 100644
--- a/lib/ofpbuf.c
+++ b/lib/ofpbuf.c
@@ -477,10 +477,9 @@ ofpbuf_to_string(const struct ofpbuf *b, size_t maxbytes)
 void
 ofpbuf_list_delete(struct ovs_list *list)
 {
-    struct ofpbuf *b, *next;
+    struct ofpbuf *b;
 
-    LIST_FOR_EACH_SAFE (b, next, list_node, list) {
-        list_remove(&b->list_node);
+    LIST_FOR_EACH_POP (b, list_node, list) {
         ofpbuf_delete(b);
     }
 }
diff --git a/lib/ovs-lldp.c b/lib/ovs-lldp.c
index db97648..197aecf 100644
--- a/lib/ovs-lldp.c
+++ b/lib/ovs-lldp.c
@@ -421,12 +421,9 @@ aa_get_vlan_queued(struct ovs_list *list)
     ovs_mutex_lock(&mutex);
 
     HMAP_FOR_EACH (lldp, hmap_node, all_lldps) {
-        struct bridge_aa_vlan *node, *node_next;
+        struct bridge_aa_vlan *node;
 
-        LIST_FOR_EACH_SAFE (node,
-                            node_next,
-                            list_node,
-                            &lldp->active_mapping_queue) {
+        LIST_FOR_EACH_POP (node, list_node, &lldp->active_mapping_queue) {
             struct bridge_aa_vlan *copy;
 
             copy = xmalloc(sizeof *copy);
@@ -437,7 +434,6 @@ aa_get_vlan_queued(struct ovs_list *list)
             list_push_back(list, &copy->list_node);
 
             /* Cleanup */
-            list_remove(&node->list_node);
             free(node->port_name);
             free(node);
         }
diff --git a/lib/ovs-numa.c b/lib/ovs-numa.c
index 3aa1036..5bed2b5 100644
--- a/lib/ovs-numa.c
+++ b/lib/ovs-numa.c
@@ -380,10 +380,9 @@ ovs_numa_dump_cores_on_numa(int numa_id)
 void
 ovs_numa_dump_destroy(struct ovs_numa_dump *dump)
 {
-    struct ovs_numa_info *iter, *next;
+    struct ovs_numa_info *iter;
 
-    LIST_FOR_EACH_SAFE (iter, next, list_node, &dump->dump) {
-        list_remove(&iter->list_node);
+    LIST_FOR_EACH_POP (iter, list_node, &dump->dump) {
         free(iter);
     }
 
diff --git a/lib/ovs-rcu.c b/lib/ovs-rcu.c
index 5276981..76659bb 100644
--- a/lib/ovs-rcu.c
+++ b/lib/ovs-rcu.c
@@ -239,7 +239,7 @@ ovsrcu_postpone__(void (*function)(void *aux), void *aux)
 static bool
 ovsrcu_call_postponed(void)
 {
-    struct ovsrcu_cbset *cbset, *next_cbset;
+    struct ovsrcu_cbset *cbset;
     struct ovs_list cbsets;
 
     guarded_list_pop_all(&flushed_cbsets, &cbsets);
@@ -249,13 +249,12 @@ ovsrcu_call_postponed(void)
 
     ovsrcu_synchronize();
 
-    LIST_FOR_EACH_SAFE (cbset, next_cbset, list_node, &cbsets) {
+    LIST_FOR_EACH_POP (cbset, list_node, &cbsets) {
         struct ovsrcu_cb *cb;
 
         for (cb = cbset->cbs; cb < &cbset->cbs[cbset->n_cbs]; cb++) {
             cb->function(cb->aux);
         }
-        list_remove(&cbset->list_node);
         free(cbset);
     }
 
diff --git a/lib/vconn.c b/lib/vconn.c
index a59829d..c033b48 100644
--- a/lib/vconn.c
+++ b/lib/vconn.c
@@ -881,13 +881,11 @@ int
 vconn_transact_multiple_noreply(struct vconn *vconn, struct ovs_list *requests,
                                 struct ofpbuf **replyp)
 {
-    struct ofpbuf *request, *next;
+    struct ofpbuf *request;
 
-    LIST_FOR_EACH_SAFE (request, next, list_node, requests) {
+    LIST_FOR_EACH_POP (request, list_node, requests) {
         int error;
 
-        list_remove(&request->list_node);
-
         error = vconn_transact_noreply(vconn, request, replyp);
         if (error || *replyp) {
             ofpbuf_list_delete(requests);
diff --git a/ofproto/bundles.c b/ofproto/bundles.c
index 4d9deac..c409091 100644
--- a/ofproto/bundles.c
+++ b/ofproto/bundles.c
@@ -100,11 +100,10 @@ ofp_bundle_create(uint32_t id, uint16_t flags)
 static void
 ofp_bundle_remove(struct ofconn *ofconn, struct ofp_bundle *item)
 {
-    struct bundle_message *msg, *next;
+    struct bundle_message *msg;
     struct hmap *bundles;
 
-    LIST_FOR_EACH_SAFE (msg, next, node, &item->msg_list) {
-        list_remove(&msg->node);
+    LIST_FOR_EACH_POP (msg, node, &item->msg_list) {
         free(msg->msg);
         free(msg);
     }
diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c
index f34652b..707385f 100644
--- a/ofproto/connmgr.c
+++ b/ofproto/connmgr.c
@@ -1093,10 +1093,9 @@ ofconn_send_reply(const struct ofconn *ofconn, struct ofpbuf *msg)
 void
 ofconn_send_replies(const struct ofconn *ofconn, struct ovs_list *replies)
 {
-    struct ofpbuf *reply, *next;
+    struct ofpbuf *reply;
 
-    LIST_FOR_EACH_SAFE (reply, next, list_node, replies) {
-        list_remove(&reply->list_node);
+    LIST_FOR_EACH_POP (reply, list_node, replies) {
         ofconn_send_reply(ofconn, reply);
     }
 }
@@ -1724,11 +1723,9 @@ connmgr_send_packet_in(struct connmgr *mgr,
 static void
 do_send_packet_ins(struct ofconn *ofconn, struct ovs_list *txq)
 {
-    struct ofpbuf *pin, *next_pin;
-
-    LIST_FOR_EACH_SAFE (pin, next_pin, list_node, txq) {
-        list_remove(&pin->list_node);
+    struct ofpbuf *pin;
 
+    LIST_FOR_EACH_POP (pin, list_node, txq) {
         if (rconn_send_with_limit(ofconn->rconn, pin,
                                   ofconn->packet_in_counter, 100) == EAGAIN) {
             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5);
@@ -2255,12 +2252,11 @@ ofmonitor_flush(struct connmgr *mgr)
     struct ofconn *ofconn;
 
     LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
-        struct ofpbuf *msg, *next;
+        struct ofpbuf *msg;
 
-        LIST_FOR_EACH_SAFE (msg, next, list_node, &ofconn->updates) {
+        LIST_FOR_EACH_POP (msg, list_node, &ofconn->updates) {
             unsigned int n_bytes;
 
-            list_remove(&msg->list_node);
             ofconn_send(ofconn, msg, ofconn->monitor_counter);
             n_bytes = rconn_packet_counter_n_bytes(ofconn->monitor_counter);
             if (!ofconn->monitor_paused && n_bytes > 128 * 1024) {
diff --git a/ofproto/ofproto-dpif-rid.c b/ofproto/ofproto-dpif-rid.c
index 17bcede..f1b3bdc 100644
--- a/ofproto/ofproto-dpif-rid.c
+++ b/ofproto/ofproto-dpif-rid.c
@@ -67,7 +67,7 @@ recirc_run(void)
     /* Do maintenance at most 4 times / sec. */
     ovs_mutex_lock(&mutex);
     if (now - last > 250) {
-        struct recirc_id_node *node, *next;
+        struct recirc_id_node *node;
 
         last = now;
 
@@ -86,8 +86,7 @@ recirc_run(void)
         /* Delete the expired.  These have been lingering for at least 250 ms,
          * which should be enough for any ongoing recirculations to be
          * finished. */
-        LIST_FOR_EACH_SAFE (node, next, exp_node, &expired) {
-            list_remove(&node->exp_node);
+        LIST_FOR_EACH_POP (node, exp_node, &expired) {
             cmap_remove(&id_map, &node->id_node, node->id);
             ovsrcu_postpone(free, node);
         }
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 4f82238..55ae683 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -949,14 +949,13 @@ xlate_bundle_set(struct ofproto_dpif *ofproto, struct ofbundle *ofbundle,
 static void
 xlate_xbundle_remove(struct xlate_cfg *xcfg, struct xbundle *xbundle)
 {
-    struct xport *xport, *next;
+    struct xport *xport;
 
     if (!xbundle) {
         return;
     }
 
-    LIST_FOR_EACH_SAFE (xport, next, bundle_node, &xbundle->xports) {
-        list_remove(&xport->bundle_node);
+    LIST_FOR_EACH_POP (xport, bundle_node, &xbundle->xports) {
         xport->xbundle = NULL;
     }
 
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 837ae0b..01d99c5 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -886,7 +886,7 @@ open_dpif_backer(const char *type, struct dpif_backer **backerp)
     struct dpif_port port;
     struct shash_node *node;
     struct ovs_list garbage_list;
-    struct odp_garbage *garbage, *next;
+    struct odp_garbage *garbage;
 
     struct sset names;
     char *backer_name;
@@ -964,9 +964,8 @@ open_dpif_backer(const char *type, struct dpif_backer **backerp)
     }
     dpif_port_dump_done(&port_dump);
 
-    LIST_FOR_EACH_SAFE (garbage, next, list_node, &garbage_list) {
+    LIST_FOR_EACH_POP (garbage, list_node, &garbage_list) {
         dpif_port_del(backer->dpif, garbage->odp_port);
-        list_remove(&garbage->list_node);
         free(garbage);
     }
 
@@ -1377,7 +1376,7 @@ static void
 destruct(struct ofproto *ofproto_)
 {
     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
-    struct ofproto_packet_in *pin, *next_pin;
+    struct ofproto_packet_in *pin;
     struct rule_dpif *rule;
     struct oftable *table;
     struct ovs_list pins;
@@ -1400,8 +1399,7 @@ destruct(struct ofproto *ofproto_)
     }
 
     guarded_list_pop_all(&ofproto->pins, &pins);
-    LIST_FOR_EACH_SAFE (pin, next_pin, list_node, &pins) {
-        list_remove(&pin->list_node);
+    LIST_FOR_EACH_POP (pin, list_node, &pins) {
         free(CONST_CAST(void *, pin->up.packet));
         free(pin);
     }
@@ -1456,13 +1454,12 @@ run(struct ofproto *ofproto_)
     /* Do not perform any periodic activity required by 'ofproto' while
      * waiting for flow restore to complete. */
     if (!ofproto_get_flow_restore_wait()) {
-        struct ofproto_packet_in *pin, *next_pin;
+        struct ofproto_packet_in *pin;
         struct ovs_list pins;
 
         guarded_list_pop_all(&ofproto->pins, &pins);
-        LIST_FOR_EACH_SAFE (pin, next_pin, list_node, &pins) {
+        LIST_FOR_EACH_POP (pin, list_node, &pins) {
             connmgr_send_packet_in(ofproto->up.connmgr, pin);
-            list_remove(&pin->list_node);
             free(CONST_CAST(void *, pin->up.packet));
             free(pin);
         }
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index a36a1f8..927521b 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -2961,9 +2961,9 @@ static void
 learned_cookies_flush(struct ofproto *ofproto, struct ovs_list *dead_cookies)
     OVS_REQUIRES(ofproto_mutex)
 {
-    struct learned_cookie *c, *next;
+    struct learned_cookie *c;
 
-    LIST_FOR_EACH_SAFE (c, next, u.list_node, dead_cookies) {
+    LIST_FOR_EACH_POP (c, u.list_node, dead_cookies) {
         struct rule_criteria criteria;
         struct rule_collection rules;
         struct match match;
@@ -2977,7 +2977,6 @@ learned_cookies_flush(struct ofproto *ofproto, struct ovs_list *dead_cookies)
         rule_criteria_destroy(&criteria);
         rule_collection_destroy(&rules);
 
-        list_remove(&c->u.list_node);
         free(c);
     }
 }
diff --git a/tests/library.at b/tests/library.at
index 2507688..dfc5ad9 100644
--- a/tests/library.at
+++ b/tests/library.at
@@ -38,7 +38,7 @@ AT_CHECK([ovstest test-atomic])
 AT_CLEANUP
 
 AT_SETUP([test linked lists])
-AT_CHECK([ovstest test-list], [0], [..
+AT_CHECK([ovstest test-list], [0], [...
 ])
 AT_CLEANUP
 
diff --git a/tests/test-list.c b/tests/test-list.c
index 5fd7149..9b6b0bd 100644
--- a/tests/test-list.c
+++ b/tests/test-list.c
@@ -159,6 +159,31 @@ test_list_for_each_safe(void)
     }
 }
 
+/* Tests that LIST_FOR_EACH_POP removes the elements of a list.  */
+static void
+test_list_for_each_pop(void)
+{
+    enum { MAX_ELEMS = 10 };
+    size_t n;
+
+    for (n = 0; n <= MAX_ELEMS; n++) {
+        struct element elements[MAX_ELEMS];
+        int values[MAX_ELEMS];
+        struct ovs_list list;
+        struct element *e;
+        size_t n_remaining;
+
+        make_list(&list, elements, values, n);
+
+        n_remaining = n;
+        LIST_FOR_EACH_POP (e, node, &list) {
+            n_remaining--;
+            memmove(values, values + 1, sizeof *values * n_remaining);
+            check_list(&list, values, n_remaining);
+        }
+    }
+}
+
 static void
 run_test(void (*function)(void))
 {
@@ -171,6 +196,7 @@ test_list_main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
 {
     run_test(test_list_construction);
     run_test(test_list_for_each_safe);
+    run_test(test_list_for_each_pop);
     printf("\n");
 }
 
-- 
1.7.10.4




More information about the dev mailing list