1*84e872a0SLloyd Pique /*
2*84e872a0SLloyd Pique * Copyright © 2008-2011 Kristian Høgsberg
3*84e872a0SLloyd Pique * Copyright © 2011 Intel Corporation
4*84e872a0SLloyd Pique *
5*84e872a0SLloyd Pique * Permission is hereby granted, free of charge, to any person obtaining
6*84e872a0SLloyd Pique * a copy of this software and associated documentation files (the
7*84e872a0SLloyd Pique * "Software"), to deal in the Software without restriction, including
8*84e872a0SLloyd Pique * without limitation the rights to use, copy, modify, merge, publish,
9*84e872a0SLloyd Pique * distribute, sublicense, and/or sell copies of the Software, and to
10*84e872a0SLloyd Pique * permit persons to whom the Software is furnished to do so, subject to
11*84e872a0SLloyd Pique * the following conditions:
12*84e872a0SLloyd Pique *
13*84e872a0SLloyd Pique * The above copyright notice and this permission notice (including the
14*84e872a0SLloyd Pique * next paragraph) shall be included in all copies or substantial
15*84e872a0SLloyd Pique * portions of the Software.
16*84e872a0SLloyd Pique *
17*84e872a0SLloyd Pique * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18*84e872a0SLloyd Pique * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19*84e872a0SLloyd Pique * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20*84e872a0SLloyd Pique * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21*84e872a0SLloyd Pique * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22*84e872a0SLloyd Pique * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23*84e872a0SLloyd Pique * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24*84e872a0SLloyd Pique * SOFTWARE.
25*84e872a0SLloyd Pique */
26*84e872a0SLloyd Pique
27*84e872a0SLloyd Pique #include <errno.h>
28*84e872a0SLloyd Pique #include <stdlib.h>
29*84e872a0SLloyd Pique #include <stdint.h>
30*84e872a0SLloyd Pique #include <stdio.h>
31*84e872a0SLloyd Pique #include <string.h>
32*84e872a0SLloyd Pique #include <stdarg.h>
33*84e872a0SLloyd Pique
34*84e872a0SLloyd Pique #include "wayland-util.h"
35*84e872a0SLloyd Pique #include "wayland-private.h"
36*84e872a0SLloyd Pique
37*84e872a0SLloyd Pique WL_EXPORT void
wl_list_init(struct wl_list * list)38*84e872a0SLloyd Pique wl_list_init(struct wl_list *list)
39*84e872a0SLloyd Pique {
40*84e872a0SLloyd Pique list->prev = list;
41*84e872a0SLloyd Pique list->next = list;
42*84e872a0SLloyd Pique }
43*84e872a0SLloyd Pique
44*84e872a0SLloyd Pique WL_EXPORT void
wl_list_insert(struct wl_list * list,struct wl_list * elm)45*84e872a0SLloyd Pique wl_list_insert(struct wl_list *list, struct wl_list *elm)
46*84e872a0SLloyd Pique {
47*84e872a0SLloyd Pique elm->prev = list;
48*84e872a0SLloyd Pique elm->next = list->next;
49*84e872a0SLloyd Pique list->next = elm;
50*84e872a0SLloyd Pique elm->next->prev = elm;
51*84e872a0SLloyd Pique }
52*84e872a0SLloyd Pique
53*84e872a0SLloyd Pique WL_EXPORT void
wl_list_remove(struct wl_list * elm)54*84e872a0SLloyd Pique wl_list_remove(struct wl_list *elm)
55*84e872a0SLloyd Pique {
56*84e872a0SLloyd Pique elm->prev->next = elm->next;
57*84e872a0SLloyd Pique elm->next->prev = elm->prev;
58*84e872a0SLloyd Pique elm->next = NULL;
59*84e872a0SLloyd Pique elm->prev = NULL;
60*84e872a0SLloyd Pique }
61*84e872a0SLloyd Pique
62*84e872a0SLloyd Pique WL_EXPORT int
wl_list_length(const struct wl_list * list)63*84e872a0SLloyd Pique wl_list_length(const struct wl_list *list)
64*84e872a0SLloyd Pique {
65*84e872a0SLloyd Pique struct wl_list *e;
66*84e872a0SLloyd Pique int count;
67*84e872a0SLloyd Pique
68*84e872a0SLloyd Pique count = 0;
69*84e872a0SLloyd Pique e = list->next;
70*84e872a0SLloyd Pique while (e != list) {
71*84e872a0SLloyd Pique e = e->next;
72*84e872a0SLloyd Pique count++;
73*84e872a0SLloyd Pique }
74*84e872a0SLloyd Pique
75*84e872a0SLloyd Pique return count;
76*84e872a0SLloyd Pique }
77*84e872a0SLloyd Pique
78*84e872a0SLloyd Pique WL_EXPORT int
wl_list_empty(const struct wl_list * list)79*84e872a0SLloyd Pique wl_list_empty(const struct wl_list *list)
80*84e872a0SLloyd Pique {
81*84e872a0SLloyd Pique return list->next == list;
82*84e872a0SLloyd Pique }
83*84e872a0SLloyd Pique
84*84e872a0SLloyd Pique WL_EXPORT void
wl_list_insert_list(struct wl_list * list,struct wl_list * other)85*84e872a0SLloyd Pique wl_list_insert_list(struct wl_list *list, struct wl_list *other)
86*84e872a0SLloyd Pique {
87*84e872a0SLloyd Pique if (wl_list_empty(other))
88*84e872a0SLloyd Pique return;
89*84e872a0SLloyd Pique
90*84e872a0SLloyd Pique other->next->prev = list;
91*84e872a0SLloyd Pique other->prev->next = list->next;
92*84e872a0SLloyd Pique list->next->prev = other->prev;
93*84e872a0SLloyd Pique list->next = other->next;
94*84e872a0SLloyd Pique }
95*84e872a0SLloyd Pique
96*84e872a0SLloyd Pique WL_EXPORT void
wl_array_init(struct wl_array * array)97*84e872a0SLloyd Pique wl_array_init(struct wl_array *array)
98*84e872a0SLloyd Pique {
99*84e872a0SLloyd Pique memset(array, 0, sizeof *array);
100*84e872a0SLloyd Pique }
101*84e872a0SLloyd Pique
102*84e872a0SLloyd Pique WL_EXPORT void
wl_array_release(struct wl_array * array)103*84e872a0SLloyd Pique wl_array_release(struct wl_array *array)
104*84e872a0SLloyd Pique {
105*84e872a0SLloyd Pique free(array->data);
106*84e872a0SLloyd Pique array->data = WL_ARRAY_POISON_PTR;
107*84e872a0SLloyd Pique }
108*84e872a0SLloyd Pique
109*84e872a0SLloyd Pique WL_EXPORT void *
wl_array_add(struct wl_array * array,size_t size)110*84e872a0SLloyd Pique wl_array_add(struct wl_array *array, size_t size)
111*84e872a0SLloyd Pique {
112*84e872a0SLloyd Pique size_t alloc;
113*84e872a0SLloyd Pique void *data, *p;
114*84e872a0SLloyd Pique
115*84e872a0SLloyd Pique if (array->alloc > 0)
116*84e872a0SLloyd Pique alloc = array->alloc;
117*84e872a0SLloyd Pique else
118*84e872a0SLloyd Pique alloc = 16;
119*84e872a0SLloyd Pique
120*84e872a0SLloyd Pique while (alloc < array->size + size)
121*84e872a0SLloyd Pique alloc *= 2;
122*84e872a0SLloyd Pique
123*84e872a0SLloyd Pique if (array->alloc < alloc) {
124*84e872a0SLloyd Pique if (array->alloc > 0)
125*84e872a0SLloyd Pique data = realloc(array->data, alloc);
126*84e872a0SLloyd Pique else
127*84e872a0SLloyd Pique data = malloc(alloc);
128*84e872a0SLloyd Pique
129*84e872a0SLloyd Pique if (data == NULL)
130*84e872a0SLloyd Pique return NULL;
131*84e872a0SLloyd Pique array->data = data;
132*84e872a0SLloyd Pique array->alloc = alloc;
133*84e872a0SLloyd Pique }
134*84e872a0SLloyd Pique
135*84e872a0SLloyd Pique p = (char *)array->data + array->size;
136*84e872a0SLloyd Pique array->size += size;
137*84e872a0SLloyd Pique
138*84e872a0SLloyd Pique return p;
139*84e872a0SLloyd Pique }
140*84e872a0SLloyd Pique
141*84e872a0SLloyd Pique WL_EXPORT int
wl_array_copy(struct wl_array * array,struct wl_array * source)142*84e872a0SLloyd Pique wl_array_copy(struct wl_array *array, struct wl_array *source)
143*84e872a0SLloyd Pique {
144*84e872a0SLloyd Pique if (array->size < source->size) {
145*84e872a0SLloyd Pique if (!wl_array_add(array, source->size - array->size))
146*84e872a0SLloyd Pique return -1;
147*84e872a0SLloyd Pique } else {
148*84e872a0SLloyd Pique array->size = source->size;
149*84e872a0SLloyd Pique }
150*84e872a0SLloyd Pique
151*84e872a0SLloyd Pique if (source->size > 0)
152*84e872a0SLloyd Pique memcpy(array->data, source->data, source->size);
153*84e872a0SLloyd Pique
154*84e872a0SLloyd Pique return 0;
155*84e872a0SLloyd Pique }
156*84e872a0SLloyd Pique
157*84e872a0SLloyd Pique /** \cond */
158*84e872a0SLloyd Pique
159*84e872a0SLloyd Pique int
wl_interface_equal(const struct wl_interface * a,const struct wl_interface * b)160*84e872a0SLloyd Pique wl_interface_equal(const struct wl_interface *a, const struct wl_interface *b)
161*84e872a0SLloyd Pique {
162*84e872a0SLloyd Pique /* In most cases the pointer equality test is sufficient.
163*84e872a0SLloyd Pique * However, in some cases, depending on how things are split
164*84e872a0SLloyd Pique * across shared objects, we can end up with multiple
165*84e872a0SLloyd Pique * instances of the interface metadata constants. So if the
166*84e872a0SLloyd Pique * pointers match, the interfaces are equal, if they don't
167*84e872a0SLloyd Pique * match we have to compare the interface names.
168*84e872a0SLloyd Pique */
169*84e872a0SLloyd Pique return a == b || strcmp(a->name, b->name) == 0;
170*84e872a0SLloyd Pique }
171*84e872a0SLloyd Pique
172*84e872a0SLloyd Pique union map_entry {
173*84e872a0SLloyd Pique uintptr_t next;
174*84e872a0SLloyd Pique void *data;
175*84e872a0SLloyd Pique };
176*84e872a0SLloyd Pique
177*84e872a0SLloyd Pique #define map_entry_is_free(entry) ((entry).next & 0x1)
178*84e872a0SLloyd Pique #define map_entry_get_data(entry) ((void *)((entry).next & ~(uintptr_t)0x3))
179*84e872a0SLloyd Pique #define map_entry_get_flags(entry) (((entry).next >> 1) & 0x1)
180*84e872a0SLloyd Pique
181*84e872a0SLloyd Pique void
wl_map_init(struct wl_map * map,uint32_t side)182*84e872a0SLloyd Pique wl_map_init(struct wl_map *map, uint32_t side)
183*84e872a0SLloyd Pique {
184*84e872a0SLloyd Pique memset(map, 0, sizeof *map);
185*84e872a0SLloyd Pique map->side = side;
186*84e872a0SLloyd Pique }
187*84e872a0SLloyd Pique
188*84e872a0SLloyd Pique void
wl_map_release(struct wl_map * map)189*84e872a0SLloyd Pique wl_map_release(struct wl_map *map)
190*84e872a0SLloyd Pique {
191*84e872a0SLloyd Pique wl_array_release(&map->client_entries);
192*84e872a0SLloyd Pique wl_array_release(&map->server_entries);
193*84e872a0SLloyd Pique }
194*84e872a0SLloyd Pique
195*84e872a0SLloyd Pique uint32_t
wl_map_insert_new(struct wl_map * map,uint32_t flags,void * data)196*84e872a0SLloyd Pique wl_map_insert_new(struct wl_map *map, uint32_t flags, void *data)
197*84e872a0SLloyd Pique {
198*84e872a0SLloyd Pique union map_entry *start, *entry;
199*84e872a0SLloyd Pique struct wl_array *entries;
200*84e872a0SLloyd Pique uint32_t base;
201*84e872a0SLloyd Pique uint32_t count;
202*84e872a0SLloyd Pique
203*84e872a0SLloyd Pique if (map->side == WL_MAP_CLIENT_SIDE) {
204*84e872a0SLloyd Pique entries = &map->client_entries;
205*84e872a0SLloyd Pique base = 0;
206*84e872a0SLloyd Pique } else {
207*84e872a0SLloyd Pique entries = &map->server_entries;
208*84e872a0SLloyd Pique base = WL_SERVER_ID_START;
209*84e872a0SLloyd Pique }
210*84e872a0SLloyd Pique
211*84e872a0SLloyd Pique if (map->free_list) {
212*84e872a0SLloyd Pique start = entries->data;
213*84e872a0SLloyd Pique entry = &start[map->free_list >> 1];
214*84e872a0SLloyd Pique map->free_list = entry->next;
215*84e872a0SLloyd Pique } else {
216*84e872a0SLloyd Pique entry = wl_array_add(entries, sizeof *entry);
217*84e872a0SLloyd Pique if (!entry)
218*84e872a0SLloyd Pique return 0;
219*84e872a0SLloyd Pique start = entries->data;
220*84e872a0SLloyd Pique }
221*84e872a0SLloyd Pique
222*84e872a0SLloyd Pique /* wl_array only grows, so if we have too many objects at
223*84e872a0SLloyd Pique * this point there's no way to clean up. We could be more
224*84e872a0SLloyd Pique * pro-active about trying to avoid this allocation, but
225*84e872a0SLloyd Pique * it doesn't really matter because at this point there is
226*84e872a0SLloyd Pique * nothing to be done but disconnect the client and delete
227*84e872a0SLloyd Pique * the whole array either way.
228*84e872a0SLloyd Pique */
229*84e872a0SLloyd Pique count = entry - start;
230*84e872a0SLloyd Pique if (count > WL_MAP_MAX_OBJECTS) {
231*84e872a0SLloyd Pique /* entry->data is freshly malloced garbage, so we'd
232*84e872a0SLloyd Pique * better make it a NULL so wl_map_for_each doesn't
233*84e872a0SLloyd Pique * dereference it later. */
234*84e872a0SLloyd Pique entry->data = NULL;
235*84e872a0SLloyd Pique errno = ENOSPC;
236*84e872a0SLloyd Pique return 0;
237*84e872a0SLloyd Pique }
238*84e872a0SLloyd Pique entry->data = data;
239*84e872a0SLloyd Pique entry->next |= (flags & 0x1) << 1;
240*84e872a0SLloyd Pique
241*84e872a0SLloyd Pique return count + base;
242*84e872a0SLloyd Pique }
243*84e872a0SLloyd Pique
244*84e872a0SLloyd Pique int
wl_map_insert_at(struct wl_map * map,uint32_t flags,uint32_t i,void * data)245*84e872a0SLloyd Pique wl_map_insert_at(struct wl_map *map, uint32_t flags, uint32_t i, void *data)
246*84e872a0SLloyd Pique {
247*84e872a0SLloyd Pique union map_entry *start;
248*84e872a0SLloyd Pique uint32_t count;
249*84e872a0SLloyd Pique struct wl_array *entries;
250*84e872a0SLloyd Pique
251*84e872a0SLloyd Pique if (i < WL_SERVER_ID_START) {
252*84e872a0SLloyd Pique entries = &map->client_entries;
253*84e872a0SLloyd Pique } else {
254*84e872a0SLloyd Pique entries = &map->server_entries;
255*84e872a0SLloyd Pique i -= WL_SERVER_ID_START;
256*84e872a0SLloyd Pique }
257*84e872a0SLloyd Pique
258*84e872a0SLloyd Pique if (i > WL_MAP_MAX_OBJECTS) {
259*84e872a0SLloyd Pique errno = ENOSPC;
260*84e872a0SLloyd Pique return -1;
261*84e872a0SLloyd Pique }
262*84e872a0SLloyd Pique
263*84e872a0SLloyd Pique count = entries->size / sizeof *start;
264*84e872a0SLloyd Pique if (count < i) {
265*84e872a0SLloyd Pique errno = EINVAL;
266*84e872a0SLloyd Pique return -1;
267*84e872a0SLloyd Pique }
268*84e872a0SLloyd Pique
269*84e872a0SLloyd Pique if (count == i) {
270*84e872a0SLloyd Pique if (!wl_array_add(entries, sizeof *start))
271*84e872a0SLloyd Pique return -1;
272*84e872a0SLloyd Pique }
273*84e872a0SLloyd Pique
274*84e872a0SLloyd Pique start = entries->data;
275*84e872a0SLloyd Pique start[i].data = data;
276*84e872a0SLloyd Pique start[i].next |= (flags & 0x1) << 1;
277*84e872a0SLloyd Pique
278*84e872a0SLloyd Pique return 0;
279*84e872a0SLloyd Pique }
280*84e872a0SLloyd Pique
281*84e872a0SLloyd Pique int
wl_map_reserve_new(struct wl_map * map,uint32_t i)282*84e872a0SLloyd Pique wl_map_reserve_new(struct wl_map *map, uint32_t i)
283*84e872a0SLloyd Pique {
284*84e872a0SLloyd Pique union map_entry *start;
285*84e872a0SLloyd Pique uint32_t count;
286*84e872a0SLloyd Pique struct wl_array *entries;
287*84e872a0SLloyd Pique
288*84e872a0SLloyd Pique if (i < WL_SERVER_ID_START) {
289*84e872a0SLloyd Pique if (map->side == WL_MAP_CLIENT_SIDE) {
290*84e872a0SLloyd Pique errno = EINVAL;
291*84e872a0SLloyd Pique return -1;
292*84e872a0SLloyd Pique }
293*84e872a0SLloyd Pique
294*84e872a0SLloyd Pique entries = &map->client_entries;
295*84e872a0SLloyd Pique } else {
296*84e872a0SLloyd Pique if (map->side == WL_MAP_SERVER_SIDE) {
297*84e872a0SLloyd Pique errno = EINVAL;
298*84e872a0SLloyd Pique return -1;
299*84e872a0SLloyd Pique }
300*84e872a0SLloyd Pique
301*84e872a0SLloyd Pique entries = &map->server_entries;
302*84e872a0SLloyd Pique i -= WL_SERVER_ID_START;
303*84e872a0SLloyd Pique }
304*84e872a0SLloyd Pique
305*84e872a0SLloyd Pique if (i > WL_MAP_MAX_OBJECTS) {
306*84e872a0SLloyd Pique errno = ENOSPC;
307*84e872a0SLloyd Pique return -1;
308*84e872a0SLloyd Pique }
309*84e872a0SLloyd Pique
310*84e872a0SLloyd Pique count = entries->size / sizeof *start;
311*84e872a0SLloyd Pique if (count < i) {
312*84e872a0SLloyd Pique errno = EINVAL;
313*84e872a0SLloyd Pique return -1;
314*84e872a0SLloyd Pique }
315*84e872a0SLloyd Pique
316*84e872a0SLloyd Pique if (count == i) {
317*84e872a0SLloyd Pique if (!wl_array_add(entries, sizeof *start))
318*84e872a0SLloyd Pique return -1;
319*84e872a0SLloyd Pique
320*84e872a0SLloyd Pique start = entries->data;
321*84e872a0SLloyd Pique start[i].data = NULL;
322*84e872a0SLloyd Pique } else {
323*84e872a0SLloyd Pique start = entries->data;
324*84e872a0SLloyd Pique if (start[i].data != NULL) {
325*84e872a0SLloyd Pique errno = EINVAL;
326*84e872a0SLloyd Pique return -1;
327*84e872a0SLloyd Pique }
328*84e872a0SLloyd Pique }
329*84e872a0SLloyd Pique
330*84e872a0SLloyd Pique return 0;
331*84e872a0SLloyd Pique }
332*84e872a0SLloyd Pique
333*84e872a0SLloyd Pique void
wl_map_remove(struct wl_map * map,uint32_t i)334*84e872a0SLloyd Pique wl_map_remove(struct wl_map *map, uint32_t i)
335*84e872a0SLloyd Pique {
336*84e872a0SLloyd Pique union map_entry *start;
337*84e872a0SLloyd Pique struct wl_array *entries;
338*84e872a0SLloyd Pique
339*84e872a0SLloyd Pique if (i < WL_SERVER_ID_START) {
340*84e872a0SLloyd Pique if (map->side == WL_MAP_SERVER_SIDE)
341*84e872a0SLloyd Pique return;
342*84e872a0SLloyd Pique
343*84e872a0SLloyd Pique entries = &map->client_entries;
344*84e872a0SLloyd Pique } else {
345*84e872a0SLloyd Pique if (map->side == WL_MAP_CLIENT_SIDE)
346*84e872a0SLloyd Pique return;
347*84e872a0SLloyd Pique
348*84e872a0SLloyd Pique entries = &map->server_entries;
349*84e872a0SLloyd Pique i -= WL_SERVER_ID_START;
350*84e872a0SLloyd Pique }
351*84e872a0SLloyd Pique
352*84e872a0SLloyd Pique start = entries->data;
353*84e872a0SLloyd Pique start[i].next = map->free_list;
354*84e872a0SLloyd Pique map->free_list = (i << 1) | 1;
355*84e872a0SLloyd Pique }
356*84e872a0SLloyd Pique
357*84e872a0SLloyd Pique void *
wl_map_lookup(struct wl_map * map,uint32_t i)358*84e872a0SLloyd Pique wl_map_lookup(struct wl_map *map, uint32_t i)
359*84e872a0SLloyd Pique {
360*84e872a0SLloyd Pique union map_entry *start;
361*84e872a0SLloyd Pique uint32_t count;
362*84e872a0SLloyd Pique struct wl_array *entries;
363*84e872a0SLloyd Pique
364*84e872a0SLloyd Pique if (i < WL_SERVER_ID_START) {
365*84e872a0SLloyd Pique entries = &map->client_entries;
366*84e872a0SLloyd Pique } else {
367*84e872a0SLloyd Pique entries = &map->server_entries;
368*84e872a0SLloyd Pique i -= WL_SERVER_ID_START;
369*84e872a0SLloyd Pique }
370*84e872a0SLloyd Pique
371*84e872a0SLloyd Pique start = entries->data;
372*84e872a0SLloyd Pique count = entries->size / sizeof *start;
373*84e872a0SLloyd Pique
374*84e872a0SLloyd Pique if (i < count && !map_entry_is_free(start[i]))
375*84e872a0SLloyd Pique return map_entry_get_data(start[i]);
376*84e872a0SLloyd Pique
377*84e872a0SLloyd Pique return NULL;
378*84e872a0SLloyd Pique }
379*84e872a0SLloyd Pique
380*84e872a0SLloyd Pique uint32_t
wl_map_lookup_flags(struct wl_map * map,uint32_t i)381*84e872a0SLloyd Pique wl_map_lookup_flags(struct wl_map *map, uint32_t i)
382*84e872a0SLloyd Pique {
383*84e872a0SLloyd Pique union map_entry *start;
384*84e872a0SLloyd Pique uint32_t count;
385*84e872a0SLloyd Pique struct wl_array *entries;
386*84e872a0SLloyd Pique
387*84e872a0SLloyd Pique if (i < WL_SERVER_ID_START) {
388*84e872a0SLloyd Pique entries = &map->client_entries;
389*84e872a0SLloyd Pique } else {
390*84e872a0SLloyd Pique entries = &map->server_entries;
391*84e872a0SLloyd Pique i -= WL_SERVER_ID_START;
392*84e872a0SLloyd Pique }
393*84e872a0SLloyd Pique
394*84e872a0SLloyd Pique start = entries->data;
395*84e872a0SLloyd Pique count = entries->size / sizeof *start;
396*84e872a0SLloyd Pique
397*84e872a0SLloyd Pique if (i < count && !map_entry_is_free(start[i]))
398*84e872a0SLloyd Pique return map_entry_get_flags(start[i]);
399*84e872a0SLloyd Pique
400*84e872a0SLloyd Pique return 0;
401*84e872a0SLloyd Pique }
402*84e872a0SLloyd Pique
403*84e872a0SLloyd Pique static enum wl_iterator_result
for_each_helper(struct wl_array * entries,wl_iterator_func_t func,void * data)404*84e872a0SLloyd Pique for_each_helper(struct wl_array *entries, wl_iterator_func_t func, void *data)
405*84e872a0SLloyd Pique {
406*84e872a0SLloyd Pique enum wl_iterator_result ret = WL_ITERATOR_CONTINUE;
407*84e872a0SLloyd Pique union map_entry entry, *start;
408*84e872a0SLloyd Pique size_t count;
409*84e872a0SLloyd Pique
410*84e872a0SLloyd Pique start = (union map_entry *) entries->data;
411*84e872a0SLloyd Pique count = entries->size / sizeof(union map_entry);
412*84e872a0SLloyd Pique
413*84e872a0SLloyd Pique for (size_t idx = 0; idx < count; idx++) {
414*84e872a0SLloyd Pique entry = start[idx];
415*84e872a0SLloyd Pique if (entry.data && !map_entry_is_free(entry)) {
416*84e872a0SLloyd Pique ret = func(map_entry_get_data(entry), data, map_entry_get_flags(entry));
417*84e872a0SLloyd Pique if (ret != WL_ITERATOR_CONTINUE)
418*84e872a0SLloyd Pique break;
419*84e872a0SLloyd Pique }
420*84e872a0SLloyd Pique }
421*84e872a0SLloyd Pique
422*84e872a0SLloyd Pique return ret;
423*84e872a0SLloyd Pique }
424*84e872a0SLloyd Pique
425*84e872a0SLloyd Pique void
wl_map_for_each(struct wl_map * map,wl_iterator_func_t func,void * data)426*84e872a0SLloyd Pique wl_map_for_each(struct wl_map *map, wl_iterator_func_t func, void *data)
427*84e872a0SLloyd Pique {
428*84e872a0SLloyd Pique enum wl_iterator_result ret;
429*84e872a0SLloyd Pique
430*84e872a0SLloyd Pique ret = for_each_helper(&map->client_entries, func, data);
431*84e872a0SLloyd Pique if (ret == WL_ITERATOR_CONTINUE)
432*84e872a0SLloyd Pique for_each_helper(&map->server_entries, func, data);
433*84e872a0SLloyd Pique }
434*84e872a0SLloyd Pique
435*84e872a0SLloyd Pique static void
wl_log_stderr_handler(const char * fmt,va_list arg)436*84e872a0SLloyd Pique wl_log_stderr_handler(const char *fmt, va_list arg)
437*84e872a0SLloyd Pique {
438*84e872a0SLloyd Pique vfprintf(stderr, fmt, arg);
439*84e872a0SLloyd Pique }
440*84e872a0SLloyd Pique
441*84e872a0SLloyd Pique wl_log_func_t wl_log_handler = wl_log_stderr_handler;
442*84e872a0SLloyd Pique
443*84e872a0SLloyd Pique void
wl_log(const char * fmt,...)444*84e872a0SLloyd Pique wl_log(const char *fmt, ...)
445*84e872a0SLloyd Pique {
446*84e872a0SLloyd Pique va_list argp;
447*84e872a0SLloyd Pique
448*84e872a0SLloyd Pique va_start(argp, fmt);
449*84e872a0SLloyd Pique wl_log_handler(fmt, argp);
450*84e872a0SLloyd Pique va_end(argp);
451*84e872a0SLloyd Pique }
452*84e872a0SLloyd Pique
453*84e872a0SLloyd Pique void
wl_abort(const char * fmt,...)454*84e872a0SLloyd Pique wl_abort(const char *fmt, ...)
455*84e872a0SLloyd Pique {
456*84e872a0SLloyd Pique va_list argp;
457*84e872a0SLloyd Pique
458*84e872a0SLloyd Pique va_start(argp, fmt);
459*84e872a0SLloyd Pique wl_log_handler(fmt, argp);
460*84e872a0SLloyd Pique va_end(argp);
461*84e872a0SLloyd Pique
462*84e872a0SLloyd Pique abort();
463*84e872a0SLloyd Pique }
464*84e872a0SLloyd Pique
465*84e872a0SLloyd Pique /** \endcond */
466