From: Rusty Russell Date: Tue, 10 Jun 2014 01:39:38 +0000 (+0930) Subject: talloc_link: remove it. X-Git-Url: http://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=db4e16e71cd1bb474307c971c6312389bb254053 talloc_link: remove it. It's a prototype unused by anything else. Signed-off-by: Rusty Russell --- diff --git a/Makefile-ccan b/Makefile-ccan index 41548de6..b0c062d9 100644 --- a/Makefile-ccan +++ b/Makefile-ccan @@ -92,7 +92,6 @@ MODS_WITH_SRC := antithread \ tal/str \ tal/talloc \ talloc \ - talloc_link \ tally \ tap \ time \ diff --git a/ccan/talloc_link/LICENSE b/ccan/talloc_link/LICENSE deleted file mode 120000 index 9961ca9d..00000000 --- a/ccan/talloc_link/LICENSE +++ /dev/null @@ -1 +0,0 @@ -../../licenses/GPL-2 \ No newline at end of file diff --git a/ccan/talloc_link/_info b/ccan/talloc_link/_info deleted file mode 100644 index d1cdb24b..00000000 --- a/ccan/talloc_link/_info +++ /dev/null @@ -1,147 +0,0 @@ -#include -#include -#include "config.h" - -/** - * talloc_link - link helper for talloc - * - * Talloc references can be confusing and buggy. In the cases where an object - * needs multiple parents, all parents need to be aware of the situation; thus - * talloc_link is a helper where all "parents" talloc_link an object they - * agree to share ownership of. - * - * Example: - * // Silly program which keeps a cache of uppercased strings. - * // The cache wants to keep strings around even after they may have - * // been "freed" by the caller. - * #include - * #include - * #include - * #include - * #include - * #include - * - * struct upcache { - * const char *str; - * const char *upstr; - * }; - * - * static struct upcache *cache; - * static unsigned int cache_hits = 0; - * #define CACHE_SIZE 4 - * static void init_upcase(void) - * { - * cache = talloc_zero_array(NULL, struct upcache, CACHE_SIZE); - * } - * - * static struct upcache *lookup_upcase(const char *str) - * { - * unsigned int i; - * for (i = 0; i < CACHE_SIZE; i++) - * if (cache[i].str && !strcmp(cache[i].str, str)) { - * cache_hits++; - * return &cache[i]; - * } - * return NULL; - * } - * - * static struct upcache *new_upcase(const char *str) - * { - * unsigned int i; - * char *upstr; - * - * upstr = talloc_linked(cache, talloc_strdup(NULL, str)); - * if (!upstr) - * return NULL; - * - * i = random() % CACHE_SIZE; - * - * // Throw out old: works fine if cache[i].upstr is NULL. - * talloc_delink(cache, cache[i].upstr); - * - * // Replace with new. - * cache[i].str = str; - * cache[i].upstr = upstr; - * while (*upstr) { - * *upstr = toupper(*upstr); - * upstr++; - * } - * return &cache[i]; - * } - * - * // If you want to keep the result, talloc_link it. - * static const char *get_upcase(const char *str) - * { - * struct upcache *uc = lookup_upcase(str); - * if (!uc) - * uc = new_upcase(str); - * if (!uc) - * return NULL; - * return uc->upstr; - * } - * - * static void exit_upcase(void) - * { - * talloc_free(cache); - * printf("Cache hits: %u\n", cache_hits); - * } - * - * int main(int argc, char *argv[]) - * { - * unsigned int i; - * const char **values; - * - * // Will dump any memory leaks to stderr on exit. - * talloc_enable_leak_report(); - * - * // Initialize cache. - * init_upcase(); - * - * // Throw values in. - * values = talloc_array(NULL, const char *, argc); - * for (i = 1; i < argc; i++) { - * values[i-1] = talloc_link(values, get_upcase(argv[i])); - * if (!values[i-1]) - * err(1, "Out of memory"); - * } - * // This will free all the values, but cache will still work. - * talloc_free(values); - * - * // Repeat! - * values = talloc_array(NULL, const char *, argc); - * for (i = 1; i < argc; i++) { - * values[i-1] = talloc_link(values, get_upcase(argv[i])); - * if (!values[i-1]) - * err(1, "Out of memory"); - * } - * - * // This will remove cache links, but we still have a link. - * exit_upcase(); - * - * // Show values, so we output something. - * for (i = 0; i < argc - 1; i++) - * printf("%s ", values[i]); - * printf("\n"); - * - * // This will finally free the upcase strings (last link). - * talloc_free(values); - * - * return 0; - * } - * - * License: GPL (v2 or any later version) - * Author: Rusty Russell - */ -int main(int argc, char *argv[]) -{ - if (argc != 2) - return 1; - - if (strcmp(argv[1], "depends") == 0) { - printf("ccan/talloc\n"); - printf("ccan/list\n"); - return 0; - } - - return 1; -} diff --git a/ccan/talloc_link/talloc_link.c b/ccan/talloc_link/talloc_link.c deleted file mode 100644 index 280f8eb2..00000000 --- a/ccan/talloc_link/talloc_link.c +++ /dev/null @@ -1,96 +0,0 @@ -/* Licensed under GPLv2+ - see LICENSE file for details */ -#include -#include -#include -#include - -/* Fake parent, if they care. */ -static void *talloc_links = NULL; - -/* This is the parent of the linked object, so we can implement delink. */ -struct talloc_linked { - struct list_head links; - const void *obj; -}; - -/* This is a child of the linker, but not a parent of ref. */ -struct talloc_link { - struct list_node list; - struct talloc_linked *linked; -}; - -static int destroy_link(struct talloc_link *link) -{ - list_del(&link->list); - if (list_empty(&link->linked->links)) - talloc_free(link->linked); - return 0; -} - -static bool add_link(const void *ctx, struct talloc_linked *linked) -{ - struct talloc_link *link = talloc(ctx, struct talloc_link); - if (!link) - return false; - - link->linked = linked; - list_add(&linked->links, &link->list); - talloc_set_destructor(link, destroy_link); - return true; -} - -void *_talloc_linked(const void *ctx, const void *newobj) -{ - struct talloc_linked *linked; - - if (talloc_parent(newobj)) { - /* Assume leak reporting is on: create dummy parent. */ - if (!talloc_links) - talloc_links = talloc_named_const(NULL, 0, - "talloc_links"); - /* This should now have same pseudo-NULL parent. */ - assert(talloc_parent(newobj) == talloc_parent(talloc_links)); - } - - linked = talloc(talloc_links, struct talloc_linked); - if (!linked) { - talloc_free(newobj); - return NULL; - } - list_head_init(&linked->links); - linked->obj = talloc_steal(linked, newobj); - - if (!add_link(ctx, linked)) { - talloc_free(linked); - return NULL; - } - - return (void *)newobj; -} - -void *_talloc_link(const void *ctx, const void *obj) -{ - struct talloc_linked *linked; - - linked = talloc_get_type(talloc_parent(obj), struct talloc_linked); - assert(!list_empty(&linked->links)); - return add_link(ctx, linked) ? (void *)obj : NULL; -} - -void talloc_delink(const void *ctx, const void *obj) -{ - struct talloc_linked *linked; - struct talloc_link *i; - - if (!obj) - return; - - linked = talloc_get_type(talloc_parent(obj), struct talloc_linked); - list_for_each(&linked->links, i, list) { - if (talloc_is_parent(i, ctx)) { - talloc_free(i); - return; - } - } - abort(); -} diff --git a/ccan/talloc_link/talloc_link.h b/ccan/talloc_link/talloc_link.h deleted file mode 100644 index 2cd0df88..00000000 --- a/ccan/talloc_link/talloc_link.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Licensed under GPLv2+ - see LICENSE file for details */ -#ifndef TALLOC_LINK_H -#define TALLOC_LINK_H -#include - -/** - * talloc_linked - set up an object with an initial link. - * @ctx - the context to initially link to - * @newobj - the newly allocated object (with a NULL parent) - * - * The object will be freed when @ctx is freed (or talloc_delink(ctx, - * newobj) is called), unless more links are added using - * talloc_link(). - * - * For convenient chaining, it returns @newobj on success, or frees - * @newobj and returns NULL. - */ -#define talloc_linked(ctx, newobj) \ - ((_TALLOC_TYPEOF(newobj))_talloc_linked((ctx), (newobj))) - -/** - * talloc_link - add another link to a linkable object. - * @ctx - the context to link to - * @obj - the object previously made linkable with talloc_linked(). - * - * The @obj will only be freed when all contexts linked to it are - * freed (or talloc_delink()ed). - * - * Returns @obj, or NULL on failure (out of memory). - */ -#define talloc_link(ctx, obj) \ - ((_TALLOC_TYPEOF(obj))_talloc_link((ctx), (obj))) - -/** - * talloc_delink - explicitly remove a link from a linkable object. - * @ctx - the context previously used for talloc_link/talloc_linked - * @obj - the object previously used for talloc_link/talloc_linked - * - * Explicitly remove a link: normally it is implied by freeing @ctx. - * Removing the last link frees the object. - */ -void talloc_delink(const void *ctx, const void *linked); - -/* Internal helpers. */ -void *_talloc_link(const void *ctx, const void *linked); -void *_talloc_linked(const void *ctx, const void *linked); - -#endif /* TALLOC_LINK_H */ diff --git a/ccan/talloc_link/test/run.c b/ccan/talloc_link/test/run.c deleted file mode 100644 index d36bd6ad..00000000 --- a/ccan/talloc_link/test/run.c +++ /dev/null @@ -1,118 +0,0 @@ -#include -#include -#include -#include -#include - -static unsigned int destroy_count = 0; -static int destroy_obj(void *obj) -{ - destroy_count++; - return 0; -} - -int main(int argc, char *argv[]) -{ - void *obj, *p1, *p2, *p3; - - plan_tests(16); - - talloc_enable_leak_report(); - - /* Single parent case. */ - p1 = talloc(NULL, char); - obj = talloc_linked(p1, talloc(NULL, char)); - talloc_set_destructor(obj, destroy_obj); - - ok(destroy_count == 0, "destroy_count = %u", destroy_count); - talloc_free(p1); - ok(destroy_count == 1, "destroy_count = %u", destroy_count); - - /* Dual parent case. */ - p1 = talloc(NULL, char); - obj = talloc_linked(p1, talloc(NULL, char)); - talloc_set_destructor(obj, destroy_obj); - p2 = talloc(NULL, char); - talloc_link(p2, obj); - - talloc_free(p1); - ok(destroy_count == 1, "destroy_count = %u", destroy_count); - talloc_free(p2); - ok(destroy_count == 2, "destroy_count = %u", destroy_count); - - /* Triple parent case. */ - p1 = talloc(NULL, char); - obj = talloc_linked(p1, talloc(NULL, char)); - talloc_set_destructor(obj, destroy_obj); - - p2 = talloc(NULL, char); - p3 = talloc(NULL, char); - - talloc_link(p2, obj); - talloc_link(p3, obj); - - talloc_free(p1); - ok(destroy_count == 2, "destroy_count = %u", destroy_count); - talloc_free(p2); - ok(destroy_count == 2, "destroy_count = %u", destroy_count); - talloc_free(p3); - ok(destroy_count == 3, "destroy_count = %u", destroy_count); - - /* Single delink case. */ - p1 = talloc(NULL, char); - obj = talloc_linked(p1, talloc(NULL, char)); - talloc_set_destructor(obj, destroy_obj); - - ok(destroy_count == 3, "destroy_count = %u", destroy_count); - talloc_delink(p1, obj); - ok(destroy_count == 4, "destroy_count = %u", destroy_count); - talloc_free(p1); - - /* Double delink case. */ - p1 = talloc(NULL, char); - obj = talloc_linked(p1, talloc(NULL, char)); - talloc_set_destructor(obj, destroy_obj); - - p2 = talloc(NULL, char); - talloc_link(p2, obj); - - talloc_delink(p1, obj); - ok(destroy_count == 4, "destroy_count = %u", destroy_count); - talloc_delink(p2, obj); - ok(destroy_count == 5, "destroy_count = %u", destroy_count); - talloc_free(p1); - talloc_free(p2); - - /* Delink and free. */ - p1 = talloc(NULL, char); - obj = talloc_linked(p1, talloc(NULL, char)); - talloc_set_destructor(obj, destroy_obj); - p2 = talloc(NULL, char); - talloc_link(p2, obj); - - talloc_delink(p1, obj); - ok(destroy_count == 5, "destroy_count = %u", destroy_count); - talloc_free(p2); - ok(destroy_count == 6, "destroy_count = %u", destroy_count); - talloc_free(p1); - - /* Free and delink. */ - p1 = talloc(NULL, char); - obj = talloc_linked(p1, talloc(NULL, char)); - talloc_set_destructor(obj, destroy_obj); - p2 = talloc(NULL, char); - talloc_link(p2, obj); - - talloc_free(p1); - ok(destroy_count == 6, "destroy_count = %u", destroy_count); - talloc_delink(p2, obj); - ok(destroy_count == 7, "destroy_count = %u", destroy_count); - talloc_free(p2); - - /* No leaks? */ - ok1(talloc_total_size(NULL) == 0); - - talloc_disable_null_tracking(); - - return exit_status(); -}