1
mirror of https://github.com/mpv-player/mpv synced 2024-11-03 03:19:24 +01:00

ta: change API; ta_set_parent() and ta_set_destructor() never fail

The previous change ensured that these cannot fail anymore (much like in
original talloc). Change the APIs to not return a success value anymore,
to "cement" this.
This commit is contained in:
wm4 2020-02-23 17:45:05 +01:00
parent f6615f00ee
commit bc3678da65
3 changed files with 22 additions and 45 deletions

30
ta/ta.c
View File

@ -75,19 +75,18 @@ static struct ta_header *get_header(void *ptr)
}
/* Set the parent allocation of ptr. If parent==NULL, remove the parent.
* Setting parent==NULL (with ptr!=NULL) always succeeds, and unsets the
* parent of ptr. Operations ptr==NULL always succeed and do nothing.
* Returns true on success, false on OOM.
* Setting parent==NULL (with ptr!=NULL) unsets the parent of ptr.
* With ptr==NULL, the function does nothing.
*
* Warning: if ta_parent is a direct or indirect child of ptr, things will go
* wrong. The function will apparently succeed, but creates circular
* parent links, which are not allowed.
*/
bool ta_set_parent(void *ptr, void *ta_parent)
void ta_set_parent(void *ptr, void *ta_parent)
{
struct ta_header *ch = get_header(ptr);
if (!ch)
return true;
return;
struct ta_header *new_parent = get_header(ta_parent);
// Unlink from previous parent
if (ch->prev)
@ -114,7 +113,6 @@ bool ta_set_parent(void *ptr, void *ta_parent)
new_parent->child = ch;
ch->parent = new_parent;
}
return true;
}
/* Allocate size bytes of memory. If ta_parent is not NULL, this is used as
@ -132,10 +130,7 @@ void *ta_alloc_size(void *ta_parent, size_t size)
*h = (struct ta_header) {.size = size};
ta_dbg_add(h);
void *ptr = PTR_FROM_HEADER(h);
if (!ta_set_parent(ptr, ta_parent)) {
ta_free(ptr);
return NULL;
}
ta_set_parent(ptr, ta_parent);
return ptr;
}
@ -152,10 +147,7 @@ void *ta_zalloc_size(void *ta_parent, size_t size)
*h = (struct ta_header) {.size = size};
ta_dbg_add(h);
void *ptr = PTR_FROM_HEADER(h);
if (!ta_set_parent(ptr, ta_parent)) {
ta_free(ptr);
return NULL;
}
ta_set_parent(ptr, ta_parent);
return ptr;
}
@ -252,16 +244,12 @@ void ta_free(void *ptr)
* almost anything, but it must not attempt to free or realloc ptr. The
* destructor is run before the allocation's children are freed (also, before
* their destructors are run).
*
* Returns false if ptr==NULL, or on OOM.
*/
bool ta_set_destructor(void *ptr, void (*destructor)(void *))
void ta_set_destructor(void *ptr, void (*destructor)(void *))
{
struct ta_header *h = get_header(ptr);
if (!h)
return false;
h->destructor = destructor;
return true;
if (h)
h->destructor = destructor;
}
#ifdef TA_MEMORY_DEBUGGING

10
ta/ta.h
View File

@ -50,8 +50,8 @@ void *ta_realloc_size(void *ta_parent, void *ptr, size_t size);
size_t ta_get_size(void *ptr);
void ta_free(void *ptr);
void ta_free_children(void *ptr);
bool ta_set_destructor(void *ptr, void (*destructor)(void *));
bool ta_set_parent(void *ptr, void *ta_parent);
void ta_set_destructor(void *ptr, void (*destructor)(void *));
void ta_set_parent(void *ptr, void *ta_parent);
// Utility functions
size_t ta_calc_array_size(size_t element_size, size_t count);
@ -105,8 +105,6 @@ bool ta_vasprintf_append_buffer(char **str, const char *fmt, va_list ap) TA_PRF(
// code.
#define ta_xalloc_size(...) ta_oom_p(ta_alloc_size(__VA_ARGS__))
#define ta_xzalloc_size(...) ta_oom_p(ta_zalloc_size(__VA_ARGS__))
#define ta_xset_destructor(...) ta_oom_b(ta_set_destructor(__VA_ARGS__))
#define ta_xset_parent(...) ta_oom_b(ta_set_parent(__VA_ARGS__))
#define ta_xnew_context(...) ta_oom_p(ta_new_context(__VA_ARGS__))
#define ta_xstrdup_append(...) ta_oom_b(ta_strdup_append(__VA_ARGS__))
#define ta_xstrdup_append_buffer(...) ta_oom_b(ta_strdup_append_buffer(__VA_ARGS__))
@ -127,6 +125,10 @@ bool ta_vasprintf_append_buffer(char **str, const char *fmt, va_list ap) TA_PRF(
#define ta_xnew_array_ptrtype(...) ta_oom_g(ta_new_array_ptrtype(__VA_ARGS__))
#define ta_xdup(...) ta_oom_g(ta_dup(__VA_ARGS__))
// Cannot fail anymore.
#define ta_xset_destructor(...) ta_set_destructor(__VA_ARGS__)
#define ta_xset_parent(...) ta_set_parent(__VA_ARGS__)
#define ta_xsteal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_xsteal_(ta_parent, ptr)
#define ta_xrealloc(ta_parent, ptr, type, count) \
(type *)ta_xrealloc_size(ta_parent, ptr, ta_calc_array_size(sizeof(type), count))

View File

@ -44,21 +44,11 @@ size_t ta_calc_prealloc_elems(size_t nextidx)
return (nextidx + 1) * 2;
}
static void dummy_dtor(void *p){}
/* Create an empty (size 0) TA allocation, which is prepared in a way such that
* using it as parent with ta_set_parent() always succeed. Calling
* ta_set_destructor() on it will always succeed as well.
/* Create an empty (size 0) TA allocation.
*/
void *ta_new_context(void *ta_parent)
{
void *new = ta_alloc_size(ta_parent, 0);
// Force it to allocate an extended header.
if (!ta_set_destructor(new, dummy_dtor)) {
ta_free(new);
new = NULL;
}
return new;
return ta_alloc_size(ta_parent, 0);
}
/* Set parent of ptr to ta_parent, return the ptr.
@ -68,8 +58,7 @@ void *ta_new_context(void *ta_parent)
*/
void *ta_steal_(void *ta_parent, void *ptr)
{
if (!ta_set_parent(ptr, ta_parent))
return NULL;
ta_set_parent(ptr, ta_parent);
return ptr;
}
@ -138,10 +127,7 @@ char *ta_strndup(void *ta_parent, const char *str, size_t n)
return NULL;
char *new = NULL;
strndup_append_at(&new, 0, str, n);
if (!ta_set_parent(new, ta_parent)) {
ta_free(new);
new = NULL;
}
ta_set_parent(new, ta_parent);
return new;
}
@ -229,7 +215,8 @@ char *ta_vasprintf(void *ta_parent, const char *fmt, va_list ap)
{
char *res = NULL;
ta_vasprintf_append_at(&res, 0, fmt, ap);
if (!res || !ta_set_parent(res, ta_parent)) {
ta_set_parent(res, ta_parent);
if (!res) {
ta_free(res);
return NULL;
}
@ -303,7 +290,7 @@ char *ta_oom_s(char *s)
void *ta_xsteal_(void *ta_parent, void *ptr)
{
ta_oom_b(ta_set_parent(ptr, ta_parent));
ta_set_parent(ptr, ta_parent);
return ptr;
}