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
32PA_STATIC_FLIST_DECLARE(entries, 0, pa_xfree);
33
34struct queue_entry {
35    struct queue_entry *next;
36    void *data;
37};
38
39struct pa_queue {
40    struct queue_entry *front, *back;
41    unsigned length;
42};
43
44pa_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
53void 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
68void 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
92void* 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
118int pa_queue_isempty(pa_queue *q) {
119    pa_assert(q);
120
121    return q->length == 0;
122}
123
124unsigned PaQueueGetLen(pa_queue *q)
125{
126    pa_assert(q);
127    return q->length;
128}
129