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 *****************************************************************************/
31 #include <vlc_common.h>
32 #include <vlc_block.h>
36 * Internal state for block queues
40 vlc_mutex_t lock
; /* fifo data lock */
41 vlc_cond_t wait
; /**< Wait for data */
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
)
84 size_t vlc_fifo_GetBytes(const vlc_fifo_t
*fifo
)
89 void vlc_fifo_QueueUnlocked(block_fifo_t
*fifo
, block_t
*block
)
91 vlc_assert_locked(&fifo
->lock
);
92 assert(*(fifo
->pp_last
) == NULL
);
94 *(fifo
->pp_last
) = block
;
98 fifo
->pp_last
= &block
->p_next
;
100 fifo
->i_size
+= block
->i_buffer
;
102 block
= block
->p_next
;
105 vlc_fifo_Signal(fifo
);
108 block_t
*vlc_fifo_DequeueUnlocked(block_fifo_t
*fifo
)
110 vlc_assert_locked(&fifo
->lock
);
112 block_t
*block
= fifo
->p_first
;
115 return NULL
; /* Nothing to do */
117 fifo
->p_first
= block
->p_next
;
118 if (block
->p_next
== NULL
)
119 fifo
->pp_last
= &fifo
->p_first
;
120 block
->p_next
= NULL
;
122 assert(fifo
->i_depth
> 0);
124 assert(fifo
->i_size
>= block
->i_buffer
);
125 fifo
->i_size
-= block
->i_buffer
;
130 block_t
*vlc_fifo_DequeueAllUnlocked(block_fifo_t
*fifo
)
132 vlc_assert_locked(&fifo
->lock
);
134 block_t
*block
= fifo
->p_first
;
136 fifo
->p_first
= NULL
;
137 fifo
->pp_last
= &fifo
->p_first
;
144 block_fifo_t
*block_FifoNew( void )
146 block_fifo_t
*p_fifo
= malloc( sizeof( block_fifo_t
) );
150 vlc_mutex_init( &p_fifo
->lock
);
151 vlc_cond_init( &p_fifo
->wait
);
152 p_fifo
->p_first
= NULL
;
153 p_fifo
->pp_last
= &p_fifo
->p_first
;
154 p_fifo
->i_depth
= p_fifo
->i_size
= 0;
159 void block_FifoRelease( block_fifo_t
*p_fifo
)
161 block_ChainRelease( p_fifo
->p_first
);
162 vlc_cond_destroy( &p_fifo
->wait
);
163 vlc_mutex_destroy( &p_fifo
->lock
);
167 void block_FifoEmpty(block_fifo_t
*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
)
180 vlc_fifo_QueueUnlocked(fifo
, block
);
181 vlc_fifo_Unlock(fifo
);
184 block_t
*block_FifoGet(block_fifo_t
*fifo
)
191 while (vlc_fifo_IsEmpty(fifo
))
193 vlc_fifo_CleanupPush(fifo
);
197 block
= vlc_fifo_DequeueUnlocked(fifo
);
198 vlc_fifo_Unlock(fifo
);
203 block_t
*block_FifoShow( block_fifo_t
*p_fifo
)
207 vlc_mutex_lock( &p_fifo
->lock
);
208 assert(p_fifo
->p_first
!= NULL
);
210 vlc_mutex_unlock( &p_fifo
->lock
);
215 /* FIXME: not (really) thread-safe */
216 size_t block_FifoSize (block_fifo_t
*fifo
)
220 vlc_mutex_lock (&fifo
->lock
);
222 vlc_mutex_unlock (&fifo
->lock
);
226 /* FIXME: not (really) thread-safe */
227 size_t block_FifoCount (block_fifo_t
*fifo
)
231 vlc_mutex_lock (&fifo
->lock
);
232 depth
= fifo
->i_depth
;
233 vlc_mutex_unlock (&fifo
->lock
);