Line | Count | Source (jump to first uncovered line) |
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 |
6 | | * |
7 | | * Authors: Laurent Aimar <fenrir@videolan.org> |
8 | | * |
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. |
13 | | * |
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. |
18 | | * |
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 | | *****************************************************************************/ |
23 | | |
24 | | #ifdef HAVE_CONFIG_H |
25 | | # include "config.h" |
26 | | #endif |
27 | | |
28 | | #include <assert.h> |
29 | | #include <stdlib.h> |
30 | | |
31 | | #include <vlc_common.h> |
32 | | #include <vlc_block.h> |
33 | | #include "../libvlc.h" |
34 | | |
35 | | /** |
36 | | * Internal state for block queues |
37 | | */ |
38 | | struct vlc_fifo_t |
39 | | { |
40 | | vlc_queue_t q; |
41 | | size_t i_depth; |
42 | | size_t i_size; |
43 | | }; |
44 | | |
45 | | static_assert (offsetof (block_fifo_t, q) == 0, "Problems in <vlc_block.h>"); |
46 | | |
47 | | bool vlc_fifo_Held(const block_fifo_t *fifo) |
48 | 0 | { |
49 | 0 | return vlc_mutex_held(&fifo->q.lock); |
50 | 0 | } |
51 | | |
52 | | size_t vlc_fifo_GetCount(const block_fifo_t *fifo) |
53 | 0 | { |
54 | 0 | vlc_mutex_assert(&fifo->q.lock); |
55 | 0 | return fifo->i_depth; |
56 | 0 | } |
57 | | |
58 | | size_t vlc_fifo_GetBytes(const block_fifo_t *fifo) |
59 | 0 | { |
60 | 0 | vlc_mutex_assert(&fifo->q.lock); |
61 | 0 | return fifo->i_size; |
62 | 0 | } |
63 | | |
64 | | void vlc_fifo_QueueUnlocked(block_fifo_t *fifo, block_t *block) |
65 | 0 | { |
66 | 0 | for (block_t *b = block; b != NULL; b = b->p_next) { |
67 | 0 | fifo->i_depth++; |
68 | 0 | fifo->i_size += b->i_buffer; |
69 | 0 | } |
70 | |
|
71 | 0 | vlc_queue_EnqueueUnlocked(&fifo->q, block); |
72 | 0 | } |
73 | | |
74 | | block_t *vlc_fifo_DequeueUnlocked(block_fifo_t *fifo) |
75 | 0 | { |
76 | 0 | block_t *block = vlc_queue_DequeueUnlocked(&fifo->q); |
77 | |
|
78 | 0 | if (block != NULL) { |
79 | 0 | assert(fifo->i_depth > 0); |
80 | 0 | assert(fifo->i_size >= block->i_buffer); |
81 | 0 | fifo->i_depth--; |
82 | 0 | fifo->i_size -= block->i_buffer; |
83 | 0 | } |
84 | | |
85 | 0 | return block; |
86 | 0 | } |
87 | | |
88 | | block_t *vlc_fifo_DequeueAllUnlocked(block_fifo_t *fifo) |
89 | 0 | { |
90 | 0 | fifo->i_depth = 0; |
91 | 0 | fifo->i_size = 0; |
92 | 0 | return vlc_queue_DequeueAllUnlocked(&fifo->q); |
93 | 0 | } |
94 | | |
95 | | block_fifo_t *vlc_fifo_New( void ) |
96 | 0 | { |
97 | 0 | block_fifo_t *p_fifo = malloc( sizeof( block_fifo_t ) ); |
98 | |
|
99 | 0 | if (likely(p_fifo != NULL)) { |
100 | 0 | vlc_queue_Init(&p_fifo->q, offsetof (block_t, p_next)); |
101 | 0 | p_fifo->i_depth = 0; |
102 | 0 | p_fifo->i_size = 0; |
103 | 0 | } |
104 | |
|
105 | 0 | return p_fifo; |
106 | 0 | } |
107 | | |
108 | | void vlc_fifo_Delete( block_fifo_t *p_fifo ) |
109 | 0 | { |
110 | 0 | vlc_fifo_Empty(p_fifo); |
111 | 0 | free( p_fifo ); |
112 | 0 | } |
113 | | |
114 | | block_t *vlc_fifo_Get(block_fifo_t *fifo) |
115 | 0 | { |
116 | 0 | block_t *block; |
117 | |
|
118 | 0 | vlc_testcancel(); |
119 | |
|
120 | 0 | vlc_fifo_Lock(fifo); |
121 | 0 | while (vlc_fifo_IsEmpty(fifo)) |
122 | 0 | { |
123 | 0 | vlc_fifo_CleanupPush(fifo); |
124 | 0 | vlc_fifo_Wait(fifo); |
125 | 0 | vlc_cleanup_pop(); |
126 | 0 | } |
127 | 0 | block = vlc_fifo_DequeueUnlocked(fifo); |
128 | 0 | vlc_fifo_Unlock(fifo); |
129 | |
|
130 | 0 | return block; |
131 | 0 | } |
132 | | |
133 | | block_t *vlc_fifo_Show( block_fifo_t *p_fifo ) |
134 | 0 | { |
135 | 0 | block_t *b; |
136 | |
|
137 | 0 | vlc_fifo_Lock(p_fifo); |
138 | 0 | assert(p_fifo->q.first != NULL); |
139 | 0 | b = (block_t *)p_fifo->q.first; |
140 | 0 | vlc_fifo_Unlock(p_fifo); |
141 | |
|
142 | 0 | return b; |
143 | 0 | } |