Add abstraction of packet queue, and use it in the controller.
[sliver-openvswitch.git] / lib / queue.c
1 /* Copyright (C) 2008 Board of Trustees, Leland Stanford Jr. University.
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to
5  * deal in the Software without restriction, including without limitation the
6  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7  * sell copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19  * IN THE SOFTWARE.
20  */
21
22 #include "queue.h"
23 #include <assert.h>
24 #include "buffer.h"
25
26 static void check_queue(struct queue *q);
27
28 void
29 queue_init(struct queue *q)
30 {
31     q->n = 0;
32     q->head = NULL;
33     q->tail = NULL;
34 }
35
36 void
37 queue_destroy(struct queue *q)
38 {
39     struct buffer *cur, *next;
40     for (cur = q->head; cur != NULL; cur = next) {
41         next = cur->next;
42         buffer_delete(cur);
43     }
44 }
45
46 void
47 queue_clear(struct queue *q)
48 {
49     queue_destroy(q);
50     queue_init(q);
51 }
52
53 void
54 queue_advance_head(struct queue *q, struct buffer *next)
55 {
56     assert(q->n);
57     assert(q->head);
58     q->head = next;
59     if (q->head == NULL) {
60         q->tail = NULL;
61     }
62     q->n--;
63 }
64
65 void
66 queue_push_tail(struct queue *q, struct buffer *b)
67 {
68     check_queue(q);
69
70     b->next = NULL;
71     if (q->n++) {
72         q->tail->next = b;
73     } else {
74         q->head = b;
75     }
76     q->tail = b;
77
78     check_queue(q);
79 }
80
81 static void
82 check_queue(struct queue *q)
83 {
84 #if 0
85     struct buffer *iter;
86     size_t n;
87
88     assert(q->n == 0
89            ? q->head == NULL && q->tail == NULL
90            : q->head != NULL && q->tail != NULL);
91
92     n = 0;
93     for (iter = q->head; iter != NULL; iter = iter->next) {
94         n++;
95         assert((iter->next != NULL) == (iter != q->tail));
96     }
97     assert(n == q->n);
98 #endif
99 }