The Samba-Bugzilla – Attachment 10837 Details for
Bug 11144
Memory leak in SMB2 notify handling.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patches for v4-1-test
tmp41.diff.txt (text/plain), 112.51 KB, created by
Stefan Metzmacher
on 2015-03-10 10:53:01 UTC
(
hide
)
Description:
Patches for v4-1-test
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2015-03-10 10:53:01 UTC
Size:
112.51 KB
patch
obsolete
>From d904b6e06704fe449c861bae282a2cb185d68751 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 12:36:23 -0700 >Subject: [PATCH 01/37] Start to fix talloc memlimits with talloc pools. > >Add the functions: > >talloc_memlimit_grow(), talloc_memlimit_shrink(), >talloc_memlimit_update_on_free(). > >as replacements for talloc_memlimit_update(). >The interface to talloc_memlimit_update() is very >hard to understand and use. The above functions >are (to me) much clearer. > >The goal of these changes is to only update >the memlimits on malloc/free/realloc, not >on every pool allocation. That way we only >count pool creation as allocation from any >imposed limits, not allocation from an already >created pool. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit fe790f6cbc9b888a8d613cfb515f0d0c76daad47) >--- > lib/talloc/talloc.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 72 insertions(+) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 76f0aee..067d46f 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -238,6 +238,11 @@ struct talloc_memlimit { > 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); >+static void talloc_memlimit_grow(struct talloc_memlimit *limit, >+ size_t size); >+static void talloc_memlimit_shrink(struct talloc_memlimit *limit, >+ size_t size); >+static void talloc_memlimit_update_on_free(struct talloc_chunk *tc); > > typedef int (*talloc_destructor_t)(void *); > >@@ -2564,6 +2569,73 @@ static bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size) > return true; > } > >+/* >+ Update memory limits when freeing a talloc_chunk. >+*/ >+static void talloc_memlimit_update_on_free(struct talloc_chunk *tc) >+{ >+ if (!tc->limit) { >+ return; >+ } >+ >+ /* >+ * Pool entries don't count. Only the pools >+ * themselves are counted as part of the memory >+ * limits. >+ */ >+ if (tc->flags & TALLOC_FLAG_POOLMEM) { >+ return; >+ } >+ >+ /* >+ * If we are part of a memory limited context hierarchy >+ * we need to subtract the memory used from the counters >+ */ >+ >+ talloc_memlimit_shrink(tc->limit, tc->size+TC_HDR_SIZE); >+ >+ if (tc->limit->parent == tc) { >+ free(tc->limit); >+ } >+ >+ tc->limit = NULL; >+} >+ >+/* >+ Increase memory limit accounting after a malloc/realloc. >+*/ >+static void talloc_memlimit_grow(struct talloc_memlimit *limit, >+ size_t size) >+{ >+ struct talloc_memlimit *l; >+ >+ for (l = limit; l != NULL; l = l->upper) { >+ size_t new_cur_size = l->cur_size + size; >+ if (new_cur_size < l->cur_size) { >+ talloc_abort("logic error in talloc_memlimit_grow\n"); >+ return; >+ } >+ l->cur_size = new_cur_size; >+ } >+} >+ >+/* >+ Decrease memory limit accounting after a free/realloc. >+*/ >+static void talloc_memlimit_shrink(struct talloc_memlimit *limit, >+ size_t size) >+{ >+ struct talloc_memlimit *l; >+ >+ for (l = limit; l != NULL; l = l->upper) { >+ if (l->cur_size < size) { >+ talloc_abort("logic error in talloc_memlimit_shrink\n"); >+ return; >+ } >+ l->cur_size = l->cur_size - size; >+ } >+} >+ > static bool talloc_memlimit_update(struct talloc_memlimit *limit, > size_t old_size, size_t new_size) > { >-- >1.9.1 > > >From 9ca81454177087c3166fae011499f1cc3d036543 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 12:43:50 -0700 >Subject: [PATCH 02/37] Remove magic TC_HDR_SIZE handling inside > talloc_memlimit_check(). > >Callers already account for TC_HDR_SIZE, do not add it twice. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit 7a6beae68ee3f9a97e9e56f4e24a437839fb3e19) >--- > lib/talloc/talloc.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 067d46f..7b827ca 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -2561,7 +2561,7 @@ static bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size) > 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))) { >+ (l->max_size - l->cur_size < size))) { > return false; > } > } >-- >1.9.1 > > >From e684b8993082caaf22cfc5de517219f37af2eadb Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 12:46:09 -0700 >Subject: [PATCH 03/37] Change _talloc_total_mem_internal() to ignore memory > allocated from a pool when calculating limit size. > >We must only count normal tallocs, or a talloc pool itself. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit 4159a78ed7eda340758e22286f16186987a20f2f) >--- > lib/talloc/talloc.c | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 7b827ca..1e25dfd 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -1817,7 +1817,14 @@ static size_t _talloc_total_mem_internal(const void *ptr, > break; > case TOTAL_MEM_LIMIT: > if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) { >- total = tc->size + TC_HDR_SIZE; >+ /* >+ * Don't count memory allocated from a pool >+ * when calculating limits. Only count the >+ * pool itself. >+ */ >+ if (!(tc->flags & TALLOC_FLAG_POOLMEM)) { >+ total = tc->size + TC_HDR_SIZE; >+ } > } > break; > } >-- >1.9.1 > > >From 69e80d924f0d5d2a8842ad34c151242ea7c0639e Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 12:49:00 -0700 >Subject: [PATCH 04/37] Change __talloc() to only call > talloc_memlimit_check()/talloc_memlimit_grow() on actual malloc allocation. > >Don't check the memlimit if the allocation was successful from a pool. We already >checked the memory limit when we created the pool. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit a4ebbe73b4b8dcab4d344e693ad9796ec8997f87) >--- > lib/talloc/talloc.c | 21 +++++++++------------ > 1 file changed, 9 insertions(+), 12 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 1e25dfd..cee7d23 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -586,27 +586,24 @@ static inline void *__talloc(const void *context, size_t size) > limit = ptc->limit; > } > >- if (!talloc_memlimit_check(limit, (TC_HDR_SIZE+size))) { >- errno = ENOMEM; >- return NULL; >- } >- > tc = talloc_alloc_pool(ptc, TC_HDR_SIZE+size); > } > > if (tc == NULL) { >+ /* >+ * Only do the memlimit check/update on actual allocation. >+ */ >+ if (!talloc_memlimit_check(limit, TC_HDR_SIZE + size)) { >+ errno = ENOMEM; >+ return NULL; >+ } >+ > tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size); > if (unlikely(tc == NULL)) return NULL; > tc->flags = TALLOC_MAGIC; > tc->pool = NULL; >- } > >- if (limit != NULL) { >- struct talloc_memlimit *l; >- >- for (l = limit; l != NULL; l = l->upper) { >- l->cur_size += TC_HDR_SIZE+size; >- } >+ talloc_memlimit_grow(limit, TC_HDR_SIZE + size); > } > > tc->limit = limit; >-- >1.9.1 > > >From a96bdd421e18d963aec4f491c9c5d2472281acca Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 12:51:20 -0700 >Subject: [PATCH 05/37] Update memory limits when we call free() on a pool. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit 4dfde7d33e7ac6c94833ecc758baff487ab67e4e) >--- > lib/talloc/talloc.c | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index cee7d23..c45ac93 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -807,6 +807,8 @@ static inline void _talloc_free_poolmem(struct talloc_chunk *tc, > */ > pool->hdr.c.name = location; > >+ talloc_memlimit_update_on_free(&pool->hdr.c); >+ > TC_INVALIDATE_FULL_CHUNK(&pool->hdr.c); > free(pool); > return; >-- >1.9.1 > > >From 5766bd9760dd540814400c91f070236f3d1586ad Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 12:54:38 -0700 >Subject: [PATCH 06/37] Inside _talloc_free_internal(), always call > talloc_memlimit_update_on_free() before we free the real memory. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit 6bc190d6dd7fd0ab028c39c1463477a863f6943a) >--- > lib/talloc/talloc.c | 27 ++++----------------------- > 1 file changed, 4 insertions(+), 23 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index c45ac93..74eca3f 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -909,29 +909,6 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > > tc->flags |= TALLOC_FLAG_FREE; > >- /* >- * If we are part of a memory limited context hierarchy >- * we need to subtract the memory used from the counters >- */ >- if (tc->limit) { >- struct talloc_memlimit *l; >- >- for (l = tc->limit; l != NULL; l = l->upper) { >- if (l->cur_size >= tc->size+TC_HDR_SIZE) { >- l->cur_size -= tc->size+TC_HDR_SIZE; >- } else { >- talloc_abort("cur_size memlimit counter not correct!"); >- return 0; >- } >- } >- >- if (tc->limit->parent == tc) { >- free(tc->limit); >- } >- >- tc->limit = NULL; >- } >- > /* we mark the freed memory with where we called the free > * from. This means on a double free error we can report where > * the first free came from >@@ -952,6 +929,8 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > return 0; > } > >+ talloc_memlimit_update_on_free(tc); >+ > TC_INVALIDATE_FULL_CHUNK(tc); > free(tc); > return 0; >@@ -962,6 +941,8 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > return 0; > } > >+ talloc_memlimit_update_on_free(tc); >+ > TC_INVALIDATE_FULL_CHUNK(tc); > free(tc); > return 0; >-- >1.9.1 > > >From 888df605ac59a66fe8d63a17b005ac8da4512929 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 12:57:43 -0700 >Subject: [PATCH 07/37] In _talloc_steal_internal(), correctly decrement the > memory limit in the source, and increment in the destination. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit 43860293225d14ca2c339277b42f8705322463ab) >--- > lib/talloc/talloc.c | 17 +++++------------ > 1 file changed, 5 insertions(+), 12 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 74eca3f..54f3c0a 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -976,11 +976,8 @@ static void *_talloc_steal_internal(const void *new_ctx, const void *ptr) > > ctx_size = _talloc_total_limit_size(ptr, NULL, NULL); > >- if (!talloc_memlimit_update(tc->limit->upper, ctx_size, 0)) { >- talloc_abort("cur_size memlimit counter not correct!"); >- errno = EINVAL; >- return NULL; >- } >+ /* Decrement the memory limit from the source .. */ >+ talloc_memlimit_shrink(tc->limit->upper, ctx_size); > > if (tc->limit->parent == tc) { > tc->limit->upper = NULL; >@@ -1028,13 +1025,9 @@ static void *_talloc_steal_internal(const void *new_ctx, const void *ptr) > if (tc->limit || new_tc->limit) { > ctx_size = _talloc_total_limit_size(ptr, tc->limit, > new_tc->limit); >- } >- >- if (new_tc->limit) { >- struct talloc_memlimit *l; >- >- for (l = new_tc->limit; l != NULL; l = l->upper) { >- l->cur_size += ctx_size; >+ /* .. and increment it in the destination. */ >+ if (new_tc->limit) { >+ talloc_memlimit_grow(new_tc->limit, ctx_size); > } > } > >-- >1.9.1 > > >From 96817ea2db25010aeb5a78f36a6b832c1ec48b67 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 12:59:04 -0700 >Subject: [PATCH 08/37] Fix a conditional check. (size - tc->size > 0) is > always true if size and tc->size are unsigned. > >Replace with (size > tc->size). > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit 0fbcfcc824e474874c15d7c0b2ea0df408448906) >--- > lib/talloc/talloc.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 54f3c0a..2683ff0 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -1507,7 +1507,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > return NULL; > } > >- if (tc->limit && (size - tc->size > 0)) { >+ if (tc->limit && (size > tc->size)) { > if (!talloc_memlimit_check(tc->limit, (size - tc->size))) { > errno = ENOMEM; > return NULL; >-- >1.9.1 > > >From 14fd63bff0efc5a510d2b77bf4378cf5b8a96cfe Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 13:03:27 -0700 >Subject: [PATCH 09/37] Don't call talloc_memlimit_update() inside > _talloc_realloc() when we're just manipulating pool members. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit 314508dd73105138d756f4ca3dfb65f1d368a9f7) >--- > lib/talloc/talloc.c | 15 --------------- > 1 file changed, 15 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 2683ff0..aabd2fb 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -1629,14 +1629,6 @@ _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 (!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; > } >@@ -1652,13 +1644,6 @@ _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 (!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; >-- >1.9.1 > > >From d2a2a7cb6f08f34bbaad6a434e39248dfcc34fe8 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 13:07:04 -0700 >Subject: [PATCH 10/37] Inside _talloc_realloc(), keep track of size changes > over malloc/realloc/free. > >Replace the last use of talloc_memlimit_update() with talloc_memlimit_grow()/ >talloc_memlimit_shrink(). > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit 8e2a543e088cac36a5b6bbab1a6be961fa00cc4d) >--- > lib/talloc/talloc.c | 19 +++++++++++++++---- > 1 file changed, 15 insertions(+), 4 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index aabd2fb..66ac110 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -1479,6 +1479,8 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > void *new_ptr; > bool malloced = false; > union talloc_pool_chunk *pool_tc = NULL; >+ size_t old_size = 0; >+ size_t new_size = 0; > > /* size zero is equivalent to free() */ > if (unlikely(size == 0)) { >@@ -1566,6 +1568,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > if (new_ptr == NULL) { > new_ptr = malloc(TC_HDR_SIZE+size); > malloced = true; >+ new_size = size; > } > > if (new_ptr) { >@@ -1573,6 +1576,9 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > TC_INVALIDATE_FULL_CHUNK(tc); > } > } else { >+ /* We're doing malloc then free here, so record the difference. */ >+ old_size = tc->size; >+ new_size = size; > new_ptr = malloc(size + TC_HDR_SIZE); > if (new_ptr) { > memcpy(new_ptr, tc, MIN(tc->size, size) + TC_HDR_SIZE); >@@ -1655,6 +1661,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > if (new_ptr == NULL) { > new_ptr = malloc(TC_HDR_SIZE+size); > malloced = true; >+ new_size = size; > } > > if (new_ptr) { >@@ -1664,6 +1671,9 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > } > } > else { >+ /* We're doing realloc here, so record the difference. */ >+ old_size = tc->size; >+ new_size = size; > new_ptr = realloc(tc, size + TC_HDR_SIZE); > } > got_new_ptr: >@@ -1692,11 +1702,12 @@ got_new_ptr: > tc->next->prev = tc; > } > >- if (!talloc_memlimit_update(tc->limit, tc->size, size)) { >- talloc_abort("cur_size memlimit counter not correct!"); >- errno = EINVAL; >- return NULL; >+ if (new_size > old_size) { >+ talloc_memlimit_grow(tc->limit, new_size - old_size); >+ } else if (new_size < old_size) { >+ talloc_memlimit_shrink(tc->limit, old_size - new_size); > } >+ > tc->size = size; > _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name); > >-- >1.9.1 > > >From 3df8fdbe7193322ba8dd996e421ade8841a76fc1 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 13:08:33 -0700 >Subject: [PATCH 11/37] Remove talloc_memlimit_update(). No longer used. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit 3d0f717d437bb24f430fad788b9eb35e8fe8e0e8) >--- > lib/talloc/talloc.c | 24 ------------------------ > 1 file changed, 24 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 66ac110..677ec0f 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -236,8 +236,6 @@ struct talloc_memlimit { > }; > > 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); > static void talloc_memlimit_grow(struct talloc_memlimit *limit, > size_t size); > static void talloc_memlimit_shrink(struct talloc_memlimit *limit, >@@ -2612,28 +2610,6 @@ static void talloc_memlimit_shrink(struct talloc_memlimit *limit, > } > } > >-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); >-- >1.9.1 > > >From 27e4daa7dc6509863068a0d006ea550e44ee2655 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 13:09:03 -0700 >Subject: [PATCH 12/37] Add simple limited pool tests to test_memlimit(). > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Simo Sorce <idra@samba.org> >(cherry picked from commit cbfc3efbfd4a3a6f3b031ce8ef375d37f2c545f3) >--- > lib/talloc/testsuite.c | 27 +++++++++++++++++++++++++++ > 1 file changed, 27 insertions(+) > >diff --git a/lib/talloc/testsuite.c b/lib/talloc/testsuite.c >index d456cbb..426c31a 100644 >--- a/lib/talloc/testsuite.c >+++ b/lib/talloc/testsuite.c >@@ -1359,6 +1359,8 @@ static bool test_memlimit(void) > { > void *root; > char *l1, *l2, *l3, *l4, *l5, *t; >+ char *pool; >+ int i; > > printf("test: memlimit\n# MEMORY LIMITS\n"); > >@@ -1520,6 +1522,31 @@ static bool test_memlimit(void) > talloc_report_full(root, stdout); > talloc_free(root); > >+ /* Test memlimits with pools. */ >+ pool = talloc_pool(NULL, 10*1024); >+ torture_assert("memlimit", pool != NULL, >+ "failed: alloc should not fail due to memory limit\n"); >+ talloc_set_memlimit(pool, 10*1024); >+ for (i = 0; i < 9; i++) { >+ l1 = talloc_size(pool, 1024); >+ torture_assert("memlimit", l1 != NULL, >+ "failed: alloc should not fail due to memory limit\n"); >+ } >+ /* The next alloc should fail. */ >+ l2 = talloc_size(pool, 1024); >+ torture_assert("memlimit", l2 == NULL, >+ "failed: alloc should fail due to memory limit\n"); >+ >+ /* Moving one of the children shouldn't change the limit, >+ as it's still inside the pool. */ >+ root = talloc_new(NULL); >+ talloc_steal(root, l1); >+ l2 = talloc_size(pool, 1024); >+ torture_assert("memlimit", l2 == NULL, >+ "failed: alloc should fail due to memory limit\n"); >+ >+ talloc_free(pool); >+ talloc_free(root); > printf("success: memlimit\n"); > > return true; >-- >1.9.1 > > >From 3b011b2e65c9308ccf0fcae78eb0e4b458f7a420 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 27 Aug 2013 13:20:43 -0700 >Subject: [PATCH 13/37] Fix valgrind errors with memmove and talloc pools. > >bin/smbtorture //127.0.0.1 local.talloc now runs with no valgrind errors. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: "Stefan (metze) Metzmacher" <metze@samba.org> > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Wed Aug 28 02:44:17 CEST 2013 on sn-devel-104 > >(cherry picked from commit 617c647b8ef562ace589a11a15eb460e6db71f2a) >--- > lib/talloc/talloc.c | 21 +++++++++++++++++++++ > 1 file changed, 21 insertions(+) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 677ec0f..69d5a16 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -1609,6 +1609,27 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > size_t old_used = TC_HDR_SIZE + tc->size; > size_t new_used = TC_HDR_SIZE + size; > new_ptr = start; >+ >+#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) >+ { >+ /* >+ * The area from >+ * start -> tc may have >+ * been freed and thus been marked as >+ * VALGRIND_MEM_NOACCESS. Set it to >+ * VALGRIND_MEM_UNDEFINED so we can >+ * copy into it without valgrind errors. >+ * We can't just mark >+ * new_ptr -> new_ptr + old_used >+ * as this may overlap on top of tc, >+ * (which is why we use memmove, not >+ * memcpy below) hence the MIN. >+ */ >+ size_t undef_len = MIN((((char *)tc) - ((char *)new_ptr)),old_used); >+ VALGRIND_MAKE_MEM_UNDEFINED(new_ptr, undef_len); >+ } >+#endif >+ > memmove(new_ptr, tc, old_used); > > tc = (struct talloc_chunk *)new_ptr; >-- >1.9.1 > > >From d474e014f883ad6a46e364ce84a40c13448260a1 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 6 Sep 2013 10:54:43 -0700 >Subject: [PATCH 14/37] talloc: Decouple the dual use of chunk->pool > >If we want nested pools, we will have pools that are pool members. So >we will have to have a separate "next object" pointer for pools. As >we have struct talloc_pool_chunk now, this additional pointer does not >affect normal talloc objects. > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 1334c745e1f2157b66e14f9d8b4f6f7750238717) >--- > lib/talloc/talloc.c | 48 +++++++++++++++++++++++------------------------- > 1 file changed, 23 insertions(+), 25 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 69d5a16..74db284 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -244,6 +244,8 @@ static void talloc_memlimit_update_on_free(struct talloc_chunk *tc); > > typedef int (*talloc_destructor_t)(void *); > >+union talloc_pool_chunk; >+ > struct talloc_chunk { > struct talloc_chunk *next, *prev; > struct talloc_chunk *parent, *child; >@@ -263,17 +265,12 @@ struct talloc_chunk { > struct talloc_memlimit *limit; > > /* >- * "pool" has dual use: >- * >- * For the talloc pool itself (i.e. TALLOC_FLAG_POOL is set), "pool" >- * marks the end of the currently allocated area. >- * >- * For members of the pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool" >+ * For members of a pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool" > * is a pointer to the struct talloc_chunk of the pool that it was > * allocated from. This way children can quickly find the pool to chew > * from. > */ >- void *pool; >+ union talloc_pool_chunk *pool; > }; > > /* 16 byte alignment seems to keep everyone happy */ >@@ -466,6 +463,7 @@ union talloc_pool_chunk { > * on 32-bit platforms. */ > struct tc_pool_hdr { > struct talloc_chunk c; >+ void *next; > unsigned int object_count; > } hdr; > /* This makes it always 16 byte aligned. */ >@@ -479,7 +477,7 @@ static void *tc_pool_end(union talloc_pool_chunk *pool_tc) > > static size_t tc_pool_space_left(union talloc_pool_chunk *pool_tc) > { >- return (char *)tc_pool_end(pool_tc) - (char *)pool_tc->hdr.c.pool; >+ return (char *)tc_pool_end(pool_tc) - (char *)pool_tc->hdr.next; > } > > static void *tc_pool_first_chunk(union talloc_pool_chunk *pool_tc) >@@ -499,11 +497,11 @@ static void tc_invalidate_pool(union talloc_pool_chunk *pool_tc) > size_t flen = tc_pool_space_left(pool_tc); > > if (unlikely(talloc_fill.enabled)) { >- memset(pool_tc->hdr.c.pool, talloc_fill.fill_value, flen); >+ memset(pool_tc->hdr.next, talloc_fill.fill_value, flen); > } > > #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) >- VALGRIND_MAKE_MEM_NOACCESS(pool_tc->hdr.c.pool, flen); >+ VALGRIND_MAKE_MEM_NOACCESS(pool_tc->hdr.next, flen); > #endif > } > >@@ -527,7 +525,7 @@ static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, > pool_ctx = (union talloc_pool_chunk *)parent; > } > else if (parent->flags & TALLOC_FLAG_POOLMEM) { >- pool_ctx = (union talloc_pool_chunk *)parent->pool; >+ pool_ctx = parent->pool; > } > > if (pool_ctx == NULL) { >@@ -545,13 +543,13 @@ static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, > return NULL; > } > >- result = (struct talloc_chunk *)pool_ctx->hdr.c.pool; >+ result = (struct talloc_chunk *)pool_ctx->hdr.next; > > #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) > VALGRIND_MAKE_MEM_UNDEFINED(result, size); > #endif > >- pool_ctx->hdr.c.pool = (void *)((char *)result + chunk_size); >+ pool_ctx->hdr.next = (void *)((char *)result + chunk_size); > > result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM; > result->pool = pool_ctx; >@@ -653,7 +651,7 @@ _PUBLIC_ void *talloc_pool(const void *context, size_t size) > return NULL; > } > pool_tc->hdr.c.flags |= TALLOC_FLAG_POOL; >- pool_tc->hdr.c.pool = tc_pool_first_chunk(pool_tc); >+ pool_tc->hdr.next = tc_pool_first_chunk(pool_tc); > > pool_tc->hdr.object_count = 1; > >@@ -763,7 +761,7 @@ static inline void _talloc_free_poolmem(struct talloc_chunk *tc, > union talloc_pool_chunk *pool; > void *next_tc; > >- pool = (union talloc_pool_chunk *)tc->pool; >+ pool = tc->pool; > next_tc = tc_next_chunk(tc); > > tc->flags |= TALLOC_FLAG_FREE; >@@ -792,7 +790,7 @@ static inline void _talloc_free_poolmem(struct talloc_chunk *tc, > * the rest is available for new objects > * again. > */ >- pool->hdr.c.pool = tc_pool_first_chunk(pool); >+ pool->hdr.next = tc_pool_first_chunk(pool); > tc_invalidate_pool(pool); > return; > } >@@ -812,13 +810,13 @@ static inline void _talloc_free_poolmem(struct talloc_chunk *tc, > return; > } > >- if (pool->hdr.c.pool == next_tc) { >+ if (pool->hdr.next == next_tc) { > /* > * if pool->pool still points to end of > * 'tc' (which is stored in the 'next_tc' variable), > * we can reclaim the memory of 'tc'. > */ >- pool->hdr.c.pool = tc; >+ pool->hdr.next = tc; > return; > } > >@@ -1516,7 +1514,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > > /* handle realloc inside a talloc_pool */ > if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) { >- pool_tc = (union talloc_pool_chunk *)tc->pool; >+ pool_tc = tc->pool; > } > > #if (ALWAYS_REALLOC == 0) >@@ -1526,9 +1524,9 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > void *next_tc = tc_next_chunk(tc); > TC_INVALIDATE_SHRINK_CHUNK(tc, size); > tc->size = size; >- if (next_tc == pool_tc->hdr.c.pool) { >+ if (next_tc == pool_tc->hdr.next) { > /* note: tc->size has changed, so this works */ >- pool_tc->hdr.c.pool = tc_next_chunk(tc); >+ pool_tc->hdr.next = tc_next_chunk(tc); > } > return ptr; > } else if ((tc->size - size) < 1024) { >@@ -1640,11 +1638,11 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > * because we want to invalidate the padding > * too. > */ >- pool_tc->hdr.c.pool = new_used + (char *)new_ptr; >+ pool_tc->hdr.next = new_used + (char *)new_ptr; > tc_invalidate_pool(pool_tc); > > /* now the aligned pointer */ >- pool_tc->hdr.c.pool = new_chunk_size + (char *)new_ptr; >+ pool_tc->hdr.next = new_chunk_size + (char *)new_ptr; > goto got_new_ptr; > } > >@@ -1658,7 +1656,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > return ptr; > } > >- if (next_tc == pool_tc->hdr.c.pool) { >+ if (next_tc == pool_tc->hdr.next) { > /* > * optimize for the case where 'tc' is the last > * chunk in the pool. >@@ -1670,7 +1668,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > TC_UNDEFINE_GROW_CHUNK(tc, size); > tc->flags &= ~TALLOC_FLAG_FREE; > tc->size = size; >- pool_tc->hdr.c.pool = tc_next_chunk(tc); >+ pool_tc->hdr.next = tc_next_chunk(tc); > return ptr; > } > } >-- >1.9.1 > > >From 5bf2a271e58a12a61d7fe01f1b53bbcd43d41bd4 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 6 Sep 2013 12:18:26 -0700 >Subject: [PATCH 15/37] talloc: Introduce __talloc_with_prefix > >This will allow to exchange the extra talloc pool header with the >talloc_chunk structure > >Signed-off-by: Volker Lendecke <vl@samba.org> >Signed-off-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 9887f387a10e94f71790c0c3c7dc5f8cde7e4eb2) >--- > lib/talloc/talloc.c | 32 ++++++++++++++++++++++---------- > 1 file changed, 22 insertions(+), 10 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 74db284..21d675d 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -510,7 +510,7 @@ static void tc_invalidate_pool(union talloc_pool_chunk *pool_tc) > */ > > static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, >- size_t size) >+ size_t size, size_t prefix_len) > { > union talloc_pool_chunk *pool_ctx = NULL; > size_t space_left; >@@ -537,13 +537,14 @@ static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, > /* > * Align size to 16 bytes > */ >- chunk_size = TC_ALIGN16(size); >+ chunk_size = TC_ALIGN16(size + prefix_len); > > if (space_left < chunk_size) { > return NULL; > } > >- result = (struct talloc_chunk *)pool_ctx->hdr.next; >+ result = (struct talloc_chunk *) >+ ((char *)pool_ctx->hdr.next + prefix_len); > > #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) > VALGRIND_MAKE_MEM_UNDEFINED(result, size); >@@ -562,10 +563,12 @@ static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, > /* > Allocate a bit of memory as a child of an existing pointer > */ >-static inline void *__talloc(const void *context, size_t size) >+static inline void *__talloc_with_prefix(const void *context, size_t size, >+ size_t prefix_len) > { > struct talloc_chunk *tc = NULL; > struct talloc_memlimit *limit = NULL; >+ size_t total_len = TC_HDR_SIZE + size + prefix_len; > > if (unlikely(context == NULL)) { > context = null_context; >@@ -575,6 +578,10 @@ static inline void *__talloc(const void *context, size_t size) > return NULL; > } > >+ if (unlikely(total_len < TC_HDR_SIZE)) { >+ return NULL; >+ } >+ > if (context != NULL) { > struct talloc_chunk *ptc = talloc_chunk_from_ptr(context); > >@@ -582,24 +589,24 @@ static inline void *__talloc(const void *context, size_t size) > limit = ptc->limit; > } > >- tc = talloc_alloc_pool(ptc, TC_HDR_SIZE+size); >+ tc = talloc_alloc_pool(ptc, TC_HDR_SIZE+size, prefix_len); > } > > if (tc == NULL) { > /* > * Only do the memlimit check/update on actual allocation. > */ >- if (!talloc_memlimit_check(limit, TC_HDR_SIZE + size)) { >+ if (!talloc_memlimit_check(limit, total_len)) { > errno = ENOMEM; > return NULL; > } > >- tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size); >+ tc = (struct talloc_chunk *)malloc(total_len); > if (unlikely(tc == NULL)) return NULL; > tc->flags = TALLOC_MAGIC; > tc->pool = NULL; > >- talloc_memlimit_grow(limit, TC_HDR_SIZE + size); >+ talloc_memlimit_grow(limit, total_len); > } > > tc->limit = limit; >@@ -629,6 +636,11 @@ static inline void *__talloc(const void *context, size_t size) > return TC_PTR_FROM_CHUNK(tc); > } > >+static inline void *__talloc(const void *context, size_t size) >+{ >+ return __talloc_with_prefix(context, size, 0); >+} >+ > /* > * Create a talloc pool > */ >@@ -1558,7 +1570,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > > #if ALWAYS_REALLOC > if (pool_tc) { >- new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE); >+ new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE, 0); > pool_tc->hdr.object_count--; > > if (new_ptr == NULL) { >@@ -1673,7 +1685,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > } > } > >- new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE); >+ new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE, 0); > > if (new_ptr == NULL) { > new_ptr = malloc(TC_HDR_SIZE+size); >-- >1.9.1 > > >From 63c44d6d79b10861f0f85b80131d73c44390841f Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 6 Sep 2013 14:08:43 -0700 >Subject: [PATCH 16/37] talloc: Put pool-specific data before the chunk > >This is a preparation to make talloc pool real objects themselves. > >Signed-off-by: Volker Lendecke <vl@samba.org> >Signed-off-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit b87c8fd435d1863d6efcec03830ecd85ddfcd7fb) >--- > lib/talloc/talloc.c | 204 ++++++++++++++++++++++++++++++++-------------------- > 1 file changed, 125 insertions(+), 79 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 21d675d..a553050 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -244,7 +244,7 @@ static void talloc_memlimit_update_on_free(struct talloc_chunk *tc); > > typedef int (*talloc_destructor_t)(void *); > >-union talloc_pool_chunk; >+struct talloc_pool_hdr; > > struct talloc_chunk { > struct talloc_chunk *next, *prev; >@@ -270,7 +270,7 @@ struct talloc_chunk { > * allocated from. This way children can quickly find the pool to chew > * from. > */ >- union talloc_pool_chunk *pool; >+ struct talloc_pool_hdr *pool; > }; > > /* 16 byte alignment seems to keep everyone happy */ >@@ -458,31 +458,37 @@ _PUBLIC_ const char *talloc_parent_name(const void *ptr) > memory footprint of each talloc chunk by those 16 bytes. > */ > >-union talloc_pool_chunk { >- /* This lets object_count nestle into 16-byte padding of talloc_chunk, >- * on 32-bit platforms. */ >- struct tc_pool_hdr { >- struct talloc_chunk c; >- void *next; >- unsigned int object_count; >- } hdr; >- /* This makes it always 16 byte aligned. */ >- char pad[TC_ALIGN16(sizeof(struct tc_pool_hdr))]; >+struct talloc_pool_hdr { >+ void *end; >+ unsigned int object_count; > }; > >-static void *tc_pool_end(union talloc_pool_chunk *pool_tc) >+#define TP_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_pool_hdr)) >+ >+static struct talloc_pool_hdr *talloc_pool_from_chunk(struct talloc_chunk *c) >+{ >+ return (struct talloc_pool_hdr *)((char *)c - TP_HDR_SIZE); >+} >+ >+static struct talloc_chunk *talloc_chunk_from_pool(struct talloc_pool_hdr *h) > { >- return (char *)pool_tc + TC_HDR_SIZE + pool_tc->hdr.c.size; >+ return (struct talloc_chunk *)((char *)h + TP_HDR_SIZE); > } > >-static size_t tc_pool_space_left(union talloc_pool_chunk *pool_tc) >+static void *tc_pool_end(struct talloc_pool_hdr *pool_hdr) > { >- return (char *)tc_pool_end(pool_tc) - (char *)pool_tc->hdr.next; >+ struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr); >+ return (char *)tc + TC_HDR_SIZE + tc->size; > } > >-static void *tc_pool_first_chunk(union talloc_pool_chunk *pool_tc) >+static size_t tc_pool_space_left(struct talloc_pool_hdr *pool_hdr) > { >- return pool_tc + 1; >+ return (char *)tc_pool_end(pool_hdr) - (char *)pool_hdr->end; >+} >+ >+static void *tc_pool_first_chunk(struct talloc_pool_hdr *pool_hdr) >+{ >+ return TC_PTR_FROM_CHUNK(talloc_chunk_from_pool(pool_hdr)); > } > > /* If tc is inside a pool, this gives the next neighbour. */ >@@ -492,16 +498,16 @@ static void *tc_next_chunk(struct talloc_chunk *tc) > } > > /* Mark the whole remaining pool as not accessable */ >-static void tc_invalidate_pool(union talloc_pool_chunk *pool_tc) >+static void tc_invalidate_pool(struct talloc_pool_hdr *pool_hdr) > { >- size_t flen = tc_pool_space_left(pool_tc); >+ size_t flen = tc_pool_space_left(pool_hdr); > > if (unlikely(talloc_fill.enabled)) { >- memset(pool_tc->hdr.next, talloc_fill.fill_value, flen); >+ memset(pool_hdr->end, talloc_fill.fill_value, flen); > } > > #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) >- VALGRIND_MAKE_MEM_NOACCESS(pool_tc->hdr.next, flen); >+ VALGRIND_MAKE_MEM_NOACCESS(pool_hdr->end, flen); > #endif > } > >@@ -512,7 +518,7 @@ static void tc_invalidate_pool(union talloc_pool_chunk *pool_tc) > static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, > size_t size, size_t prefix_len) > { >- union talloc_pool_chunk *pool_ctx = NULL; >+ struct talloc_pool_hdr *pool_hdr = NULL; > size_t space_left; > struct talloc_chunk *result; > size_t chunk_size; >@@ -522,17 +528,17 @@ static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, > } > > if (parent->flags & TALLOC_FLAG_POOL) { >- pool_ctx = (union talloc_pool_chunk *)parent; >+ pool_hdr = talloc_pool_from_chunk(parent); > } > else if (parent->flags & TALLOC_FLAG_POOLMEM) { >- pool_ctx = parent->pool; >+ pool_hdr = parent->pool; > } > >- if (pool_ctx == NULL) { >+ if (pool_hdr == NULL) { > return NULL; > } > >- space_left = tc_pool_space_left(pool_ctx); >+ space_left = tc_pool_space_left(pool_hdr); > > /* > * Align size to 16 bytes >@@ -543,19 +549,18 @@ static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, > return NULL; > } > >- result = (struct talloc_chunk *) >- ((char *)pool_ctx->hdr.next + prefix_len); >+ result = (struct talloc_chunk *)((char *)pool_hdr->end + prefix_len); > > #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) >- VALGRIND_MAKE_MEM_UNDEFINED(result, size); >+ VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, chunk_size); > #endif > >- pool_ctx->hdr.next = (void *)((char *)result + chunk_size); >+ pool_hdr->end = (void *)((char *)pool_hdr->end + chunk_size); > > result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM; >- result->pool = pool_ctx; >+ result->pool = pool_hdr; > >- pool_ctx->hdr.object_count++; >+ pool_hdr->object_count++; > > return result; > } >@@ -593,6 +598,8 @@ static inline void *__talloc_with_prefix(const void *context, size_t size, > } > > if (tc == NULL) { >+ char *ptr; >+ > /* > * Only do the memlimit check/update on actual allocation. > */ >@@ -601,8 +608,11 @@ static inline void *__talloc_with_prefix(const void *context, size_t size, > return NULL; > } > >- tc = (struct talloc_chunk *)malloc(total_len); >- if (unlikely(tc == NULL)) return NULL; >+ ptr = malloc(total_len); >+ if (unlikely(ptr == NULL)) { >+ return NULL; >+ } >+ tc = (struct talloc_chunk *)(ptr + prefix_len); > tc->flags = TALLOC_MAGIC; > tc->pool = NULL; > >@@ -647,27 +657,32 @@ static inline void *__talloc(const void *context, size_t size) > > _PUBLIC_ void *talloc_pool(const void *context, size_t size) > { >- union talloc_pool_chunk *pool_tc; >- void *result = __talloc(context, sizeof(*pool_tc) - TC_HDR_SIZE + size); >+ struct talloc_chunk *tc; >+ struct talloc_pool_hdr *pool_hdr; >+ void *result; >+ >+ result = __talloc_with_prefix(context, size, TP_HDR_SIZE); > > if (unlikely(result == NULL)) { > return NULL; > } > >- pool_tc = (union talloc_pool_chunk *)talloc_chunk_from_ptr(result); >- if (unlikely(pool_tc->hdr.c.flags & TALLOC_FLAG_POOLMEM)) { >+ tc = talloc_chunk_from_ptr(result); >+ pool_hdr = talloc_pool_from_chunk(tc); >+ >+ if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) { > /* We don't handle this correctly, so fail. */ > talloc_log("talloc: cannot allocate pool off another pool %s\n", > talloc_get_name(context)); > talloc_free(result); > return NULL; > } >- pool_tc->hdr.c.flags |= TALLOC_FLAG_POOL; >- pool_tc->hdr.next = tc_pool_first_chunk(pool_tc); >+ tc->flags |= TALLOC_FLAG_POOL; > >- pool_tc->hdr.object_count = 1; >+ pool_hdr->object_count = 1; >+ pool_hdr->end = result; > >- tc_invalidate_pool(pool_tc); >+ tc_invalidate_pool(pool_hdr); > > return result; > } >@@ -770,10 +785,12 @@ static void *_talloc_steal_internal(const void *new_ctx, const void *ptr); > static inline void _talloc_free_poolmem(struct talloc_chunk *tc, > const char *location) > { >- union talloc_pool_chunk *pool; >+ struct talloc_pool_hdr *pool; >+ struct talloc_chunk *pool_tc; > void *next_tc; > > pool = tc->pool; >+ pool_tc = talloc_chunk_from_pool(pool); > next_tc = tc_next_chunk(tc); > > tc->flags |= TALLOC_FLAG_FREE; >@@ -786,15 +803,15 @@ static inline void _talloc_free_poolmem(struct talloc_chunk *tc, > > TC_INVALIDATE_FULL_CHUNK(tc); > >- if (unlikely(pool->hdr.object_count == 0)) { >+ if (unlikely(pool->object_count == 0)) { > talloc_abort("Pool object count zero!"); > return; > } > >- pool->hdr.object_count--; >+ pool->object_count--; > >- if (unlikely(pool->hdr.object_count == 1 >- && !(pool->hdr.c.flags & TALLOC_FLAG_FREE))) { >+ if (unlikely(pool->object_count == 1 >+ && !(pool_tc->flags & TALLOC_FLAG_FREE))) { > /* > * if there is just one object left in the pool > * and pool->flags does not have TALLOC_FLAG_FREE, >@@ -802,33 +819,33 @@ static inline void _talloc_free_poolmem(struct talloc_chunk *tc, > * the rest is available for new objects > * again. > */ >- pool->hdr.next = tc_pool_first_chunk(pool); >+ pool->end = tc_pool_first_chunk(pool); > tc_invalidate_pool(pool); > return; > } > >- if (unlikely(pool->hdr.object_count == 0)) { >+ if (unlikely(pool->object_count == 0)) { > /* > * we mark the freed memory with where we called the free > * from. This means on a double free error we can report where > * the first free came from > */ >- pool->hdr.c.name = location; >+ pool_tc->name = location; > >- talloc_memlimit_update_on_free(&pool->hdr.c); >+ talloc_memlimit_update_on_free(pool_tc); > >- TC_INVALIDATE_FULL_CHUNK(&pool->hdr.c); >+ TC_INVALIDATE_FULL_CHUNK(pool_tc); > free(pool); > return; > } > >- if (pool->hdr.next == next_tc) { >+ if (pool->end == next_tc) { > /* > * if pool->pool still points to end of > * 'tc' (which is stored in the 'next_tc' variable), > * we can reclaim the memory of 'tc'. > */ >- pool->hdr.next = tc; >+ pool->end = tc; > return; > } > >@@ -924,23 +941,30 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > tc->name = location; > > if (tc->flags & TALLOC_FLAG_POOL) { >- union talloc_pool_chunk *pool = (union talloc_pool_chunk *)tc; >+ struct talloc_pool_hdr *pool; >+ >+ pool = talloc_pool_from_chunk(tc); > >- if (unlikely(pool->hdr.object_count == 0)) { >+ if (unlikely(pool->object_count == 0)) { > talloc_abort("Pool object count zero!"); > return 0; > } > >- pool->hdr.object_count--; >+ pool->object_count--; > >- if (likely(pool->hdr.object_count != 0)) { >+ if (likely(pool->object_count != 0)) { > return 0; > } > >+ /* >+ * This call takes into account the >+ * prefix TP_HDR_SIZE allocated before >+ * the pool talloc_chunk. >+ */ > talloc_memlimit_update_on_free(tc); > > TC_INVALIDATE_FULL_CHUNK(tc); >- free(tc); >+ free(pool); > return 0; > } > >@@ -1486,7 +1510,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > struct talloc_chunk *tc; > void *new_ptr; > bool malloced = false; >- union talloc_pool_chunk *pool_tc = NULL; >+ struct talloc_pool_hdr *pool_hdr = NULL; > size_t old_size = 0; > size_t new_size = 0; > >@@ -1526,19 +1550,19 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > > /* handle realloc inside a talloc_pool */ > if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) { >- pool_tc = tc->pool; >+ pool_hdr = tc->pool; > } > > #if (ALWAYS_REALLOC == 0) > /* don't shrink if we have less than 1k to gain */ > if (size < tc->size && tc->limit == NULL) { >- if (pool_tc) { >+ if (pool_hdr) { > void *next_tc = tc_next_chunk(tc); > TC_INVALIDATE_SHRINK_CHUNK(tc, size); > tc->size = size; >- if (next_tc == pool_tc->hdr.next) { >+ if (next_tc == pool_hdr->end) { > /* note: tc->size has changed, so this works */ >- pool_tc->hdr.next = tc_next_chunk(tc); >+ pool_hdr->end = tc_next_chunk(tc); > } > return ptr; > } else if ((tc->size - size) < 1024) { >@@ -1569,9 +1593,9 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > tc->flags |= TALLOC_FLAG_FREE; > > #if ALWAYS_REALLOC >- if (pool_tc) { >+ if (pool_hdr) { > new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE, 0); >- pool_tc->hdr.object_count--; >+ pool_hdr->object_count--; > > if (new_ptr == NULL) { > new_ptr = malloc(TC_HDR_SIZE+size); >@@ -1594,15 +1618,17 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > } > } > #else >- if (pool_tc) { >+ if (pool_hdr) { >+ struct talloc_chunk *pool_tc; > void *next_tc = tc_next_chunk(tc); > size_t old_chunk_size = TC_ALIGN16(TC_HDR_SIZE + tc->size); > size_t new_chunk_size = TC_ALIGN16(TC_HDR_SIZE + size); > size_t space_needed; > size_t space_left; >- unsigned int chunk_count = pool_tc->hdr.object_count; >+ unsigned int chunk_count = pool_hdr->object_count; > >- if (!(pool_tc->hdr.c.flags & TALLOC_FLAG_FREE)) { >+ pool_tc = talloc_chunk_from_pool(pool_hdr); >+ if (!(pool_tc->flags & TALLOC_FLAG_FREE)) { > chunk_count -= 1; > } > >@@ -1611,9 +1637,9 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > * optimize for the case where 'tc' is the only > * chunk in the pool. > */ >- char *start = tc_pool_first_chunk(pool_tc); >+ char *start = tc_pool_first_chunk(pool_hdr); > space_needed = new_chunk_size; >- space_left = (char *)tc_pool_end(pool_tc) - start; >+ space_left = (char *)tc_pool_end(pool_hdr) - start; > > if (space_left >= space_needed) { > size_t old_used = TC_HDR_SIZE + tc->size; >@@ -1650,11 +1676,11 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > * because we want to invalidate the padding > * too. > */ >- pool_tc->hdr.next = new_used + (char *)new_ptr; >- tc_invalidate_pool(pool_tc); >+ pool_hdr->end = new_used + (char *)new_ptr; >+ tc_invalidate_pool(pool_hdr); > > /* now the aligned pointer */ >- pool_tc->hdr.next = new_chunk_size + (char *)new_ptr; >+ pool_hdr->end = new_chunk_size + (char *)new_ptr; > goto got_new_ptr; > } > >@@ -1668,19 +1694,19 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons > return ptr; > } > >- if (next_tc == pool_tc->hdr.next) { >+ if (next_tc == pool_hdr->end) { > /* > * optimize for the case where 'tc' is the last > * chunk in the pool. > */ > space_needed = new_chunk_size - old_chunk_size; >- space_left = tc_pool_space_left(pool_tc); >+ space_left = tc_pool_space_left(pool_hdr); > > if (space_left >= space_needed) { > TC_UNDEFINE_GROW_CHUNK(tc, size); > tc->flags &= ~TALLOC_FLAG_FREE; > tc->size = size; >- pool_tc->hdr.next = tc_next_chunk(tc); >+ pool_hdr->end = tc_next_chunk(tc); > return ptr; > } > } >@@ -1822,6 +1848,13 @@ static size_t _talloc_total_mem_internal(const void *ptr, > */ > if (!(tc->flags & TALLOC_FLAG_POOLMEM)) { > total = tc->size + TC_HDR_SIZE; >+ /* >+ * If this is a pool, remember to >+ * add the prefix length. >+ */ >+ if (tc->flags & TALLOC_FLAG_POOL) { >+ total += TP_HDR_SIZE; >+ } > } > } > break; >@@ -2579,6 +2612,8 @@ static bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size) > */ > static void talloc_memlimit_update_on_free(struct talloc_chunk *tc) > { >+ size_t limit_shrink_size; >+ > if (!tc->limit) { > return; > } >@@ -2597,7 +2632,18 @@ static void talloc_memlimit_update_on_free(struct talloc_chunk *tc) > * we need to subtract the memory used from the counters > */ > >- talloc_memlimit_shrink(tc->limit, tc->size+TC_HDR_SIZE); >+ limit_shrink_size = tc->size+TC_HDR_SIZE; >+ >+ /* >+ * If we're deallocating a pool, take into >+ * account the prefix size added for the pool. >+ */ >+ >+ if (tc->flags & TALLOC_FLAG_POOL) { >+ limit_shrink_size += TP_HDR_SIZE; >+ } >+ >+ talloc_memlimit_shrink(tc->limit, limit_shrink_size); > > if (tc->limit->parent == tc) { > free(tc->limit); >-- >1.9.1 > > >From 5f85abbca1bcf28e575a4057363d6ea2775712a2 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 6 Sep 2013 14:20:20 -0700 >Subject: [PATCH 17/37] talloc: Add a separate pool size > >This is necessary to allow talloc pools to be objects on their own. It >is an incompatible change in the sense that talloc_get_size(pool) now >returns 0 instead of the pool size. When the talloc_pooled_object() >call is added, this will start to make sense again. > >Maybe we should add a talloc_pool_size call? Or is that overkill? > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit a3d9099d9a96b36df21ee0733adc5210438fe9dc) >--- > lib/talloc/talloc.c | 35 +++++++++++++++++++++++------------ > 1 file changed, 23 insertions(+), 12 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index a553050..5d13567 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -461,6 +461,7 @@ _PUBLIC_ const char *talloc_parent_name(const void *ptr) > struct talloc_pool_hdr { > void *end; > unsigned int object_count; >+ size_t poolsize; > }; > > #define TP_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_pool_hdr)) >@@ -478,7 +479,7 @@ static struct talloc_chunk *talloc_chunk_from_pool(struct talloc_pool_hdr *h) > static void *tc_pool_end(struct talloc_pool_hdr *pool_hdr) > { > struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr); >- return (char *)tc + TC_HDR_SIZE + tc->size; >+ return (char *)tc + TC_HDR_SIZE + pool_hdr->poolsize; > } > > static size_t tc_pool_space_left(struct talloc_pool_hdr *pool_hdr) >@@ -486,17 +487,18 @@ static size_t tc_pool_space_left(struct talloc_pool_hdr *pool_hdr) > return (char *)tc_pool_end(pool_hdr) - (char *)pool_hdr->end; > } > >-static void *tc_pool_first_chunk(struct talloc_pool_hdr *pool_hdr) >-{ >- return TC_PTR_FROM_CHUNK(talloc_chunk_from_pool(pool_hdr)); >-} >- > /* If tc is inside a pool, this gives the next neighbour. */ > static void *tc_next_chunk(struct talloc_chunk *tc) > { > return (char *)tc + TC_ALIGN16(TC_HDR_SIZE + tc->size); > } > >+static void *tc_pool_first_chunk(struct talloc_pool_hdr *pool_hdr) >+{ >+ struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr); >+ return tc_next_chunk(tc); >+} >+ > /* Mark the whole remaining pool as not accessable */ > static void tc_invalidate_pool(struct talloc_pool_hdr *pool_hdr) > { >@@ -678,9 +680,11 @@ _PUBLIC_ void *talloc_pool(const void *context, size_t size) > return NULL; > } > tc->flags |= TALLOC_FLAG_POOL; >+ tc->size = 0; > > pool_hdr->object_count = 1; > pool_hdr->end = result; >+ pool_hdr->poolsize = size; > > tc_invalidate_pool(pool_hdr); > >@@ -1847,13 +1851,20 @@ static size_t _talloc_total_mem_internal(const void *ptr, > * pool itself. > */ > if (!(tc->flags & TALLOC_FLAG_POOLMEM)) { >- total = tc->size + TC_HDR_SIZE; >- /* >- * If this is a pool, remember to >- * add the prefix length. >- */ > if (tc->flags & TALLOC_FLAG_POOL) { >- total += TP_HDR_SIZE; >+ /* >+ * If this is a pool, the allocated >+ * size is in the pool header, and >+ * remember to add in the prefix >+ * length. >+ */ >+ struct talloc_pool_hdr *pool_hdr >+ = talloc_pool_from_chunk(tc); >+ total = pool_hdr->poolsize + >+ TC_HDR_SIZE + >+ TP_HDR_SIZE; >+ } else { >+ total = tc->size + TC_HDR_SIZE; > } > } > } >-- >1.9.1 > > >From fa19e66294a2c5c2c4cb443c4a886429ab30d0df Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 6 Sep 2013 14:52:28 -0700 >Subject: [PATCH 18/37] talloc: Allow nested pools. > >Signed-off-by: Volker Lendecke <vl@samba.org> >Signed-off-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 20ad6d7aa3dc5e7db4d886202f757ac1f68287d4) >--- > lib/talloc/talloc.c | 47 +++++++++++++++++++++++++---------------------- > lib/talloc/talloc.h | 3 +-- > lib/talloc/testsuite.c | 26 ++++++++++++++++++++++++++ > 3 files changed, 52 insertions(+), 24 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 5d13567..198bab9 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -672,13 +672,6 @@ _PUBLIC_ void *talloc_pool(const void *context, size_t size) > tc = talloc_chunk_from_ptr(result); > pool_hdr = talloc_pool_from_chunk(tc); > >- if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) { >- /* We don't handle this correctly, so fail. */ >- talloc_log("talloc: cannot allocate pool off another pool %s\n", >- talloc_get_name(context)); >- talloc_free(result); >- return NULL; >- } > tc->flags |= TALLOC_FLAG_POOL; > tc->size = 0; > >@@ -836,10 +829,19 @@ static inline void _talloc_free_poolmem(struct talloc_chunk *tc, > */ > pool_tc->name = location; > >- talloc_memlimit_update_on_free(pool_tc); >- >- TC_INVALIDATE_FULL_CHUNK(pool_tc); >- free(pool); >+ if (pool_tc->flags & TALLOC_FLAG_POOLMEM) { >+ _talloc_free_poolmem(pool_tc, location); >+ } else { >+ /* >+ * The talloc_memlimit_update_on_free() >+ * call takes into account the >+ * prefix TP_HDR_SIZE allocated before >+ * the pool talloc_chunk. >+ */ >+ talloc_memlimit_update_on_free(pool_tc); >+ TC_INVALIDATE_FULL_CHUNK(pool_tc); >+ free(pool); >+ } > return; > } > >@@ -869,6 +871,7 @@ static inline void _talloc_free_children_internal(struct talloc_chunk *tc, > static inline int _talloc_free_internal(void *ptr, const char *location) > { > struct talloc_chunk *tc; >+ void *ptr_to_free; > > if (unlikely(ptr == NULL)) { > return -1; >@@ -961,15 +964,13 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > } > > /* >- * This call takes into account the >- * prefix TP_HDR_SIZE allocated before >- * the pool talloc_chunk. >- */ >- talloc_memlimit_update_on_free(tc); >- >- TC_INVALIDATE_FULL_CHUNK(tc); >- free(pool); >- return 0; >+ * With object_count==0, a pool becomes a normal piece of >+ * memory to free. If it's allocated inside a pool, it needs >+ * to be freed as poolmem, else it needs to be just freed. >+ */ >+ ptr_to_free = pool; >+ } else { >+ ptr_to_free = tc; > } > > if (tc->flags & TALLOC_FLAG_POOLMEM) { >@@ -980,7 +981,7 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > talloc_memlimit_update_on_free(tc); > > TC_INVALIDATE_FULL_CHUNK(tc); >- free(tc); >+ free(ptr_to_free); > return 0; > } > >@@ -2632,7 +2633,9 @@ static void talloc_memlimit_update_on_free(struct talloc_chunk *tc) > /* > * Pool entries don't count. Only the pools > * themselves are counted as part of the memory >- * limits. >+ * limits. Note that this also takes care of >+ * nested pools which have both flags >+ * TALLOC_FLAG_POOLMEM|TALLOC_FLAG_POOL set. > */ > if (tc->flags & TALLOC_FLAG_POOLMEM) { > return; >diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h >index f3cbcd0..aa9864b 100644 >--- a/lib/talloc/talloc.h >+++ b/lib/talloc/talloc.h >@@ -839,8 +839,7 @@ void *talloc_find_parent_bytype(const void *ptr, #type); > * talloc pool to a talloc parent outside the pool, the whole pool memory is > * not free(3)'ed until that moved chunk is also talloc_free()ed. > * >- * @param[in] context The talloc context to hang the result off (must not >- * be another pool). >+ * @param[in] context The talloc context to hang the result off. > * > * @param[in] size Size of the talloc pool. > * >diff --git a/lib/talloc/testsuite.c b/lib/talloc/testsuite.c >index 426c31a..f04f4f1 100644 >--- a/lib/talloc/testsuite.c >+++ b/lib/talloc/testsuite.c >@@ -1267,6 +1267,30 @@ static bool test_pool_steal(void) > return true; > } > >+static bool test_pool_nest(void) >+{ >+ void *p1, *p2, *p3; >+ void *e = talloc_new(NULL); >+ >+ p1 = talloc_pool(NULL, 1024); >+ torture_assert("talloc_pool", p1 != NULL, "failed"); >+ >+ p2 = talloc_pool(p1, 500); >+ torture_assert("talloc_pool", p2 != NULL, "failed"); >+ >+ p3 = talloc_size(p2, 10); >+ >+ talloc_steal(e, p3); >+ >+ talloc_free(p2); >+ >+ talloc_free(p3); >+ >+ talloc_free(p1); >+ >+ return true; >+} >+ > static bool test_free_ref_null_context(void) > { > void *p1, *p2, *p3; >@@ -1567,6 +1591,8 @@ bool torture_local_talloc(struct torture_context *tctx) > setlinebuf(stdout); > > test_reset(); >+ ret &= test_pool_nest(); >+ test_reset(); > ret &= test_ref1(); > test_reset(); > ret &= test_ref2(); >-- >1.9.1 > > >From 85331e2af211fd40e178ec231150c93be4d3b7b7 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 6 Sep 2013 15:15:32 -0700 >Subject: [PATCH 19/37] talloc: Add talloc_pooled_object > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit e82320e5197bcdd0330bc829c0963ad09854a36c) >--- > lib/talloc/ABI/pytalloc-util-2.1.0.sigs | 6 +++ > lib/talloc/ABI/talloc-2.1.0.sigs | 64 ++++++++++++++++++++++++++++++++ > lib/talloc/talloc.c | 66 +++++++++++++++++++++++++++++++++ > lib/talloc/talloc.h | 37 ++++++++++++++++++ > lib/talloc/wscript | 2 +- > 5 files changed, 174 insertions(+), 1 deletion(-) > create mode 100644 lib/talloc/ABI/pytalloc-util-2.1.0.sigs > create mode 100644 lib/talloc/ABI/talloc-2.1.0.sigs > >diff --git a/lib/talloc/ABI/pytalloc-util-2.1.0.sigs b/lib/talloc/ABI/pytalloc-util-2.1.0.sigs >new file mode 100644 >index 0000000..961c1a8 >--- /dev/null >+++ b/lib/talloc/ABI/pytalloc-util-2.1.0.sigs >@@ -0,0 +1,6 @@ >+pytalloc_CObject_FromTallocPtr: PyObject *(void *) >+pytalloc_Check: int (PyObject *) >+pytalloc_GetObjectType: PyTypeObject *(void) >+pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) >+pytalloc_steal: PyObject *(PyTypeObject *, void *) >+pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) >diff --git a/lib/talloc/ABI/talloc-2.1.0.sigs b/lib/talloc/ABI/talloc-2.1.0.sigs >new file mode 100644 >index 0000000..eae12cc >--- /dev/null >+++ b/lib/talloc/ABI/talloc-2.1.0.sigs >@@ -0,0 +1,64 @@ >+_talloc: void *(const void *, size_t) >+_talloc_array: void *(const void *, size_t, unsigned int, const char *) >+_talloc_free: int (void *, const char *) >+_talloc_get_type_abort: void *(const void *, const char *, const char *) >+_talloc_memdup: void *(const void *, const void *, size_t, const char *) >+_talloc_move: void *(const void *, const void *) >+_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) >+_talloc_realloc: void *(const void *, void *, size_t, const char *) >+_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) >+_talloc_reference_loc: void *(const void *, const void *, const char *) >+_talloc_set_destructor: void (const void *, int (*)(void *)) >+_talloc_steal_loc: void *(const void *, const void *, const char *) >+_talloc_zero: void *(const void *, size_t, const char *) >+_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) >+talloc_asprintf: char *(const void *, const char *, ...) >+talloc_asprintf_append: char *(char *, const char *, ...) >+talloc_asprintf_append_buffer: char *(char *, const char *, ...) >+talloc_autofree_context: void *(void) >+talloc_check_name: void *(const void *, const char *) >+talloc_disable_null_tracking: void (void) >+talloc_enable_leak_report: void (void) >+talloc_enable_leak_report_full: void (void) >+talloc_enable_null_tracking: void (void) >+talloc_enable_null_tracking_no_autofree: void (void) >+talloc_find_parent_byname: void *(const void *, const char *) >+talloc_free_children: void (void *) >+talloc_get_name: const char *(const void *) >+talloc_get_size: size_t (const void *) >+talloc_increase_ref_count: int (const void *) >+talloc_init: void *(const char *, ...) >+talloc_is_parent: int (const void *, const void *) >+talloc_named: void *(const void *, size_t, const char *, ...) >+talloc_named_const: void *(const void *, size_t, const char *) >+talloc_parent: void *(const void *) >+talloc_parent_name: const char *(const void *) >+talloc_pool: void *(const void *, size_t) >+talloc_realloc_fn: void *(const void *, void *, size_t) >+talloc_reference_count: size_t (const void *) >+talloc_reparent: void *(const void *, const void *, const void *) >+talloc_report: void (const void *, FILE *) >+talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) >+talloc_report_depth_file: void (const void *, int, int, FILE *) >+talloc_report_full: void (const void *, FILE *) >+talloc_set_abort_fn: void (void (*)(const char *)) >+talloc_set_log_fn: void (void (*)(const char *)) >+talloc_set_log_stderr: void (void) >+talloc_set_memlimit: int (const void *, size_t) >+talloc_set_name: const char *(const void *, const char *, ...) >+talloc_set_name_const: void (const void *, const char *) >+talloc_show_parents: void (const void *, FILE *) >+talloc_strdup: char *(const void *, const char *) >+talloc_strdup_append: char *(char *, const char *) >+talloc_strdup_append_buffer: char *(char *, const char *) >+talloc_strndup: char *(const void *, const char *, size_t) >+talloc_strndup_append: char *(char *, const char *, size_t) >+talloc_strndup_append_buffer: char *(char *, const char *, size_t) >+talloc_total_blocks: size_t (const void *) >+talloc_total_size: size_t (const void *) >+talloc_unlink: int (const void *, void *) >+talloc_vasprintf: char *(const void *, const char *, va_list) >+talloc_vasprintf_append: char *(char *, const char *, va_list) >+talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) >+talloc_version_major: int (void) >+talloc_version_minor: int (void) >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 198bab9..1cb4d7d 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -685,6 +685,72 @@ _PUBLIC_ void *talloc_pool(const void *context, size_t size) > } > > /* >+ * Create a talloc pool correctly sized for a basic size plus >+ * a number of subobjects whose total size is given. Essentially >+ * a custom allocator for talloc to reduce fragmentation. >+ */ >+ >+_PUBLIC_ void *_talloc_pooled_object(const void *ctx, >+ size_t type_size, >+ const char *type_name, >+ unsigned num_subobjects, >+ size_t total_subobjects_size) >+{ >+ size_t poolsize, subobjects_slack, tmp; >+ struct talloc_chunk *tc; >+ struct talloc_pool_hdr *pool_hdr; >+ void *ret; >+ >+ poolsize = type_size + total_subobjects_size; >+ >+ if ((poolsize < type_size) || (poolsize < total_subobjects_size)) { >+ goto overflow; >+ } >+ >+ if (num_subobjects == UINT_MAX) { >+ goto overflow; >+ } >+ num_subobjects += 1; /* the object body itself */ >+ >+ /* >+ * Alignment can increase the pool size by at most 15 bytes per object >+ * plus alignment for the object itself >+ */ >+ subobjects_slack = (TC_HDR_SIZE + TP_HDR_SIZE + 15) * num_subobjects; >+ if (subobjects_slack < num_subobjects) { >+ goto overflow; >+ } >+ >+ tmp = poolsize + subobjects_slack; >+ if ((tmp < poolsize) || (tmp < subobjects_slack)) { >+ goto overflow; >+ } >+ poolsize = tmp; >+ >+ ret = talloc_pool(ctx, poolsize); >+ if (ret == NULL) { >+ return NULL; >+ } >+ >+ tc = talloc_chunk_from_ptr(ret); >+ tc->size = type_size; >+ >+ pool_hdr = talloc_pool_from_chunk(tc); >+ >+#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) >+ VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, type_size); >+#endif >+ >+ pool_hdr->end = ((char *)pool_hdr->end + TC_ALIGN16(type_size)); >+ >+ talloc_set_name_const(ret, type_name); >+ return ret; >+ >+overflow: >+ return NULL; >+} >+ >+/* > setup a destructor to be called on free of a pointer > the destructor should return 0 on success, or -1 on failure. > if the destructor fails then the free is failed, and the memory can >diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h >index aa9864b..1b59390 100644 >--- a/lib/talloc/talloc.h >+++ b/lib/talloc/talloc.h >@@ -847,6 +847,43 @@ void *talloc_find_parent_bytype(const void *ptr, #type); > */ > void *talloc_pool(const void *context, size_t size); > >+#ifdef DOXYGEN >+/** >+ * @brief Allocate a talloc object as/with an additional pool. >+ * >+ * This is like talloc_pool(), but's it's more flexible >+ * and allows an object to be a pool for its children. >+ * >+ * @param[in] ctx The talloc context to hang the result off. >+ * >+ * @param[in] type The type that we want to allocate. >+ * >+ * @param[in] num_subobjects The expected number of subobjects, which will >+ * be allocated within the pool. This allocates >+ * space for talloc_chunk headers. >+ * >+ * @param[in] total_subobjects_size The size that all subobjects can use in total. >+ * >+ * >+ * @return The allocated talloc object, NULL on error. >+ */ >+void *talloc_pooled_object(const void *ctx, #type, >+ unsigned num_subobjects, >+ size_t total_subobjects_size); >+#else >+#define talloc_pooled_object(_ctx, _type, \ >+ _num_subobjects, \ >+ _total_subobjects_size) \ >+ (_type *)_talloc_pooled_object((_ctx), sizeof(_type), #_type, \ >+ (_num_subobjects), \ >+ (_total_subobjects_size)) >+void *_talloc_pooled_object(const void *ctx, >+ size_t type_size, >+ const char *type_name, >+ unsigned num_subobjects, >+ size_t total_subobjects_size); >+#endif >+ > /** > * @brief Free a talloc chunk and NULL out the pointer. > * >diff --git a/lib/talloc/wscript b/lib/talloc/wscript >index ecc5e24..1ca41f6 100644 >--- a/lib/talloc/wscript >+++ b/lib/talloc/wscript >@@ -1,7 +1,7 @@ > #!/usr/bin/env python > > APPNAME = 'talloc' >-VERSION = '2.0.8' >+VERSION = '2.1.0' > > > blddir = 'bin' >-- >1.9.1 > > >From 544a81e8d7632291c683addda0dc7627cfd33b77 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 6 Sep 2013 15:30:38 -0700 >Subject: [PATCH 20/37] talloc: Test the pooled object > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 256d10f5792a37d20cbb45f2af3f8578bd354110) >--- > lib/talloc/testsuite.c | 36 ++++++++++++++++++++++++++++++++++++ > 1 file changed, 36 insertions(+) > >diff --git a/lib/talloc/testsuite.c b/lib/talloc/testsuite.c >index f04f4f1..888d260 100644 >--- a/lib/talloc/testsuite.c >+++ b/lib/talloc/testsuite.c >@@ -1291,6 +1291,40 @@ static bool test_pool_nest(void) > return true; > } > >+struct pooled { >+ char *s1; >+ char *s2; >+ char *s3; >+}; >+ >+static bool test_pooled_object(void) >+{ >+ struct pooled *p; >+ const char *s1 = "hello"; >+ const char *s2 = "world"; >+ const char *s3 = ""; >+ >+ p = talloc_pooled_object(NULL, struct pooled, 3, >+ strlen(s1)+strlen(s2)+strlen(s3)+3); >+ >+ if (talloc_get_size(p) != sizeof(struct pooled)) { >+ return false; >+ } >+ >+ p->s1 = talloc_strdup(p, s1); >+ >+ TALLOC_FREE(p->s1); >+ p->s1 = talloc_strdup(p, s2); >+ TALLOC_FREE(p->s1); >+ >+ p->s1 = talloc_strdup(p, s1); >+ p->s2 = talloc_strdup(p, s2); >+ p->s3 = talloc_strdup(p, s3); >+ >+ TALLOC_FREE(p); >+ return true; >+} >+ > static bool test_free_ref_null_context(void) > { > void *p1, *p2, *p3; >@@ -1591,6 +1625,8 @@ bool torture_local_talloc(struct torture_context *tctx) > setlinebuf(stdout); > > test_reset(); >+ ret &= test_pooled_object(); >+ test_reset(); > ret &= test_pool_nest(); > test_reset(); > ret &= test_ref1(); >-- >1.9.1 > > >From 7f5e5a8af49158de22b73052bcf9df11594f6c53 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 14 Oct 2013 13:17:12 +0200 >Subject: [PATCH 21/37] talloc: Add a warning to talloc_reference() > documentation. > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Kai Blin <kai@samba.org> > >Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org> >Autobuild-Date(master): Mon Oct 14 23:05:54 CEST 2013 on sn-devel-104 > >(cherry picked from commit 2343df451a13115eebfd46f9247ec2ae8c3a85c0) >--- > lib/talloc/talloc.h | 8 ++++++++ > 1 file changed, 8 insertions(+) > >diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h >index 1b59390..5d29a8d 100644 >--- a/lib/talloc/talloc.h >+++ b/lib/talloc/talloc.h >@@ -961,6 +961,10 @@ size_t talloc_reference_count(const void *ptr); > * @return The original pointer 'ptr', NULL if talloc ran out of > * memory in creating the reference. > * >+ * @warning You should try to avoid using this interface. It turns a beautiful >+ * talloc-tree into a graph. It is often really hard to debug if you >+ * screw something up by accident. >+ * > * Example: > * @code > * unsigned int *a, *b, *c; >@@ -1001,6 +1005,10 @@ void *_talloc_reference_loc(const void *context, const void *ptr, const char *lo > * this function will fail and will return -1. Likewise, if ptr is NULL, > * then the function will make no modifications and return -1. > * >+ * @warning You should try to avoid using this interface. It turns a beautiful >+ * talloc-tree into a graph. It is often really hard to debug if you >+ * screw something up by accident. >+ * > * Example: > * @code > * unsigned int *a, *b, *c; >-- >1.9.1 > > >From 11a9da40dd8191fe63fbf41d98193e2a16aba04c Mon Sep 17 00:00:00 2001 >From: Jelmer Vernooij <jelmer@samba.org> >Date: Wed, 27 Nov 2013 02:12:02 +0000 >Subject: [PATCH 22/37] Add a basic guide on pytalloc. > >Signed-off-by: Jelmer Vernooij <jelmer@samba.org> >Reviewed-By: Andrew Bartlett <abartlet@samba.org> > >Autobuild-User(master): Jelmer Vernooij <jelmer@samba.org> >Autobuild-Date(master): Thu Nov 28 02:24:45 CET 2013 on sn-devel-104 > >(cherry picked from commit 91c1053413e1f309b2d5b215a423f37e3883aa91) >--- > lib/talloc/pytalloc.h | 3 + > lib/talloc/pytalloc_guide.txt | 153 ++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 156 insertions(+) > create mode 100644 lib/talloc/pytalloc_guide.txt > >diff --git a/lib/talloc/pytalloc.h b/lib/talloc/pytalloc.h >index 2d2c57b..5c3876e 100644 >--- a/lib/talloc/pytalloc.h >+++ b/lib/talloc/pytalloc.h >@@ -29,7 +29,10 @@ typedef struct { > void *ptr; > } pytalloc_Object; > >+/* Return the PyTypeObject for pytalloc_Object. Returns a new reference. */ > PyTypeObject *pytalloc_GetObjectType(void); >+ >+/* Check whether a specific object is a talloc Object. */ > int pytalloc_Check(PyObject *); > > /* Retrieve the pointer for a pytalloc_object. Like talloc_get_type() >diff --git a/lib/talloc/pytalloc_guide.txt b/lib/talloc/pytalloc_guide.txt >new file mode 100644 >index 0000000..755a52b >--- /dev/null >+++ b/lib/talloc/pytalloc_guide.txt >@@ -0,0 +1,153 @@ >+Using talloc in Samba4 >+====================== >+ >+.. contents:: >+ >+Jelmer Vernooij >+August 2013 >+ >+The most current version of this document is available at >+ http://samba.org/ftp/unpacked/talloc/pytalloc_guide.txt >+ >+pytalloc is a small library that provides glue for wrapping >+talloc-allocated objects from C in Python objects. >+ >+What is pytalloc, and what is it not? >+------------------------------------- >+ >+pytalloc is merely a helper library - it provides a convenient base type object >+for objects that wrap talloc-maintained memory in C. It won't write your >+bindings for you but it will make it easier to write C bindings that involve >+talloc, and take away some of the boiler plate. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+pytalloc_Object >+ >+This is the new base class that all Python objects that wrap talloc pointers >+derive from. It is itself a subclass of the "Object" type that all objects >+in Python derive from. >+ >+Note that you will almost never create objects of the pytalloc_Object type >+itself, as they are just opaque pointers that can not be accessed from >+Python. A common pattern is other objects that subclass pytalloc_Object and >+rely on it for their memory management. >+ >+Each `pytalloc_Object` wraps two core of information - a talloc context >+and a pointer. The pointer is the actual data that is wrapped. The talloc >+context is used for memory management purposes only; when the wrapping Python object >+goes away, it unlinks the talloc context. The talloc context pointer and the ptr >+can (and often do) have the same value. >+ >+Each pytalloc_Object has a custom __repr__ implementation that >+describes that it is a talloc object and the location of the >+pointer it is wrapping. it also has a custom __cmp__/__eq__/__neq__ method that >+compares the pointers the object is wrapping rather than the objects >+themselves (since there can be multiple objects that wrap the same talloc >+pointer). >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+PyTypeObject *pytalloc_GetObjectType(void) >+ >+Obtain a reference to the PyTypeObject for `pytalloc_Object`. The reference >+counter for the object will be incremented, so the caller will have to >+decrement it when it no longer needs it (using `Py_DECREF`). >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=- >+int pytalloc_Check(PyObject *) >+ >+Check whether a specific object is a talloc Object. Returns non-zero if it is >+a pytalloc_Object and zero otherwise. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+type *pytalloc_get_type(PyObject *py_obj, type) >+ >+Retrieve the pointer from a `pytalloc_Object` py_obj. type should be a >+C type, similar to a type passed to `talloc_get_type`. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+pytalloc_get_ptr(PyObject *py_obj) >+ >+Retrieve the pointer from a `pytalloc_Object` py_obj. There is no >+type checking - use `pytalloc_get_type` if possible. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+TALLOC_CTX *pytalloc_get_mem_ctx(PyObject *py_obj) >+ >+Retrieve the talloc context associated with a pytalloc_Object. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr) >+ >+Create a new Python wrapping object for a talloc pointer and context, with >+py_type as associated Python sub type object. >+ >+This will *not* increment the reference counter for the talloc context, >+so the caller should make sure such an increment has happened. When the Python >+object goes away, it will unreference the talloc context. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+PyObject *pytalloc_steal(PyTypeObject *py_type, void *ptr) >+ >+Create a new Python wrapping object for a talloc pointer and context, with >+py_type as associated Python sub type object. >+ >+This will *not* increment the reference counter for the talloc context, >+so the caller should make sure such an increment has happened. When the Python >+object goes away, it will unreference the talloc context. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+PyObject *pytalloc_reference_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr) >+ >+Create a new Python wrapping object for a talloc pointer and context, with >+py_type as associated Python sub type object. >+ >+This will increment the reference counter for the talloc context. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+PyObject *pytalloc_reference(PyTypeObject *py_type, void *talloc_ptr) >+ >+Create a new Python wrapping object for a talloc pointer, with >+py_type as associated Python sub type object. The pointer will also be used >+as the talloc context. >+ >+This will increment the reference counter for the talloc context. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+PyObject *pytalloc_new(type, PyTypeObject *typeobj) >+ >+Create a new, empty pytalloc_Object with the specified Python type object. type >+should be a C type, similar to talloc_new(). >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+PyObject *pytalloc_CObject_FromTallocPtr(void *); >+ >+Create a new pytalloc_Object for an abitrary talloc-maintained C pointer. This will >+use a generic VoidPtr Python type, which just provides an opaque object in >+Python. The caller is responsible for incrementing the talloc reference count before calling >+this function - it will dereference the talloc pointer when it is garbage collected. >+ >+Debug function for talloc in Python >+----------------------------------- >+ >+The "talloc" module in Python provides a couple of functions that can be used >+to debug issues with objects wrapped by pytalloc. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+report_full(obj?) >+ >+Print a full report on a specific object or on all allocated objects by Python. >+Same behaviour as the `talloc_report_full()` function that is provided by >+C talloc. >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+enable_null_tracking() >+ >+This enables tracking of the NULL memory context without enabling leak >+reporting on exit. Useful for when you want to do your own leak >+reporting call via talloc_report_null_full(). >+ >+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >+pytalloc_total_blocks(obj?) >+ >+Return the talloc block count for all allocated objects or a specific object if >+specified. >-- >1.9.1 > > >From a9e6e0385cfb1d3694f422dd6b65341e4fea13ba Mon Sep 17 00:00:00 2001 >From: Lukas Slebodnik <lslebodn@redhat.com> >Date: Fri, 4 Apr 2014 13:29:39 +0200 >Subject: [PATCH 23/37] talloc: Update flags in pytalloc-util pkgconfig file > >After exapnding, @LIB_RPATH@ will be -Wl,-rpatch,/usr/local/lib if rpath is >used on install. But "-Wl," will be passed to linker and should not be among >CFLAGS. Other pkgconfig files have @LIB_RPATH@ in the right place. > @see commit 735c1cd2da15167748e92ba6de48fdb5169db587 > >Signed-off-by: Lukas Slebodnik <lslebodn@redhat.com> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Fri Apr 4 23:50:25 CEST 2014 on sn-devel-104 > >(cherry picked from commit e1df75b5a965829db0c1f76673dcc824447b3ae7) >--- > lib/talloc/pytalloc-util.pc.in | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/lib/talloc/pytalloc-util.pc.in b/lib/talloc/pytalloc-util.pc.in >index bc704b4..b7426bb 100644 >--- a/lib/talloc/pytalloc-util.pc.in >+++ b/lib/talloc/pytalloc-util.pc.in >@@ -6,6 +6,6 @@ includedir=@includedir@ > Name: pytalloc-util > Description: Utility functions for using talloc objects with Python > Version: @TALLOC_VERSION@ >-Libs: -L${libdir} -lpytalloc-util >-Cflags: @LIB_RPATH@ -I${includedir} >+Libs: @LIB_RPATH@ -L${libdir} -lpytalloc-util >+Cflags: -I${includedir} > URL: http://talloc.samba.org/ >-- >1.9.1 > > >From f3ce5c6f0ddc229debb0a1ad573a3d619dfe63df Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 10 Jan 2014 10:45:22 +0100 >Subject: [PATCH 24/37] talloc: Tune talloc_vasprintf > >vsnprintf is significantly more expensive than memcpy. For the >common case where the string we print is less than a kilobyte, avoid >the second vsnprintf. > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Thu May 15 12:49:14 CEST 2014 on sn-devel-104 > >(cherry picked from commit 593c8103af5a5ed6b3c915369fed5b90efb42c25) >--- > lib/talloc/talloc.c | 14 +++++++++----- > 1 file changed, 9 insertions(+), 5 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 1cb4d7d..2a5406e 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -2356,11 +2356,11 @@ _PUBLIC_ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) > int len; > char *ret; > va_list ap2; >- char c; >+ char buf[1024]; > > /* this call looks strange, but it makes it work on older solaris boxes */ > va_copy(ap2, ap); >- len = vsnprintf(&c, 1, fmt, ap2); >+ len = vsnprintf(buf, sizeof(buf), fmt, ap2); > va_end(ap2); > if (unlikely(len < 0)) { > return NULL; >@@ -2369,9 +2369,13 @@ _PUBLIC_ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) > ret = (char *)__talloc(t, len+1); > if (unlikely(!ret)) return NULL; > >- va_copy(ap2, ap); >- vsnprintf(ret, len+1, fmt, ap2); >- va_end(ap2); >+ if (len < sizeof(buf)) { >+ memcpy(ret, buf, len+1); >+ } else { >+ va_copy(ap2, ap); >+ vsnprintf(ret, len+1, fmt, ap2); >+ va_end(ap2); >+ } > > _talloc_set_name_const(ret, ret); > return ret; >-- >1.9.1 > > >From c506efc82bee05ed07bee0b7f9ddb461649274cb Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 20 Nov 2013 09:57:58 +0100 >Subject: [PATCH 25/37] talloc: inline more static functions > >We need the code to be as fast as possible. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 3aa35354724b88acc63f6b4439f7203d10db4e90) >--- > lib/talloc/talloc.c | 45 ++++++++++++++++++++++++++------------------- > 1 file changed, 26 insertions(+), 19 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 2a5406e..56ad4f7 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -235,12 +235,14 @@ struct talloc_memlimit { > size_t cur_size; > }; > >-static bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size); >-static void talloc_memlimit_grow(struct talloc_memlimit *limit, >+static inline bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size); >+static inline void talloc_memlimit_grow(struct talloc_memlimit *limit, > size_t size); >-static void talloc_memlimit_shrink(struct talloc_memlimit *limit, >+static inline void talloc_memlimit_shrink(struct talloc_memlimit *limit, > size_t size); >-static void talloc_memlimit_update_on_free(struct talloc_chunk *tc); >+static inline void talloc_memlimit_update_on_free(struct talloc_chunk *tc); >+ >+static inline void _talloc_set_name_const(const void *ptr, const char *name); > > typedef int (*talloc_destructor_t)(void *); > >@@ -466,41 +468,41 @@ struct talloc_pool_hdr { > > #define TP_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_pool_hdr)) > >-static struct talloc_pool_hdr *talloc_pool_from_chunk(struct talloc_chunk *c) >+static inline struct talloc_pool_hdr *talloc_pool_from_chunk(struct talloc_chunk *c) > { > return (struct talloc_pool_hdr *)((char *)c - TP_HDR_SIZE); > } > >-static struct talloc_chunk *talloc_chunk_from_pool(struct talloc_pool_hdr *h) >+static inline struct talloc_chunk *talloc_chunk_from_pool(struct talloc_pool_hdr *h) > { > return (struct talloc_chunk *)((char *)h + TP_HDR_SIZE); > } > >-static void *tc_pool_end(struct talloc_pool_hdr *pool_hdr) >+static inline void *tc_pool_end(struct talloc_pool_hdr *pool_hdr) > { > struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr); > return (char *)tc + TC_HDR_SIZE + pool_hdr->poolsize; > } > >-static size_t tc_pool_space_left(struct talloc_pool_hdr *pool_hdr) >+static inline size_t tc_pool_space_left(struct talloc_pool_hdr *pool_hdr) > { > return (char *)tc_pool_end(pool_hdr) - (char *)pool_hdr->end; > } > > /* If tc is inside a pool, this gives the next neighbour. */ >-static void *tc_next_chunk(struct talloc_chunk *tc) >+static inline void *tc_next_chunk(struct talloc_chunk *tc) > { > return (char *)tc + TC_ALIGN16(TC_HDR_SIZE + tc->size); > } > >-static void *tc_pool_first_chunk(struct talloc_pool_hdr *pool_hdr) >+static inline void *tc_pool_first_chunk(struct talloc_pool_hdr *pool_hdr) > { > struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr); > return tc_next_chunk(tc); > } > > /* Mark the whole remaining pool as not accessable */ >-static void tc_invalidate_pool(struct talloc_pool_hdr *pool_hdr) >+static inline void tc_invalidate_pool(struct talloc_pool_hdr *pool_hdr) > { > size_t flen = tc_pool_space_left(pool_hdr); > >@@ -517,8 +519,8 @@ static void tc_invalidate_pool(struct talloc_pool_hdr *pool_hdr) > Allocate from a pool > */ > >-static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, >- size_t size, size_t prefix_len) >+static inline struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, >+ size_t size, size_t prefix_len) > { > struct talloc_pool_hdr *pool_hdr = NULL; > size_t space_left; >@@ -657,7 +659,7 @@ static inline void *__talloc(const void *context, size_t size) > * Create a talloc pool > */ > >-_PUBLIC_ void *talloc_pool(const void *context, size_t size) >+static inline void *_talloc_pool(const void *context, size_t size) > { > struct talloc_chunk *tc; > struct talloc_pool_hdr *pool_hdr; >@@ -684,6 +686,11 @@ _PUBLIC_ void *talloc_pool(const void *context, size_t size) > return result; > } > >+_PUBLIC_ void *talloc_pool(const void *context, size_t size) >+{ >+ return _talloc_pool(context, size); >+} >+ > /* > * Create a talloc pool correctly sized for a basic size plus > * a number of subobjects whose total size is given. Essentially >@@ -727,7 +734,7 @@ _PUBLIC_ void *_talloc_pooled_object(const void *ctx, > } > poolsize = tmp; > >- ret = talloc_pool(ctx, poolsize); >+ ret = _talloc_pool(ctx, poolsize); > if (ret == NULL) { > return NULL; > } >@@ -743,7 +750,7 @@ _PUBLIC_ void *_talloc_pooled_object(const void *ctx, > > pool_hdr->end = ((char *)pool_hdr->end + TC_ALIGN16(type_size)); > >- talloc_set_name_const(ret, type_name); >+ _talloc_set_name_const(ret, type_name); > return ret; > > overflow: >@@ -1858,7 +1865,7 @@ enum talloc_mem_count_type { > TOTAL_MEM_LIMIT, > }; > >-static size_t _talloc_total_mem_internal(const void *ptr, >+static inline size_t _talloc_total_mem_internal(const void *ptr, > enum talloc_mem_count_type type, > struct talloc_memlimit *old_limit, > struct talloc_memlimit *new_limit) >@@ -2666,7 +2673,7 @@ _PUBLIC_ int talloc_is_parent(const void *context, const void *ptr) > /* > return the total size of memory used by this context and all children > */ >-static size_t _talloc_total_limit_size(const void *ptr, >+static inline size_t _talloc_total_limit_size(const void *ptr, > struct talloc_memlimit *old_limit, > struct talloc_memlimit *new_limit) > { >@@ -2674,7 +2681,7 @@ 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) >+static inline bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size) > { > struct talloc_memlimit *l; > >-- >1.9.1 > > >From 9146302673766353c7787e22b556bdb85e3a4de2 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 4 Dec 2013 23:22:04 +0100 >Subject: [PATCH 26/37] talloc: inline talloc_get_name() > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 014eecd0b2aead3a160af0d864feddd53c85b580) >--- > lib/talloc/talloc.c | 16 ++++++++++------ > 1 file changed, 10 insertions(+), 6 deletions(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 56ad4f7..3b8cb81 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -1355,7 +1355,7 @@ _PUBLIC_ void *talloc_named(const void *context, size_t size, const char *fmt, . > /* > return the name of a talloc ptr, or "UNNAMED" > */ >-_PUBLIC_ const char *talloc_get_name(const void *ptr) >+static inline const char *__talloc_get_name(const void *ptr) > { > struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); > if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) { >@@ -1367,6 +1367,10 @@ _PUBLIC_ const char *talloc_get_name(const void *ptr) > return "UNNAMED"; > } > >+_PUBLIC_ const char *talloc_get_name(const void *ptr) >+{ >+ return __talloc_get_name(ptr); >+} > > /* > check if a pointer has the given name. If it does, return the pointer, >@@ -1376,7 +1380,7 @@ _PUBLIC_ void *talloc_check_name(const void *ptr, const char *name) > { > const char *pname; > if (unlikely(ptr == NULL)) return NULL; >- pname = talloc_get_name(ptr); >+ pname = __talloc_get_name(ptr); > if (likely(pname == name || strcmp(pname, name) == 0)) { > return discard_const_p(void, ptr); > } >@@ -1410,7 +1414,7 @@ _PUBLIC_ void *_talloc_get_type_abort(const void *ptr, const char *name, const c > return NULL; > } > >- pname = talloc_get_name(ptr); >+ pname = __talloc_get_name(ptr); > if (likely(pname == name || strcmp(pname, name) == 0)) { > return discard_const_p(void, ptr); > } >@@ -2028,7 +2032,7 @@ _PUBLIC_ void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, > > static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f) > { >- const char *name = talloc_get_name(ptr); >+ const char *name = __talloc_get_name(ptr); > struct talloc_chunk *tc; > FILE *f = (FILE *)_f; > >@@ -2628,9 +2632,9 @@ _PUBLIC_ void talloc_show_parents(const void *context, FILE *file) > } > > tc = talloc_chunk_from_ptr(context); >- fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context)); >+ fprintf(file, "talloc parents of '%s'\n", __talloc_get_name(context)); > while (tc) { >- fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc))); >+ fprintf(file, "\t'%s'\n", __talloc_get_name(TC_PTR_FROM_CHUNK(tc))); > while (tc && tc->prev) tc = tc->prev; > if (tc) { > tc = tc->parent; >-- >1.9.1 > > >From 270c7316cfdb0e0659f9df84c3aaf15d47644b8a Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 4 Dec 2013 15:35:37 +0100 >Subject: [PATCH 27/37] talloc: avoid a function call in TALLOC_FREE() if > possible. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit b9fcfc6399eab750880ee0b9806311dd351a8ff6) >--- > lib/talloc/talloc.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h >index 5d29a8d..0d47d23 100644 >--- a/lib/talloc/talloc.h >+++ b/lib/talloc/talloc.h >@@ -893,7 +893,7 @@ void *_talloc_pooled_object(const void *ctx, > * > * @param[in] ctx The chunk to be freed. > */ >-#define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0) >+#define TALLOC_FREE(ctx) do { if (ctx != NULL) { talloc_free(ctx); ctx=NULL; } } while(0) > > /* @} ******************************************************************/ > >-- >1.9.1 > > >From beb3026791ef107882ee3c844c1cb6f588697999 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 5 Dec 2013 08:36:13 +0100 >Subject: [PATCH 28/37] talloc: check for TALLOC_GET_TYPE_ABORT_NOOP > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit eb95fc8866dd1710b4cc2f4a4e1dc9867424def2) >--- > lib/talloc/talloc.h | 4 ++++ > 1 file changed, 4 insertions(+) > >diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h >index 0d47d23..5ece54d 100644 >--- a/lib/talloc/talloc.h >+++ b/lib/talloc/talloc.h >@@ -761,7 +761,11 @@ type *talloc_get_type(const void *ptr, #type); > */ > void *talloc_get_type_abort(const void *ptr, #type); > #else >+#ifdef TALLOC_GET_TYPE_ABORT_NOOP >+#define talloc_get_type_abort(ptr, type) (type *)(ptr) >+#else > #define talloc_get_type_abort(ptr, type) (type *)_talloc_get_type_abort(ptr, #type, __location__) >+#endif > void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location); > #endif > >-- >1.9.1 > > >From 0f8edd30f852cc04b86509791b6b08b05aea4cb3 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 20 Nov 2013 09:58:09 +0100 >Subject: [PATCH 29/37] talloc: fix compiler warning >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >This avoids the following warning when using: > >CFLAGS="-O3 -g -fstrict-overflow -Wstrict-overflow=5" > >../talloc.c: In Funktion »talloc_is_parent«: >../talloc.c:2658:21: Warnung: assuming signed overflow does not occur when >changing X +- C1 cmp C2 to X cmp C1 +- C2 [-Wstrict-overflow] > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit de822b58476093dc43c27577d2f7074541113cc5) >--- > lib/talloc/talloc.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 3b8cb81..fa56ea5 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -2655,7 +2655,10 @@ static int _talloc_is_parent(const void *context, const void *ptr, int depth) > } > > tc = talloc_chunk_from_ptr(context); >- while (tc && depth > 0) { >+ while (tc) { >+ if (depth <= 0) { >+ return 0; >+ } > if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1; > while (tc && tc->prev) tc = tc->prev; > if (tc) { >-- >1.9.1 > > >From fe7288f02e0f933010541e876e94547aeb479305 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 27 Feb 2014 09:28:02 +0100 >Subject: [PATCH 30/37] talloc/tests: avoid some unused variable warnings > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 8fbb81923ddf3449b4ad1fa1a562c9fab8c74103) >--- > lib/talloc/testsuite.c | 13 +++++++++++++ > 1 file changed, 13 insertions(+) > >diff --git a/lib/talloc/testsuite.c b/lib/talloc/testsuite.c >index 888d260..a878278 100644 >--- a/lib/talloc/testsuite.c >+++ b/lib/talloc/testsuite.c >@@ -141,6 +141,7 @@ static bool test_ref1(void) > > CHECK_BLOCKS("ref1", p1, 5); > CHECK_BLOCKS("ref1", p2, 1); >+ CHECK_BLOCKS("ref1", ref, 1); > CHECK_BLOCKS("ref1", r1, 2); > > fprintf(stderr, "Freeing p2\n"); >@@ -249,6 +250,7 @@ static bool test_ref3(void) > CHECK_BLOCKS("ref3", p1, 2); > CHECK_BLOCKS("ref3", p2, 2); > CHECK_BLOCKS("ref3", r1, 1); >+ CHECK_BLOCKS("ref3", ref, 1); > > fprintf(stderr, "Freeing p1\n"); > talloc_free(p1); >@@ -291,6 +293,7 @@ static bool test_ref4(void) > > CHECK_BLOCKS("ref4", p1, 5); > CHECK_BLOCKS("ref4", p2, 1); >+ CHECK_BLOCKS("ref4", ref, 1); > CHECK_BLOCKS("ref4", r1, 2); > > fprintf(stderr, "Freeing r1\n"); >@@ -341,6 +344,7 @@ static bool test_unlink1(void) > > CHECK_BLOCKS("unlink", p1, 7); > CHECK_BLOCKS("unlink", p2, 1); >+ CHECK_BLOCKS("unlink", ref, 1); > CHECK_BLOCKS("unlink", r1, 2); > > fprintf(stderr, "Unreferencing r1\n"); >@@ -409,6 +413,8 @@ static bool test_misc(void) > name = talloc_set_name(p1, "my name is %s", "foo"); > torture_assert_str_equal("misc", talloc_get_name(p1), "my name is foo", > "failed: wrong name after talloc_set_name(my name is foo)"); >+ torture_assert_str_equal("misc", talloc_get_name(p1), name, >+ "failed: wrong name after talloc_set_name(my name is foo)"); > CHECK_BLOCKS("misc", p1, 2); > CHECK_BLOCKS("misc", root, 3); > >@@ -617,6 +623,7 @@ static bool test_realloc_child(void) > el2 = talloc(el1->list, struct el2); > el2 = talloc(el1->list2, struct el2); > el2 = talloc(el1->list3, struct el2); >+ (void)el2; > > el1->list = talloc_realloc(el1, el1->list, struct el2 *, 100); > el1->list2 = talloc_realloc(el1, el1->list2, struct el2 *, 200); >@@ -829,6 +836,8 @@ static bool test_speed(void) > p1 = talloc_size(ctx, loop % 100); > p2 = talloc_strdup(p1, "foo bar"); > p3 = talloc_size(p1, 300); >+ (void)p2; >+ (void)p3; > talloc_free(p1); > } > count += 3 * loop; >@@ -848,6 +857,8 @@ static bool test_speed(void) > p1 = talloc_size(ctx, loop % 100); > p2 = talloc_strdup(p1, "foo bar"); > p3 = talloc_size(p1, 300); >+ (void)p2; >+ (void)p3; > talloc_free(p1); > } > count += 3 * loop; >@@ -1380,6 +1391,7 @@ static bool test_free_children(void) > root = talloc_new(NULL); > p1 = talloc_strdup(root, "foo1"); > p2 = talloc_strdup(p1, "foo2"); >+ (void)p2; > > talloc_set_name(p1, "%s", "testname"); > talloc_free_children(p1); >@@ -1404,6 +1416,7 @@ static bool test_free_children(void) > name2 = talloc_get_name(p1); > /* but this does */ > talloc_free_children(p1); >+ (void)name2; > torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname2") == 0, > "wrong name"); > CHECK_BLOCKS("name1", p1, 1); >-- >1.9.1 > > >From a00bb5f1fe6b049e96d7f4179306eff48ffd2fda Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 15 May 2014 14:53:49 +0200 >Subject: [PATCH 31/37] talloc: version 2.1.1 > >Changes: >- documentation updates >- a fix for pytalloc-util.pc >- performance improvements here and there >- fixed compiler warnings > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >Autobuild-User(master): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(master): Fri May 16 19:51:26 CEST 2014 on sn-devel-104 > >(cherry picked from commit b8e5b68de3cff8d16e4be07fdc2e780d2c3c5750) >--- > lib/talloc/ABI/pytalloc-util-2.1.1.sigs | 6 ++++ > lib/talloc/ABI/talloc-2.1.1.sigs | 64 +++++++++++++++++++++++++++++++++ > lib/talloc/wscript | 2 +- > 3 files changed, 71 insertions(+), 1 deletion(-) > create mode 100644 lib/talloc/ABI/pytalloc-util-2.1.1.sigs > create mode 100644 lib/talloc/ABI/talloc-2.1.1.sigs > >diff --git a/lib/talloc/ABI/pytalloc-util-2.1.1.sigs b/lib/talloc/ABI/pytalloc-util-2.1.1.sigs >new file mode 100644 >index 0000000..961c1a8 >--- /dev/null >+++ b/lib/talloc/ABI/pytalloc-util-2.1.1.sigs >@@ -0,0 +1,6 @@ >+pytalloc_CObject_FromTallocPtr: PyObject *(void *) >+pytalloc_Check: int (PyObject *) >+pytalloc_GetObjectType: PyTypeObject *(void) >+pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) >+pytalloc_steal: PyObject *(PyTypeObject *, void *) >+pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) >diff --git a/lib/talloc/ABI/talloc-2.1.1.sigs b/lib/talloc/ABI/talloc-2.1.1.sigs >new file mode 100644 >index 0000000..eae12cc >--- /dev/null >+++ b/lib/talloc/ABI/talloc-2.1.1.sigs >@@ -0,0 +1,64 @@ >+_talloc: void *(const void *, size_t) >+_talloc_array: void *(const void *, size_t, unsigned int, const char *) >+_talloc_free: int (void *, const char *) >+_talloc_get_type_abort: void *(const void *, const char *, const char *) >+_talloc_memdup: void *(const void *, const void *, size_t, const char *) >+_talloc_move: void *(const void *, const void *) >+_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) >+_talloc_realloc: void *(const void *, void *, size_t, const char *) >+_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) >+_talloc_reference_loc: void *(const void *, const void *, const char *) >+_talloc_set_destructor: void (const void *, int (*)(void *)) >+_talloc_steal_loc: void *(const void *, const void *, const char *) >+_talloc_zero: void *(const void *, size_t, const char *) >+_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) >+talloc_asprintf: char *(const void *, const char *, ...) >+talloc_asprintf_append: char *(char *, const char *, ...) >+talloc_asprintf_append_buffer: char *(char *, const char *, ...) >+talloc_autofree_context: void *(void) >+talloc_check_name: void *(const void *, const char *) >+talloc_disable_null_tracking: void (void) >+talloc_enable_leak_report: void (void) >+talloc_enable_leak_report_full: void (void) >+talloc_enable_null_tracking: void (void) >+talloc_enable_null_tracking_no_autofree: void (void) >+talloc_find_parent_byname: void *(const void *, const char *) >+talloc_free_children: void (void *) >+talloc_get_name: const char *(const void *) >+talloc_get_size: size_t (const void *) >+talloc_increase_ref_count: int (const void *) >+talloc_init: void *(const char *, ...) >+talloc_is_parent: int (const void *, const void *) >+talloc_named: void *(const void *, size_t, const char *, ...) >+talloc_named_const: void *(const void *, size_t, const char *) >+talloc_parent: void *(const void *) >+talloc_parent_name: const char *(const void *) >+talloc_pool: void *(const void *, size_t) >+talloc_realloc_fn: void *(const void *, void *, size_t) >+talloc_reference_count: size_t (const void *) >+talloc_reparent: void *(const void *, const void *, const void *) >+talloc_report: void (const void *, FILE *) >+talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) >+talloc_report_depth_file: void (const void *, int, int, FILE *) >+talloc_report_full: void (const void *, FILE *) >+talloc_set_abort_fn: void (void (*)(const char *)) >+talloc_set_log_fn: void (void (*)(const char *)) >+talloc_set_log_stderr: void (void) >+talloc_set_memlimit: int (const void *, size_t) >+talloc_set_name: const char *(const void *, const char *, ...) >+talloc_set_name_const: void (const void *, const char *) >+talloc_show_parents: void (const void *, FILE *) >+talloc_strdup: char *(const void *, const char *) >+talloc_strdup_append: char *(char *, const char *) >+talloc_strdup_append_buffer: char *(char *, const char *) >+talloc_strndup: char *(const void *, const char *, size_t) >+talloc_strndup_append: char *(char *, const char *, size_t) >+talloc_strndup_append_buffer: char *(char *, const char *, size_t) >+talloc_total_blocks: size_t (const void *) >+talloc_total_size: size_t (const void *) >+talloc_unlink: int (const void *, void *) >+talloc_vasprintf: char *(const void *, const char *, va_list) >+talloc_vasprintf_append: char *(char *, const char *, va_list) >+talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) >+talloc_version_major: int (void) >+talloc_version_minor: int (void) >diff --git a/lib/talloc/wscript b/lib/talloc/wscript >index 1ca41f6..9df64d9 100644 >--- a/lib/talloc/wscript >+++ b/lib/talloc/wscript >@@ -1,7 +1,7 @@ > #!/usr/bin/env python > > APPNAME = 'talloc' >-VERSION = '2.1.0' >+VERSION = '2.1.1' > > > blddir = 'bin' >-- >1.9.1 > > >From 0be72c47607393d79cf40608c86a90273409e856 Mon Sep 17 00:00:00 2001 >From: Michael Adam <obnox@samba.org> >Date: Fri, 20 Jun 2014 18:04:44 +0200 >Subject: [PATCH 32/37] talloc:build: improve detection of srcdir > >Signed-off-by: Michael Adam <obnox@samba.org> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> >(cherry picked from commit cc86b4107acebf56c7bb17f59dd358615aed57b7) >--- > lib/talloc/wscript | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/lib/talloc/wscript b/lib/talloc/wscript >index 9df64d9..986492c 100644 >--- a/lib/talloc/wscript >+++ b/lib/talloc/wscript >@@ -12,7 +12,7 @@ import os, sys > # find the buildtools directory > srcdir = '.' > while not os.path.exists(srcdir+'/buildtools') and len(srcdir.split('/')) < 5: >- srcdir = '../' + srcdir >+ srcdir = srcdir + '/..' > sys.path.insert(0, srcdir + '/buildtools/wafsamba') > > import sys >-- >1.9.1 > > >From d5eee82bf6552d802db9ef6be1478fc1d4d7d6bb Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 5 Mar 2015 12:48:47 -0800 >Subject: [PATCH 33/37] lib: talloc: Fix bug when calling a destructor. > >If the destructor itself calls talloc_set_destructor() >and returns -1, the new destructor set is overwritten >by talloc. > >Dectect that and leave the new destructor in place. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Ira Cooper <ira@samba.org> >(cherry picked from commit 3289a5d84f73bf044e5767a6c47a3f7bf8357c08) >--- > lib/talloc/talloc.c | 8 +++++++- > 1 file changed, 7 insertions(+), 1 deletion(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index fa56ea5..1ccb039 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -991,7 +991,13 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > } > tc->destructor = (talloc_destructor_t)-1; > if (d(ptr) == -1) { >- tc->destructor = d; >+ /* >+ * Only replace the destructor pointer if >+ * calling the destructor didn't modify it. >+ */ >+ if (tc->destructor == (talloc_destructor_t)-1) { >+ tc->destructor = d; >+ } > return -1; > } > tc->destructor = NULL; >-- >1.9.1 > > >From 160dc967c9d9cc0e18cd9755bb8c85e78995e5ee Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 3 Mar 2015 17:02:47 -0800 >Subject: [PATCH 34/37] lib: talloc: Allow destructors to reparent the object > they're called on. > >If a destructor returns failure (-1) when freeing a child, talloc >must then reparent the child. > >Firstly it tries the owner of any reference, next the parent of the >current object calling _talloc_free_children_internal(), and finally >the null context in the last resort. > >If a destructor reparented its own object, which can be a very >desirable thing to do (a destructor can make a decision it isn't >time to die yet, and as the parent may be going away it might >want to move itself to longer-term storage) then this new parent >gets overwritten by the existing reparenting logic. > >This patch checks when freeing a child if it already reparented >itself, and if it did doesn't then overwrite the new parent. > >Makes destructors more flexible. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Ira Cooper <ira@samba.org> >(cherry picked from commit cc4e5481ea060db7f6d8a83619d859b2e002eb90) >--- > lib/talloc/talloc.c | 7 +++++++ > 1 file changed, 7 insertions(+) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 1ccb039..46f10f4 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -1470,6 +1470,13 @@ static inline void _talloc_free_children_internal(struct talloc_chunk *tc, > if (p) new_parent = TC_PTR_FROM_CHUNK(p); > } > if (unlikely(_talloc_free_internal(child, location) == -1)) { >+ if (talloc_parent_chunk(child) != tc) { >+ /* >+ * Destructor already reparented this child. >+ * No further reparenting needed. >+ */ >+ return; >+ } > if (new_parent == null_context) { > struct talloc_chunk *p = talloc_parent_chunk(ptr); > if (p) new_parent = TC_PTR_FROM_CHUNK(p); >-- >1.9.1 > > >From 40a066d7d7282c3e4a892f1c40b044680ef047d5 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 3 Mar 2015 17:12:32 -0800 >Subject: [PATCH 35/37] lib: talloc: Test suite for the new destructor reparent > logic. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Ira Cooper <ira@samba.org> > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Sun Mar 8 20:52:43 CET 2015 on sn-devel-104 > >(cherry picked from commit 6b0cecee1b864a0589836caf9f5f2892f8cb6926) >--- > lib/talloc/testsuite.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 82 insertions(+) > >diff --git a/lib/talloc/testsuite.c b/lib/talloc/testsuite.c >index a878278..eb3e13d 100644 >--- a/lib/talloc/testsuite.c >+++ b/lib/talloc/testsuite.c >@@ -981,6 +981,84 @@ static bool test_free_parent_deny_child(void) > return true; > } > >+struct new_parent { >+ void *new_parent; >+ char val[20]; >+}; >+ >+static int reparenting_destructor(struct new_parent *np) >+{ >+ talloc_set_destructor(np, NULL); >+ (void)talloc_move(np->new_parent, &np); >+ return -1; >+} >+ >+static bool test_free_parent_reparent_child(void) >+{ >+ void *top = talloc_new(NULL); >+ char *level1; >+ char *alternate_level1; >+ char *level2; >+ struct new_parent *level3; >+ >+ printf("test: free_parent_reparent_child\n# " >+ "TALLOC FREE PARENT REPARENT CHILD\n"); >+ >+ level1 = talloc_strdup(top, "level1"); >+ alternate_level1 = talloc_strdup(top, "alternate_level1"); >+ level2 = talloc_strdup(level1, "level2"); >+ level3 = talloc(level2, struct new_parent); >+ level3->new_parent = alternate_level1; >+ memset(level3->val, 'x', sizeof(level3->val)); >+ >+ talloc_set_destructor(level3, reparenting_destructor); >+ talloc_free(level1); >+ >+ CHECK_PARENT("free_parent_reparent_child", >+ level3, alternate_level1); >+ >+ talloc_free(top); >+ >+ printf("success: free_parent_reparent_child\n"); >+ return true; >+} >+ >+static bool test_free_parent_reparent_child_in_pool(void) >+{ >+ void *top = talloc_new(NULL); >+ char *level1; >+ char *alternate_level1; >+ char *level2; >+ void *pool; >+ struct new_parent *level3; >+ >+ printf("test: free_parent_reparent_child_in_pool\n# " >+ "TALLOC FREE PARENT REPARENT CHILD IN POOL\n"); >+ >+ pool = talloc_pool(top, 1024); >+ level1 = talloc_strdup(pool, "level1"); >+ alternate_level1 = talloc_strdup(top, "alternate_level1"); >+ level2 = talloc_strdup(level1, "level2"); >+ level3 = talloc(level2, struct new_parent); >+ level3->new_parent = alternate_level1; >+ memset(level3->val, 'x', sizeof(level3->val)); >+ >+ talloc_set_destructor(level3, reparenting_destructor); >+ talloc_free(level1); >+ talloc_set_destructor(level3, NULL); >+ >+ CHECK_PARENT("free_parent_reparent_child_in_pool", >+ level3, alternate_level1); >+ >+ /* Even freeing alternate_level1 should leave pool alone. */ >+ talloc_free(alternate_level1); >+ talloc_free(top); >+ >+ printf("success: free_parent_reparent_child_in_pool\n"); >+ return true; >+} >+ >+ > static bool test_talloc_ptrtype(void) > { > void *top = talloc_new(NULL); >@@ -1674,6 +1752,10 @@ bool torture_local_talloc(struct torture_context *tctx) > test_reset(); > ret &= test_free_parent_deny_child(); > test_reset(); >+ ret &= test_free_parent_reparent_child(); >+ test_reset(); >+ ret &= test_free_parent_reparent_child_in_pool(); >+ test_reset(); > ret &= test_talloc_ptrtype(); > test_reset(); > ret &= test_talloc_free_in_destructor(); >-- >1.9.1 > > >From 4b2ec8506b5471ac34e6739a1c9ed4130fef4d59 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 27 Jan 2015 13:07:34 +0100 >Subject: [PATCH 36/37] talloc: fix _talloc_total_limit_size prototype > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 3929abfc6b5a3ae8a27da57d4dbee9524e3585e3) >--- > lib/talloc/talloc.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c >index 46f10f4..c10fd53 100644 >--- a/lib/talloc/talloc.c >+++ b/lib/talloc/talloc.c >@@ -1064,7 +1064,7 @@ static inline int _talloc_free_internal(void *ptr, const char *location) > return 0; > } > >-static size_t _talloc_total_limit_size(const void *ptr, >+static inline size_t _talloc_total_limit_size(const void *ptr, > struct talloc_memlimit *old_limit, > struct talloc_memlimit *new_limit); > >-- >1.9.1 > > >From d2fa99a6e13451aa20ddfef893cafd08f3deec79 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 9 Mar 2015 09:07:24 +0100 >Subject: [PATCH 37/37] talloc: version 2.1.2 >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >Changes: >- Allow destructors to reparent the object >- Allow destructors to remove itself >- Build improvements > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Günther Deschner <gd@samba.org> >(cherry picked from commit 7bef5e4f0e5ff4a4187f3d63e51a1725ff32b771) >--- > lib/talloc/ABI/pytalloc-util-2.1.2.sigs | 6 ++++ > lib/talloc/ABI/talloc-2.1.2.sigs | 64 +++++++++++++++++++++++++++++++++ > lib/talloc/wscript | 2 +- > 3 files changed, 71 insertions(+), 1 deletion(-) > create mode 100644 lib/talloc/ABI/pytalloc-util-2.1.2.sigs > create mode 100644 lib/talloc/ABI/talloc-2.1.2.sigs > >diff --git a/lib/talloc/ABI/pytalloc-util-2.1.2.sigs b/lib/talloc/ABI/pytalloc-util-2.1.2.sigs >new file mode 100644 >index 0000000..961c1a8 >--- /dev/null >+++ b/lib/talloc/ABI/pytalloc-util-2.1.2.sigs >@@ -0,0 +1,6 @@ >+pytalloc_CObject_FromTallocPtr: PyObject *(void *) >+pytalloc_Check: int (PyObject *) >+pytalloc_GetObjectType: PyTypeObject *(void) >+pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) >+pytalloc_steal: PyObject *(PyTypeObject *, void *) >+pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) >diff --git a/lib/talloc/ABI/talloc-2.1.2.sigs b/lib/talloc/ABI/talloc-2.1.2.sigs >new file mode 100644 >index 0000000..eae12cc >--- /dev/null >+++ b/lib/talloc/ABI/talloc-2.1.2.sigs >@@ -0,0 +1,64 @@ >+_talloc: void *(const void *, size_t) >+_talloc_array: void *(const void *, size_t, unsigned int, const char *) >+_talloc_free: int (void *, const char *) >+_talloc_get_type_abort: void *(const void *, const char *, const char *) >+_talloc_memdup: void *(const void *, const void *, size_t, const char *) >+_talloc_move: void *(const void *, const void *) >+_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) >+_talloc_realloc: void *(const void *, void *, size_t, const char *) >+_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) >+_talloc_reference_loc: void *(const void *, const void *, const char *) >+_talloc_set_destructor: void (const void *, int (*)(void *)) >+_talloc_steal_loc: void *(const void *, const void *, const char *) >+_talloc_zero: void *(const void *, size_t, const char *) >+_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) >+talloc_asprintf: char *(const void *, const char *, ...) >+talloc_asprintf_append: char *(char *, const char *, ...) >+talloc_asprintf_append_buffer: char *(char *, const char *, ...) >+talloc_autofree_context: void *(void) >+talloc_check_name: void *(const void *, const char *) >+talloc_disable_null_tracking: void (void) >+talloc_enable_leak_report: void (void) >+talloc_enable_leak_report_full: void (void) >+talloc_enable_null_tracking: void (void) >+talloc_enable_null_tracking_no_autofree: void (void) >+talloc_find_parent_byname: void *(const void *, const char *) >+talloc_free_children: void (void *) >+talloc_get_name: const char *(const void *) >+talloc_get_size: size_t (const void *) >+talloc_increase_ref_count: int (const void *) >+talloc_init: void *(const char *, ...) >+talloc_is_parent: int (const void *, const void *) >+talloc_named: void *(const void *, size_t, const char *, ...) >+talloc_named_const: void *(const void *, size_t, const char *) >+talloc_parent: void *(const void *) >+talloc_parent_name: const char *(const void *) >+talloc_pool: void *(const void *, size_t) >+talloc_realloc_fn: void *(const void *, void *, size_t) >+talloc_reference_count: size_t (const void *) >+talloc_reparent: void *(const void *, const void *, const void *) >+talloc_report: void (const void *, FILE *) >+talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) >+talloc_report_depth_file: void (const void *, int, int, FILE *) >+talloc_report_full: void (const void *, FILE *) >+talloc_set_abort_fn: void (void (*)(const char *)) >+talloc_set_log_fn: void (void (*)(const char *)) >+talloc_set_log_stderr: void (void) >+talloc_set_memlimit: int (const void *, size_t) >+talloc_set_name: const char *(const void *, const char *, ...) >+talloc_set_name_const: void (const void *, const char *) >+talloc_show_parents: void (const void *, FILE *) >+talloc_strdup: char *(const void *, const char *) >+talloc_strdup_append: char *(char *, const char *) >+talloc_strdup_append_buffer: char *(char *, const char *) >+talloc_strndup: char *(const void *, const char *, size_t) >+talloc_strndup_append: char *(char *, const char *, size_t) >+talloc_strndup_append_buffer: char *(char *, const char *, size_t) >+talloc_total_blocks: size_t (const void *) >+talloc_total_size: size_t (const void *) >+talloc_unlink: int (const void *, void *) >+talloc_vasprintf: char *(const void *, const char *, va_list) >+talloc_vasprintf_append: char *(char *, const char *, va_list) >+talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) >+talloc_version_major: int (void) >+talloc_version_minor: int (void) >diff --git a/lib/talloc/wscript b/lib/talloc/wscript >index 986492c..97c52c3 100644 >--- a/lib/talloc/wscript >+++ b/lib/talloc/wscript >@@ -1,7 +1,7 @@ > #!/usr/bin/env python > > APPNAME = 'talloc' >-VERSION = '2.1.1' >+VERSION = '2.1.2' > > > blddir = 'bin' >-- >1.9.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
jra
:
review+
Actions:
View
Attachments on
bug 11144
:
10831
| 10837 |
10838