talloc: Convert error cecking macros into fns talloc-2.0.8
authorSimo Sorce <idra@samba.org>
Fri, 5 Oct 2012 14:32:32 +0000 (10:32 -0400)
committerSimo Sorce <idra@samba.org>
Fri, 5 Oct 2012 21:24:17 +0000 (23:24 +0200)
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

lib/talloc/talloc.c

index afc44b338fa6e833e24145bb2c33945817a32ab0..3e33fc0fad5122e945dfbfb3017cd09834419208 100644 (file)
@@ -222,37 +222,6 @@ static struct {
        TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size); \
 } while (0)
 
        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;
 struct talloc_reference_handle {
        struct talloc_reference_handle *next, *prev;
        void *ptr;
@@ -266,6 +235,10 @@ struct talloc_memlimit {
        size_t cur_size;
 };
 
        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 {
 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;
                }
 
                        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);
        }
 
                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);
 
 
                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;
 
                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)) {
        }
 
        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 */
        }
 
        /* 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;
                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;
                }
                        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;
                        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;
                                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;
        }
 
                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);
 
        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);
 }
 
                                          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);
 _PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size)
 {
        struct talloc_chunk *tc = talloc_chunk_from_ptr(ctx);