Git init
[framework/multimedia/pulseaudio.git] / src / pulsecore / queue.c
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, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19   USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdlib.h>
27
28 #include <pulse/xmalloc.h>
29 #include <pulsecore/macro.h>
30 #include <pulsecore/flist.h>
31
32 #include "queue.h"
33
34 PA_STATIC_FLIST_DECLARE(entries, 0, pa_xfree);
35
36 struct queue_entry {
37     struct queue_entry *next;
38     void *data;
39 };
40
41 struct pa_queue {
42     struct queue_entry *front, *back;
43     unsigned length;
44 };
45
46 pa_queue* pa_queue_new(void) {
47     pa_queue *q = pa_xnew(pa_queue, 1);
48
49     q->front = q->back = NULL;
50     q->length = 0;
51
52     return q;
53 }
54
55 void pa_queue_free(pa_queue* q, pa_free2_cb_t free_func, void *userdata) {
56     void *data;
57     pa_assert(q);
58
59     while ((data = pa_queue_pop(q)))
60         if (free_func)
61             free_func(data, userdata);
62
63     pa_assert(!q->front);
64     pa_assert(!q->back);
65     pa_assert(q->length == 0);
66
67     pa_xfree(q);
68 }
69
70 void pa_queue_push(pa_queue *q, void *p) {
71     struct queue_entry *e;
72
73     pa_assert(q);
74     pa_assert(p);
75
76     if (!(e = pa_flist_pop(PA_STATIC_FLIST_GET(entries))))
77         e = pa_xnew(struct queue_entry, 1);
78
79     e->data = p;
80     e->next = NULL;
81
82     if (q->back) {
83         pa_assert(q->front);
84         q->back->next = e;
85     } else {
86         pa_assert(!q->front);
87         q->front = e;
88     }
89
90     q->back = e;
91     q->length++;
92 }
93
94 void* pa_queue_pop(pa_queue *q) {
95     void *p;
96     struct queue_entry *e;
97
98     pa_assert(q);
99
100     if (!(e = q->front))
101         return NULL;
102
103     q->front = e->next;
104
105     if (q->back == e) {
106         pa_assert(!e->next);
107         q->back = NULL;
108     }
109
110     p = e->data;
111
112     if (pa_flist_push(PA_STATIC_FLIST_GET(entries), e) < 0)
113         pa_xfree(e);
114
115     q->length--;
116
117     return p;
118 }
119
120 int pa_queue_isempty(pa_queue *q) {
121     pa_assert(q);
122
123     return q->length == 0;
124 }