1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2008 Lennart Poettering
5
6 PulseAudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of the
9 License, or (at your option) any later version.
10
11 PulseAudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <stdlib.h>
25
26 #include <pulse/xmalloc.h>
27 #include <pulsecore/macro.h>
28 #include <pulsecore/flist.h>
29
30 #include "queue.h"
31
32 PA_STATIC_FLIST_DECLARE(entries, 0, pa_xfree);
33
34 struct queue_entry {
35 struct queue_entry *next;
36 void *data;
37 };
38
39 struct pa_queue {
40 struct queue_entry *front, *back;
41 unsigned length;
42 };
43
pa_queue_new(void)44 pa_queue* pa_queue_new(void) {
45 pa_queue *q = pa_xnew(pa_queue, 1);
46
47 q->front = q->back = NULL;
48 q->length = 0;
49
50 return q;
51 }
52
pa_queue_free(pa_queue * q,pa_free_cb_t free_func)53 void pa_queue_free(pa_queue *q, pa_free_cb_t free_func) {
54 void *data;
55 pa_assert(q);
56
57 while ((data = pa_queue_pop(q)))
58 if (free_func)
59 free_func(data);
60
61 pa_assert(!q->front);
62 pa_assert(!q->back);
63 pa_assert(q->length == 0);
64
65 pa_xfree(q);
66 }
67
pa_queue_push(pa_queue * q,void * p)68 void pa_queue_push(pa_queue *q, void *p) {
69 struct queue_entry *e;
70
71 pa_assert(q);
72 pa_assert(p);
73
74 if (!(e = pa_flist_pop(PA_STATIC_FLIST_GET(entries))))
75 e = pa_xnew(struct queue_entry, 1);
76
77 e->data = p;
78 e->next = NULL;
79
80 if (q->back) {
81 pa_assert(q->front);
82 q->back->next = e;
83 } else {
84 pa_assert(!q->front);
85 q->front = e;
86 }
87
88 q->back = e;
89 q->length++;
90 }
91
pa_queue_pop(pa_queue * q)92 void* pa_queue_pop(pa_queue *q) {
93 void *p;
94 struct queue_entry *e;
95
96 pa_assert(q);
97
98 if (!(e = q->front))
99 return NULL;
100
101 q->front = e->next;
102
103 if (q->back == e) {
104 pa_assert(!e->next);
105 q->back = NULL;
106 }
107
108 p = e->data;
109
110 if (pa_flist_push(PA_STATIC_FLIST_GET(entries), e) < 0)
111 pa_xfree(e);
112
113 q->length--;
114
115 return p;
116 }
117
pa_queue_isempty(pa_queue * q)118 int pa_queue_isempty(pa_queue *q) {
119 pa_assert(q);
120
121 return q->length == 0;
122 }
123