thread: remove vlc_cond_destroy()
[vlc.git] / src / misc / fifo.c
blob1d060bb091d7fb9ed6493aca383fdf0a5fd76338
1 /*****************************************************************************
2 * fifo.c: FIFO management functions
3 *****************************************************************************
4 * Copyright (C) 2003-2004 VLC authors and VideoLAN
5 * Copyright (C) 2007-2015 RĂ©mi Denis-Courmont
7 * Authors: Laurent Aimar <fenrir@videolan.org>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
28 #include <assert.h>
29 #include <stdlib.h>
31 #include <vlc_common.h>
32 #include <vlc_block.h>
33 #include "libvlc.h"
35 /**
36 * Internal state for block queues
38 struct block_fifo_t
40 vlc_mutex_t lock; /* fifo data lock */
41 vlc_cond_t wait; /**< Wait for data */
43 block_t *p_first;
44 block_t **pp_last;
45 size_t i_depth;
46 size_t i_size;
49 void vlc_fifo_Lock(vlc_fifo_t *fifo)
51 vlc_mutex_lock(&fifo->lock);
54 void vlc_fifo_Unlock(vlc_fifo_t *fifo)
56 vlc_mutex_unlock(&fifo->lock);
59 void vlc_fifo_Signal(vlc_fifo_t *fifo)
61 vlc_cond_signal(&fifo->wait);
64 void vlc_fifo_Wait(vlc_fifo_t *fifo)
66 vlc_fifo_WaitCond(fifo, &fifo->wait);
69 void vlc_fifo_WaitCond(vlc_fifo_t *fifo, vlc_cond_t *condvar)
71 vlc_cond_wait(condvar, &fifo->lock);
74 int vlc_fifo_TimedWaitCond(vlc_fifo_t *fifo, vlc_cond_t *condvar, vlc_tick_t deadline)
76 return vlc_cond_timedwait(condvar, &fifo->lock, deadline);
79 size_t vlc_fifo_GetCount(const vlc_fifo_t *fifo)
81 vlc_mutex_assert(&fifo->lock);
82 return fifo->i_depth;
85 size_t vlc_fifo_GetBytes(const vlc_fifo_t *fifo)
87 vlc_mutex_assert(&fifo->lock);
88 return fifo->i_size;
91 void vlc_fifo_QueueUnlocked(block_fifo_t *fifo, block_t *block)
93 vlc_mutex_assert(&fifo->lock);
94 assert(*(fifo->pp_last) == NULL);
96 *(fifo->pp_last) = block;
98 while (block != NULL)
100 fifo->pp_last = &block->p_next;
101 fifo->i_depth++;
102 fifo->i_size += block->i_buffer;
104 block = block->p_next;
107 vlc_fifo_Signal(fifo);
110 block_t *vlc_fifo_DequeueUnlocked(block_fifo_t *fifo)
112 vlc_mutex_assert(&fifo->lock);
114 block_t *block = fifo->p_first;
116 if (block == NULL)
117 return NULL; /* Nothing to do */
119 fifo->p_first = block->p_next;
120 if (block->p_next == NULL)
121 fifo->pp_last = &fifo->p_first;
122 block->p_next = NULL;
124 assert(fifo->i_depth > 0);
125 fifo->i_depth--;
126 assert(fifo->i_size >= block->i_buffer);
127 fifo->i_size -= block->i_buffer;
129 return block;
132 block_t *vlc_fifo_DequeueAllUnlocked(block_fifo_t *fifo)
134 vlc_mutex_assert(&fifo->lock);
136 block_t *block = fifo->p_first;
138 fifo->p_first = NULL;
139 fifo->pp_last = &fifo->p_first;
140 fifo->i_depth = 0;
141 fifo->i_size = 0;
143 return block;
146 block_fifo_t *block_FifoNew( void )
148 block_fifo_t *p_fifo = malloc( sizeof( block_fifo_t ) );
149 if( !p_fifo )
150 return NULL;
152 vlc_mutex_init( &p_fifo->lock );
153 vlc_cond_init( &p_fifo->wait );
154 p_fifo->p_first = NULL;
155 p_fifo->pp_last = &p_fifo->p_first;
156 p_fifo->i_depth = p_fifo->i_size = 0;
158 return p_fifo;
161 void block_FifoRelease( block_fifo_t *p_fifo )
163 block_ChainRelease( p_fifo->p_first );
164 free( p_fifo );
167 void block_FifoEmpty(block_fifo_t *fifo)
169 block_t *block;
171 vlc_fifo_Lock(fifo);
172 block = vlc_fifo_DequeueAllUnlocked(fifo);
173 vlc_fifo_Unlock(fifo);
174 block_ChainRelease(block);
177 void block_FifoPut(block_fifo_t *fifo, block_t *block)
179 vlc_fifo_Lock(fifo);
180 vlc_fifo_QueueUnlocked(fifo, block);
181 vlc_fifo_Unlock(fifo);
184 block_t *block_FifoGet(block_fifo_t *fifo)
186 block_t *block;
188 vlc_testcancel();
190 vlc_fifo_Lock(fifo);
191 while (vlc_fifo_IsEmpty(fifo))
193 vlc_fifo_CleanupPush(fifo);
194 vlc_fifo_Wait(fifo);
195 vlc_cleanup_pop();
197 block = vlc_fifo_DequeueUnlocked(fifo);
198 vlc_fifo_Unlock(fifo);
200 return block;
203 block_t *block_FifoShow( block_fifo_t *p_fifo )
205 block_t *b;
207 vlc_mutex_lock( &p_fifo->lock );
208 assert(p_fifo->p_first != NULL);
209 b = p_fifo->p_first;
210 vlc_mutex_unlock( &p_fifo->lock );
212 return b;
215 /* FIXME: not (really) thread-safe */
216 size_t block_FifoSize (block_fifo_t *fifo)
218 size_t size;
220 vlc_mutex_lock (&fifo->lock);
221 size = fifo->i_size;
222 vlc_mutex_unlock (&fifo->lock);
223 return size;
226 /* FIXME: not (really) thread-safe */
227 size_t block_FifoCount (block_fifo_t *fifo)
229 size_t depth;
231 vlc_mutex_lock (&fifo->lock);
232 depth = fifo->i_depth;
233 vlc_mutex_unlock (&fifo->lock);
234 return depth;