qml: introduce HorizontalResizehandle
[vlc.git] / src / misc / queue.c
blob2ea374a5c1860d3164800d2489550454309ef2ef
1 /*****************************************************************************
2 * queue.c: generic queue (FIFO)
3 *****************************************************************************
4 * Copyright (C) 2020 RĂ©mi Denis-Courmont
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
25 #include <assert.h>
26 #include <stdint.h>
27 #include <stdlib.h>
29 #include <vlc_common.h>
30 #include <vlc_queue.h>
32 /* Opaque struct type.
34 * ISO C uses the same representation for all pointer-to-struct types.
35 * Still different pointer types are not compatible, i.e. cannot alias.
36 * So use memcpy() to read/write pointer values.
38 struct vlc_queue_entry;
40 static void entry_set(struct vlc_queue_entry **pp, struct vlc_queue_entry *e)
42 memcpy(pp, &e, sizeof (e));
45 static struct vlc_queue_entry *entry_get(struct vlc_queue_entry *const *pp)
47 struct vlc_queue_entry *e;
49 memcpy(&e, pp, sizeof (e));
50 return e;
53 static struct vlc_queue_entry **next_p(const struct vlc_queue_entry *e,
54 ptrdiff_t offset)
56 return (struct vlc_queue_entry **)(((unsigned char *)e) + offset);
59 static void next_set(struct vlc_queue_entry *e, struct vlc_queue_entry *next,
60 ptrdiff_t offset)
62 return entry_set(next_p(e, offset), next);
65 static struct vlc_queue_entry *next_get(const struct vlc_queue_entry *e,
66 ptrdiff_t offset)
68 return entry_get(next_p(e, offset));
71 void vlc_queue_Init(vlc_queue_t *q, ptrdiff_t next_offset)
73 q->first = NULL;
74 q->lastp = &q->first;
75 q->next_offset = next_offset;
76 vlc_mutex_init(&q->lock);
77 vlc_cond_init(&q->wait);
80 void vlc_queue_EnqueueUnlocked(vlc_queue_t *q, void *entry)
82 struct vlc_queue_entry **lastp;
83 const ptrdiff_t offset = q->next_offset;
85 vlc_mutex_assert(&q->lock);
86 assert(entry_get(q->lastp) == NULL);
87 entry_set(q->lastp, entry);
89 for (lastp = q->lastp; entry != NULL; entry = next_get(entry, offset))
90 lastp = next_p(entry, offset);
92 q->lastp = lastp;
93 vlc_queue_Signal(q);
96 void *vlc_queue_DequeueUnlocked(vlc_queue_t *q)
98 vlc_mutex_assert(&q->lock);
100 void *entry = q->first;
101 const ptrdiff_t offset = q->next_offset;
103 if (entry != NULL) {
104 struct vlc_queue_entry *next = next_get(entry, offset);
106 next_set(entry, NULL, offset);
107 q->first = next;
109 if (next == NULL)
110 q->lastp = &q->first;
113 return entry;
116 void *vlc_queue_DequeueAllUnlocked(vlc_queue_t *q)
118 vlc_mutex_assert(&q->lock);
120 void *entry = q->first;
122 q->first = NULL;
123 q->lastp = &q->first;
125 return entry;
128 void vlc_queue_Enqueue(vlc_queue_t *q, void *entry)
130 vlc_queue_Lock(q);
131 vlc_queue_EnqueueUnlocked(q, entry);
132 vlc_queue_Unlock(q);
135 void *vlc_queue_Dequeue(vlc_queue_t *q)
137 void *entry;
139 vlc_queue_Lock(q);
140 vlc_testcancel();
142 while (vlc_queue_IsEmpty(q))
143 vlc_queue_Wait(q);
145 entry = vlc_queue_DequeueUnlocked(q);
146 vlc_queue_Unlock(q);
148 return entry;
151 void *vlc_queue_DequeueAll(vlc_queue_t *q)
153 void *entry;
155 vlc_queue_Lock(q);
156 entry = vlc_queue_DequeueAllUnlocked(q);
157 vlc_queue_Unlock(q);
159 return entry;