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