core: "clock-jitter" is in milliseconds
[vlc.git] / src / misc / objres.c
blobcac8624e7e298ca3139d8fd31543a80132a681cd
1 /*****************************************************************************
2 * objres.c: vlc_object_t resources
3 *****************************************************************************
4 * Copyright (C) 2017 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 <errno.h>
27 #include <stdlib.h>
28 #include <stddef.h>
29 #include <string.h>
31 #include <vlc_common.h>
33 #include "libvlc.h"
34 #include "variables.h"
36 struct vlc_res
38 struct vlc_res *prev;
39 void (*release)(void *);
40 max_align_t payload[];
43 static struct vlc_res **vlc_obj_res(vlc_object_t *obj)
45 return &vlc_internals(obj)->resources;
48 void *vlc_objres_new(size_t size, void (*release)(void *))
50 if (unlikely(add_overflow(sizeof (struct vlc_res), size, &size)))
52 errno = ENOMEM;
53 return NULL;
56 struct vlc_res *res = malloc(size);
57 if (unlikely(res == NULL))
58 return NULL;
60 res->release = release;
61 return res->payload;
64 void vlc_objres_push(vlc_object_t *obj, void *data)
66 struct vlc_res **restrict pp = vlc_obj_res(obj);
67 struct vlc_res *res = container_of(data, struct vlc_res, payload);
69 res->prev = *pp;
70 *pp = res;
73 static void *vlc_objres_pop(vlc_object_t *obj)
75 struct vlc_res **restrict pp = vlc_obj_res(obj);
76 struct vlc_res *res = *pp;
78 if (res == NULL)
79 return NULL;
80 *pp = res->prev;
81 return res->payload;
84 void vlc_objres_clear(vlc_object_t *obj)
86 void *data;
88 while ((data = vlc_objres_pop(obj)) != NULL)
90 struct vlc_res *res = container_of(data, struct vlc_res, payload);
92 res->release(res->payload);
93 free(res);
97 void vlc_objres_remove(vlc_object_t *obj, void *data,
98 bool (*match)(void *, void *))
100 struct vlc_res **restrict pp = vlc_obj_res(obj);
102 /* With a doubly-linked list, this function could have constant complexity.
103 * But that would require one more pointer per resource.
105 * Any given list should contain a fairly small number of resources,
106 * and in most cases, the resources are destroyed implicitly by
107 * vlc_objres_clear().
109 for (;;)
111 struct vlc_res *res = *pp;
113 assert(res != NULL); /* invalid free? */
115 if (match(res->payload, data))
117 *pp = res->prev;
118 res->release(res->payload);
119 free(res);
120 return;
123 pp = &res->prev;
127 static void dummy_release(void *data)
129 (void) data;
132 static bool ptrcmp(void *a, void *b)
134 return a == b;
137 void *vlc_obj_malloc(vlc_object_t *obj, size_t size)
139 void *ptr = vlc_objres_new(size, dummy_release);
140 if (likely(ptr != NULL))
141 vlc_objres_push(obj, ptr);
142 return ptr;
145 void *vlc_obj_calloc(vlc_object_t *obj, size_t nmemb, size_t size)
147 size_t tabsize;
148 if (unlikely(mul_overflow(nmemb, size, &tabsize)))
150 errno = ENOMEM;
151 return NULL;
154 void *ptr = vlc_obj_malloc(obj, tabsize);
155 if (likely(ptr != NULL))
156 memset(ptr, 0, tabsize);
157 return ptr;
160 static void *vlc_obj_memdup(vlc_object_t *obj, const void *base, size_t len)
162 void *ptr = vlc_obj_malloc(obj, len);
163 if (likely(ptr != NULL))
164 memcpy(ptr, base, len);
165 return ptr;
168 char *vlc_obj_strdup(vlc_object_t *obj, const char *str)
170 return vlc_obj_memdup(obj, str, strlen(str) + 1);
173 void vlc_obj_free(vlc_object_t *obj, void *ptr)
175 vlc_objres_remove(obj, ptr, ptrcmp);