X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftake%2Ftake.c;h=c628aac0dc97ff663db216e4f05a14b8cfd38bbf;hp=73e5c29d206fcf5a5cf23e7b6f8d4836a3d06fc4;hb=cbabfa8c8bd4757091c7fdb566b97388be890a74;hpb=0ea6a2126c713207cb139d3329b15f0c9d735fbe diff --git a/ccan/take/take.c b/ccan/take/take.c index 73e5c29d..c628aac0 100644 --- a/ccan/take/take.c +++ b/ccan/take/take.c @@ -1,16 +1,22 @@ /* CC0 (Public domain) - see LICENSE file for details */ #include #include +#include #include #include static const void **takenarr; +static const char **labelarr; static size_t max_taken, num_taken; static size_t allocfail; static void (*allocfailfn)(const void *p); -void *take_(const void *p) +void *take_(const void *p, const char *label) { + /* Overallocate: it's better than risking calloc returning NULL! */ + if (unlikely(label && !labelarr)) + labelarr = calloc(max_taken+1, sizeof(*labelarr)); + if (unlikely(num_taken == max_taken)) { const void **new; @@ -25,9 +31,16 @@ void *take_(const void *p) return (void *)p; } takenarr = new; + /* Once labelarr is set, we maintain it. */ + if (labelarr) + labelarr = realloc(labelarr, + sizeof(*labelarr) * (max_taken+1)); max_taken++; } + if (unlikely(labelarr)) + labelarr[num_taken] = label; takenarr[num_taken++] = p; + return (void *)p; } @@ -68,9 +81,23 @@ bool is_taken(const void *p) return find_taken(p) > 0; } -bool taken_any(void) +const char *taken_any(void) { - return num_taken != 0; + static char pointer_buf[32]; + + if (num_taken == 0) + return NULL; + + /* We're *allowed* to have some with labels, some without. */ + if (labelarr) { + size_t i; + for (i = 0; i < num_taken; i++) + if (labelarr[i]) + return labelarr[i]; + } + + sprintf(pointer_buf, "%p", takenarr[0]); + return pointer_buf; } void take_cleanup(void) @@ -78,6 +105,8 @@ void take_cleanup(void) max_taken = num_taken = 0; free(takenarr); takenarr = NULL; + free(labelarr); + labelarr = NULL; } void take_allocfail(void (*fn)(const void *p))