mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
talloc: Convert error cecking macros into fns
This will avoid 'surprise returns' and makes the code cleare to readers. These macros were complex enough to warrant a full function anyway not just for readability but also for debuggability. Thanks David for pointing out this issue. Autobuild-User(master): Simo Sorce <idra@samba.org> Autobuild-Date(master): Fri Oct 5 23:24:17 CEST 2012 on sn-devel-104
This commit is contained in:
parent
7d7e33c624
commit
36ea39edf8
@ -222,37 +222,6 @@ static struct {
|
||||
TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size); \
|
||||
} while (0)
|
||||
|
||||
#define TALLOC_MEMLIMIT_CHECK(limit, size) do { \
|
||||
struct talloc_memlimit *l; \
|
||||
for (l = limit; l != NULL; l = l->upper) { \
|
||||
if (l->max_size != 0 && \
|
||||
((l->max_size <= l->cur_size) || \
|
||||
(l->max_size - l->cur_size < TC_HDR_SIZE+size))) { \
|
||||
errno = ENOMEM; \
|
||||
return NULL; \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define TALLOC_MEMLIMIT_UPDATE(limit, o_size, n_size) do { \
|
||||
struct talloc_memlimit *l; \
|
||||
ssize_t d; \
|
||||
if (o_size == 0) { \
|
||||
d = n_size + TC_HDR_SIZE; \
|
||||
} else { \
|
||||
d = n_size - o_size; \
|
||||
} \
|
||||
for (l = limit; l != NULL; l = l->upper) { \
|
||||
ssize_t new_size = l->cur_size + d; \
|
||||
if (new_size < 0) { \
|
||||
talloc_abort("cur_size memlimit counter not correct!"); \
|
||||
errno = EINVAL; \
|
||||
return NULL; \
|
||||
} \
|
||||
l->cur_size = new_size; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
struct talloc_reference_handle {
|
||||
struct talloc_reference_handle *next, *prev;
|
||||
void *ptr;
|
||||
@ -266,6 +235,10 @@ struct talloc_memlimit {
|
||||
size_t cur_size;
|
||||
};
|
||||
|
||||
static bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size);
|
||||
static bool talloc_memlimit_update(struct talloc_memlimit *limit,
|
||||
size_t old_size, size_t new_size);
|
||||
|
||||
typedef int (*talloc_destructor_t)(void *);
|
||||
|
||||
struct talloc_chunk {
|
||||
@ -608,7 +581,10 @@ static inline void *__talloc(const void *context, size_t size)
|
||||
limit = ptc->limit;
|
||||
}
|
||||
|
||||
TALLOC_MEMLIMIT_CHECK(limit, (TC_HDR_SIZE+size));
|
||||
if (!talloc_memlimit_check(limit, (TC_HDR_SIZE+size))) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tc = talloc_alloc_pool(ptc, TC_HDR_SIZE+size);
|
||||
}
|
||||
@ -996,7 +972,11 @@ static void *_talloc_steal_internal(const void *new_ctx, const void *ptr)
|
||||
|
||||
ctx_size = _talloc_total_limit_size(ptr, NULL, NULL);
|
||||
|
||||
TALLOC_MEMLIMIT_UPDATE(tc->limit->upper, ctx_size, 0);
|
||||
if (!talloc_memlimit_update(tc->limit->upper, ctx_size, 0)) {
|
||||
talloc_abort("cur_size memlimit counter not correct!");
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (tc->limit->parent == tc) {
|
||||
tc->limit->upper = NULL;
|
||||
@ -1531,7 +1511,10 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons
|
||||
}
|
||||
|
||||
if (tc->limit && (size - tc->size > 0)) {
|
||||
TALLOC_MEMLIMIT_CHECK(tc->limit, (size - tc->size));
|
||||
if (!talloc_memlimit_check(tc->limit, (size - tc->size))) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* handle realloc inside a talloc_pool */
|
||||
@ -1649,7 +1632,14 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons
|
||||
if (new_chunk_size == old_chunk_size) {
|
||||
TC_UNDEFINE_GROW_CHUNK(tc, size);
|
||||
tc->flags &= ~TALLOC_FLAG_FREE;
|
||||
TALLOC_MEMLIMIT_UPDATE(tc->limit, tc->size, size);
|
||||
if (!talloc_memlimit_update(tc->limit,
|
||||
tc->size, size)) {
|
||||
talloc_abort("cur_size memlimit counter not"
|
||||
" correct!");
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tc->size = size;
|
||||
return ptr;
|
||||
}
|
||||
@ -1665,7 +1655,13 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons
|
||||
if (space_left >= space_needed) {
|
||||
TC_UNDEFINE_GROW_CHUNK(tc, size);
|
||||
tc->flags &= ~TALLOC_FLAG_FREE;
|
||||
TALLOC_MEMLIMIT_UPDATE(tc->limit, tc->size, size);
|
||||
if (!talloc_memlimit_update(tc->limit,
|
||||
tc->size, size)) {
|
||||
talloc_abort("cur_size memlimit "
|
||||
"counter not correct!");
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
tc->size = size;
|
||||
pool_tc->hdr.c.pool = tc_next_chunk(tc);
|
||||
return ptr;
|
||||
@ -1714,7 +1710,11 @@ got_new_ptr:
|
||||
tc->next->prev = tc;
|
||||
}
|
||||
|
||||
TALLOC_MEMLIMIT_UPDATE(tc->limit, tc->size, size);
|
||||
if (!talloc_memlimit_update(tc->limit, tc->size, size)) {
|
||||
talloc_abort("cur_size memlimit counter not correct!");
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
tc->size = size;
|
||||
_talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
|
||||
|
||||
@ -2530,6 +2530,43 @@ static size_t _talloc_total_limit_size(const void *ptr,
|
||||
old_limit, new_limit);
|
||||
}
|
||||
|
||||
static bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size)
|
||||
{
|
||||
struct talloc_memlimit *l;
|
||||
|
||||
for (l = limit; l != NULL; l = l->upper) {
|
||||
if (l->max_size != 0 &&
|
||||
((l->max_size <= l->cur_size) ||
|
||||
(l->max_size - l->cur_size < TC_HDR_SIZE+size))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool talloc_memlimit_update(struct talloc_memlimit *limit,
|
||||
size_t old_size, size_t new_size)
|
||||
{
|
||||
struct talloc_memlimit *l;
|
||||
ssize_t d;
|
||||
|
||||
if (old_size == 0) {
|
||||
d = new_size + TC_HDR_SIZE;
|
||||
} else {
|
||||
d = new_size - old_size;
|
||||
}
|
||||
for (l = limit; l != NULL; l = l->upper) {
|
||||
ssize_t new_cur_size = l->cur_size + d;
|
||||
if (new_cur_size < 0) {
|
||||
return false;
|
||||
}
|
||||
l->cur_size = new_cur_size;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
_PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size)
|
||||
{
|
||||
struct talloc_chunk *tc = talloc_chunk_from_ptr(ctx);
|
||||
|
Loading…
Reference in New Issue
Block a user