pinsched: Eliminate function callback in interface.
authorBen Pfaff <blp@nicira.com>
Wed, 23 Oct 2013 04:58:58 +0000 (21:58 -0700)
committerBen Pfaff <blp@nicira.com>
Wed, 23 Oct 2013 15:37:41 +0000 (08:37 -0700)
I'm not a fan of function callbacks because I feel that they obscure
interfaces.  This eliminates the function callback used until now in
the pinsched code.

Signed-off-by: Ben Pfaff <blp@nicira.com>
ofproto/connmgr.c
ofproto/pinsched.c
ofproto/pinsched.h

index d42ab4f..3c2b6cc 100644 (file)
@@ -153,7 +153,7 @@ static void ofconn_set_rate_limit(struct ofconn *, int rate, int burst);
 static void ofconn_send(const struct ofconn *, struct ofpbuf *,
                         struct rconn_packet_counter *);
 
-static void do_send_packet_in(struct ofpbuf *, void *ofconn_);
+static void do_send_packet_ins(struct ofconn *, struct list *txq);
 
 /* A listener for incoming OpenFlow "service" connections. */
 struct ofservice {
@@ -1301,7 +1301,10 @@ ofconn_run(struct ofconn *ofconn,
     size_t i;
 
     for (i = 0; i < N_SCHEDULERS; i++) {
-        pinsched_run(ofconn->schedulers[i], do_send_packet_in, ofconn);
+        struct list txq;
+
+        pinsched_run(ofconn->schedulers[i], &txq);
+        do_send_packet_ins(ofconn, &txq);
     }
 
     rconn_run(ofconn->rconn);
@@ -1522,14 +1525,17 @@ connmgr_send_packet_in(struct connmgr *mgr,
     }
 }
 
-/* pinsched callback for sending 'ofp_packet_in' on 'ofconn'. */
 static void
-do_send_packet_in(struct ofpbuf *ofp_packet_in, void *ofconn_)
+do_send_packet_ins(struct ofconn *ofconn, struct list *txq)
 {
-    struct ofconn *ofconn = ofconn_;
+    struct ofpbuf *pin, *next_pin;
+
+    LIST_FOR_EACH_SAFE (pin, next_pin, list_node, txq) {
+        list_remove(&pin->list_node);
 
-    rconn_send_with_limit(ofconn->rconn, ofp_packet_in,
-                          ofconn->packet_in_counter, 100);
+        rconn_send_with_limit(ofconn->rconn, pin,
+                              ofconn->packet_in_counter, 100);
+    }
 }
 
 /* Takes 'pin', composes an OpenFlow packet-in message from it, and passes it
@@ -1540,6 +1546,7 @@ schedule_packet_in(struct ofconn *ofconn, struct ofproto_packet_in pin,
 {
     struct connmgr *mgr = ofconn->connmgr;
     uint16_t controller_max_len;
+    struct list txq;
 
     pin.up.total_len = pin.up.packet_len;
 
@@ -1573,15 +1580,14 @@ schedule_packet_in(struct ofconn *ofconn, struct ofproto_packet_in pin,
         pin.up.packet_len = controller_max_len;
     }
 
-    /* Make OFPT_PACKET_IN and hand over to packet scheduler.  It might
-     * immediately call into do_send_packet_in() or it might buffer it for a
-     * while (until a later call to pinsched_run()). */
+    /* Make OFPT_PACKET_IN and hand over to packet scheduler. */
     pinsched_send(ofconn->schedulers[pin.up.reason == OFPR_NO_MATCH ? 0 : 1],
                   pin.up.fmd.in_port,
                   ofputil_encode_packet_in(&pin.up,
                                            ofconn_get_protocol(ofconn),
                                            ofconn->packet_in_format),
-                  do_send_packet_in, ofconn);
+                  &txq);
+    do_send_packet_ins(ofconn, &txq);
 }
 \f
 /* Fail-open settings. */
index 91e9c41..831afef 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -186,15 +186,16 @@ get_token(struct pinsched *ps)
 
 void
 pinsched_send(struct pinsched *ps, ofp_port_t port_no,
-              struct ofpbuf *packet, pinsched_tx_cb *cb, void *aux)
+              struct ofpbuf *packet, struct list *txq)
 {
+    list_init(txq);
     if (!ps) {
-        cb(packet, aux);
+        list_push_back(txq, &packet->list_node);
     } else if (!ps->n_queued && get_token(ps)) {
         /* In the common case where we are not constrained by the rate limit,
          * let the packet take the normal path. */
         ps->n_normal++;
-        cb(packet, aux);
+        list_push_back(txq, &packet->list_node);
     } else {
         /* Otherwise queue it up for the periodic callback to drain out. */
         struct pinqueue *q;
@@ -217,15 +218,17 @@ pinsched_send(struct pinsched *ps, ofp_port_t port_no,
 }
 
 void
-pinsched_run(struct pinsched *ps, pinsched_tx_cb *cb, void *aux)
+pinsched_run(struct pinsched *ps, struct list *txq)
 {
+    list_init(txq);
     if (ps) {
         int i;
 
         /* Drain some packets out of the bucket if possible, but limit the
          * number of iterations to allow other code to get work done too. */
         for (i = 0; ps->n_queued && get_token(ps) && i < 50; i++) {
-            cb(get_tx_packet(ps), aux);
+            struct ofpbuf *packet = get_tx_packet(ps);
+            list_push_back(txq, &packet->list_node);
         }
     }
 }
index 06b22f4..8cce1f2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <stdint.h>
 #include "flow.h"
 
+struct list;
 struct ofpbuf;
 
-typedef void pinsched_tx_cb(struct ofpbuf *, void *aux);
 struct pinsched *pinsched_create(int rate_limit, int burst_limit);
 void pinsched_get_limits(const struct pinsched *,
                          int *rate_limit, int *burst_limit);
 void pinsched_set_limits(struct pinsched *, int rate_limit, int burst_limit);
 void pinsched_destroy(struct pinsched *);
 void pinsched_send(struct pinsched *, ofp_port_t port_no, struct ofpbuf *,
-                   pinsched_tx_cb *, void *aux);
-void pinsched_run(struct pinsched *, pinsched_tx_cb *, void *aux);
+                   struct list *txq);
+void pinsched_run(struct pinsched *, struct list *txq);
 void pinsched_wait(struct pinsched *);
 
 unsigned int pinsched_count_txqlen(const struct pinsched *);