From 373e0e49521d201a17842700d870f6200a924354 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Tue, 12 Nov 2013 17:00:19 +0100 Subject: [PATCH] Custom mem funcs per dict/list --- src/context.c | 19 +++++---- src/context.h | 29 ++++--------- src/dict.c | 67 ++++++++++++++++++++----------- src/dict.h | 4 +- src/example/example_synchronous.c | 2 +- src/getdns/getdns.h | 7 ++++ src/list.c | 48 +++++++++++++--------- src/list.h | 5 ++- src/test/tests_dict.c | 5 +++ src/test/tests_list.c | 1 + src/test/tests_stub_async.c | 4 +- src/types-internal.h | 15 +++++++ 12 files changed, 128 insertions(+), 78 deletions(-) diff --git a/src/context.c b/src/context.c index cd58aaac..b66642f2 100644 --- a/src/context.c +++ b/src/context.c @@ -985,10 +985,10 @@ getdns_context_clear_outbound_request(getdns_dns_req * req) } char * -getdns_strdup(getdns_context_t context, const char *s) +getdns_strdup(void *(*malloc)(size_t), const char *s) { size_t sz = strlen(s) + 1; - char *r = GETDNS_XMALLOC(context, char, sz); + char *r = (char *)(*malloc)(sizeof(char) * sz); if (r) return memcpy(r, s, sz); else @@ -996,7 +996,7 @@ getdns_strdup(getdns_context_t context, const char *s) } struct getdns_bindata * -getdns_bindata_copy(getdns_context_t context, +getdns_bindata_copy(void *(*malloc)(size_t), void (*free)(void *), const struct getdns_bindata *src) { struct getdns_bindata *dst; @@ -1004,14 +1004,14 @@ getdns_bindata_copy(getdns_context_t context, if (!src) return NULL; - dst = GETDNS_MALLOC(context, struct getdns_bindata); + dst = (struct getdns_bindata *)(*malloc)(sizeof(struct getdns_bindata)); if (!dst) return NULL; dst->size = src->size; - dst->data = GETDNS_XMALLOC(context, uint8_t, src->size); + dst->data = (uint8_t *)(*malloc)(sizeof(uint8_t) * src->size); if (!dst->data) { - GETDNS_FREE(context, dst); + (*free)(dst); return NULL; } (void) memcpy(dst->data, src->data, src->size); @@ -1019,12 +1019,11 @@ getdns_bindata_copy(getdns_context_t context, } void -getdns_bindata_destroy(getdns_context_t context, - struct getdns_bindata *bindata) +getdns_bindata_destroy(void (*free)(void *), struct getdns_bindata *bindata) { if (!bindata) return; - GETDNS_FREE(context, bindata->data); - GETDNS_FREE(context, bindata); + (*free)(bindata->data); + (*free)(bindata); } /* getdns_context.c */ diff --git a/src/context.h b/src/context.h index 53fc793b..f1aa337c 100644 --- a/src/context.h +++ b/src/context.h @@ -39,9 +39,6 @@ struct ub_ctx; /** function pointer typedefs */ typedef void (*getdns_update_callback) (getdns_context_t, uint16_t); -typedef void *(*getdns_memory_allocator) (size_t); -typedef void (*getdns_memory_deallocator) (void *); -typedef void *(*getdns_memory_reallocator) (void *, size_t); struct getdns_context_t { @@ -62,9 +59,9 @@ struct getdns_context_t uint8_t edns_do_bit; getdns_update_callback update_callback; - getdns_memory_allocator malloc; - getdns_memory_reallocator realloc; - getdns_memory_deallocator free; + void *(*malloc)(size_t); + void *(*realloc)(void *, size_t); + void (*free)(void *); /* Event loop for sync requests */ struct event_base *event_base_sync; @@ -87,19 +84,6 @@ struct getdns_context_t struct ldns_rbtree_t *outbound_requests; }; -#define GETDNS_XMALLOC(context, type, count) \ - ((context) ? ((type *) (*(context)->malloc)((count) * sizeof(type))) \ - : ((type *) malloc((count) * sizeof(type)))) -#define GETDNS_MALLOC(context, type) \ - GETDNS_XMALLOC(context, type, 1) -#define GETDNS_XREALLOC(context, ptr, type, count) \ - ((context) ? ((type *) (*(context)->realloc)((ptr), (count) * sizeof(type))) \ - : ((type *) realloc((ptr), (count) * sizeof(type)))) -#define GETDNS_REALLOC(context, ptr, type) \ - GETDNS_XREALLOC(context, ptr, type, 1); -#define GETDNS_FREE(context, ptr) \ - ((context) ? ((*(context)->free)(ptr)) : free(ptr)) - /** internal functions **/ /** * Sets up the unbound contexts with stub or recursive behavior @@ -118,12 +102,13 @@ getdns_return_t getdns_context_clear_outbound_request(struct getdns_dns_req getdns_return_t getdns_context_cancel_request(getdns_context_t context, getdns_transaction_t transaction_id, int fire_callback); -char *getdns_strdup(getdns_context_t, const char *str); +char *getdns_strdup(void *(*malloc)(size_t), const char *str); -struct getdns_bindata *getdns_bindata_copy(getdns_context_t, +struct getdns_bindata *getdns_bindata_copy( + void *(*malloc)(size_t), void (*free)(void *), const struct getdns_bindata *src); -void getdns_bindata_destroy(getdns_context_t context, +void getdns_bindata_destroy(void (*free)(void *), struct getdns_bindata *bindata); #endif /* _GETDNS_CONTEXT_H_ */ diff --git a/src/dict.c b/src/dict.c index 4804fbce..60d17b8d 100644 --- a/src/dict.c +++ b/src/dict.c @@ -37,7 +37,7 @@ #include #include -#include "context.h" +#include "types-internal.h" #include "dict.h" /*---------------------------------------- getdns_dict_find */ @@ -62,8 +62,8 @@ getdns_dict_find(struct getdns_dict *dict, char *key, bool addifnotfnd) if (!item && addifnotfnd) { /* tsearch will add a node automatically for us */ - item = GETDNS_MALLOC(dict->context, struct getdns_dict_item); - item->node.key = getdns_strdup(dict->context, key); + item = GETDNS_MALLOC(dict, struct getdns_dict_item); + item->node.key = getdns_strdup(dict->malloc, key); item->data.n = 0; ldns_rbtree_insert(&(dict->root), (ldns_rbnode_t *) item); } @@ -82,7 +82,8 @@ getdns_dict_get_names(struct getdns_dict * dict, struct getdns_list ** answer) if (!dict || !answer) return GETDNS_RETURN_NO_SUCH_DICT_NAME; - *answer = getdns_list_create_with_context(dict->context); + *answer = getdns_list_create_with_memory_functions( + dict->malloc, dict->realloc, dict->free); if (!*answer) return GETDNS_RETURN_NO_SUCH_DICT_NAME; @@ -185,20 +186,38 @@ getdns_dict_get_int(struct getdns_dict * dict, char *name, uint32_t * answer) return GETDNS_RETURN_GOOD; } /* getdns_dict_get_int */ +struct getdns_dict * +getdns_dict_create_with_memory_functions(void *(*malloc)(size_t), + void *(*realloc)(void *, size_t), void (*free)(void *)) +{ + struct getdns_dict *dict; + + if (!malloc || !realloc || !free) + return NULL; + + dict = (struct getdns_dict *)(*malloc)(sizeof(struct getdns_dict)); + if (!dict) + return NULL; + + dict->malloc = malloc; + dict->realloc = realloc; + dict->free = free; + ldns_rbtree_init(&(dict->root), + (int (*)(const void *, const void *)) strcmp); + return dict; +} + + /*-------------------------- getdns_dict_create_with_context */ struct getdns_dict * getdns_dict_create_with_context(getdns_context_t context) { - struct getdns_dict *dict; - - dict = GETDNS_MALLOC(context, struct getdns_dict); - if (!dict) - return NULL; - - dict->context = context; - ldns_rbtree_init(&(dict->root), (int (*)(const void *, - const void *)) strcmp); - return dict; + if (context) + return getdns_dict_create_with_memory_functions(context->malloc, + context->realloc, context->free); + else + return getdns_dict_create_with_memory_functions(&malloc, + &realloc, &free); } /* getdns_dict_create_with_context */ /*---------------------------------------- getdns_dict_create */ @@ -231,7 +250,8 @@ getdns_dict_copy(struct getdns_dict * srcdict, struct getdns_dict ** dstdict) *dstdict = NULL; return GETDNS_RETURN_GOOD; } - *dstdict = getdns_dict_create_with_context(srcdict->context); + *dstdict = getdns_dict_create_with_memory_functions( + srcdict->malloc, srcdict->realloc, srcdict->free); if (!*dstdict) return GETDNS_RETURN_NO_SUCH_DICT_NAME; @@ -278,14 +298,14 @@ void getdns_dict_item_free(ldns_rbnode_t * node, void *arg) { struct getdns_dict_item *item = (struct getdns_dict_item *) node; - getdns_context_t context = (getdns_context_t)arg; + struct getdns_dict *dict = (struct getdns_dict *)arg; if (!item) return; switch (item->dtype) { case t_bindata: - getdns_bindata_destroy(context, item->data.bindata); + getdns_bindata_destroy(dict->free, item->data.bindata); break; case t_dict: getdns_dict_destroy(item->data.dict); @@ -297,8 +317,8 @@ getdns_dict_item_free(ldns_rbnode_t * node, void *arg) break; } if (item->node.key) - GETDNS_FREE(context, (void *)item->node.key); - GETDNS_FREE(context, item); + GETDNS_FREE(dict, (void *)item->node.key); + GETDNS_FREE(dict, item); } /* getdns_dict_item_free */ /*---------------------------------------- getdns_dict_destroy */ @@ -309,8 +329,8 @@ getdns_dict_destroy(struct getdns_dict *dict) return; ldns_traverse_postorder(&(dict->root), - getdns_dict_item_free, dict->context); - GETDNS_FREE(dict->context, dict); + getdns_dict_item_free, dict); + GETDNS_FREE(dict, dict); } /* getdns_dict_destroy */ /*---------------------------------------- getdns_dict_set_dict */ @@ -376,13 +396,14 @@ getdns_dict_set_bindata(struct getdns_dict * dict, char *name, if (!dict || !name || !child_bindata) return GETDNS_RETURN_NO_SUCH_DICT_NAME; - newbindata = getdns_bindata_copy(dict->context, child_bindata); + newbindata = getdns_bindata_copy( + dict->malloc, dict->free, child_bindata); if (!newbindata) return GETDNS_RETURN_NO_SUCH_DICT_NAME; item = getdns_dict_find(dict, name, true); if (!item) { - getdns_bindata_destroy(dict->context, newbindata); + getdns_bindata_destroy(dict->free, newbindata); return GETDNS_RETURN_NO_SUCH_DICT_NAME; } item->dtype = t_bindata; diff --git a/src/dict.h b/src/dict.h index 5f5afae2..26a72f96 100644 --- a/src/dict.h +++ b/src/dict.h @@ -66,7 +66,9 @@ struct getdns_dict_item struct getdns_dict { ldns_rbtree_t root; - getdns_context_t context; + void *(*malloc)(size_t); + void *(*realloc)(void *, size_t); + void (*free)(void *); }; #endif diff --git a/src/example/example_synchronous.c b/src/example/example_synchronous.c index 16d0bb45..4d070ad2 100644 --- a/src/example/example_synchronous.c +++ b/src/example/example_synchronous.c @@ -110,8 +110,8 @@ main() } /* Clean up */ - getdns_free_sync_request_memory(this_response); getdns_context_destroy(this_context); + getdns_free_sync_request_memory(this_response); exit(EXIT_SUCCESS); } /* main */ diff --git a/src/getdns/getdns.h b/src/getdns/getdns.h index 67f57ca2..0d788eea 100644 --- a/src/getdns/getdns.h +++ b/src/getdns/getdns.h @@ -559,6 +559,10 @@ getdns_return_t getdns_dict_get_int(struct getdns_dict *this_dict, char *name, */ struct getdns_list *getdns_list_create(); struct getdns_list *getdns_list_create_with_context(getdns_context_t context); +struct getdns_list *getdns_list_create_with_memory_functions( + void *(*malloc) (size_t), void *(*realloc) (void *, size_t), + void (*free) (void *)); + /** * free memory allocated to the list (also frees all children of the list) * note that lists and bindata retrieved from the list via the getdns_list_get_* @@ -615,6 +619,9 @@ getdns_return_t getdns_list_set_int(struct getdns_list *list, size_t index, */ struct getdns_dict *getdns_dict_create(); struct getdns_dict *getdns_dict_create_with_context(getdns_context_t context); +struct getdns_dict *getdns_dict_create_with_memory_functions( + void *(*malloc) (size_t), void *(*realloc) (void *, size_t), + void (*free) (void *)); /** * private function used to make a copy of a dict structure, the caller is responsible diff --git a/src/list.c b/src/list.c index 8e069db4..125e9ee8 100644 --- a/src/list.c +++ b/src/list.c @@ -35,7 +35,7 @@ */ #include -#include "context.h" +#include "types-internal.h" #include "list.h" /*---------------------------------------- getdns_list_get_length */ @@ -133,12 +133,11 @@ getdns_return_t getdns_list_realloc(struct getdns_list *list) { struct getdns_list_item *newlist; - int i; if (!list) return GETDNS_RETURN_GENERIC_ERROR; - newlist = GETDNS_XREALLOC(list->context, list->items, + newlist = GETDNS_XREALLOC(list, list->items, struct getdns_list_item, list->numalloc + GETDNS_LIST_BLOCKSZ); if (!newlist) @@ -146,12 +145,6 @@ getdns_list_realloc(struct getdns_list *list) list->items = newlist; list->numalloc += GETDNS_LIST_BLOCKSZ; - /* - for (i = list->numalloc - GETDNS_LIST_BLOCKSZ; i < list->numalloc; i++) { - list->items[i].dtype = t_int; - list->items[i].data.n = 0; - } - */ return GETDNS_RETURN_GOOD; } /* getdns_list_realloc */ @@ -170,7 +163,8 @@ getdns_list_copy(struct getdns_list * srclist, struct getdns_list ** dstlist) *dstlist = NULL; return GETDNS_RETURN_GOOD; } - *dstlist = getdns_list_create_with_context(srclist->context); + *dstlist = getdns_list_create_with_memory_functions( + srclist->malloc, srclist->realloc, srclist->free); if (!dstlist) return GETDNS_RETURN_NO_SUCH_LIST_ITEM; @@ -211,17 +205,22 @@ getdns_list_copy(struct getdns_list * srclist, struct getdns_list ** dstlist) return GETDNS_RETURN_GOOD; } /* getdns_list_copy */ -/*-------------------------- getdns_list_create_with_context */ struct getdns_list * -getdns_list_create_with_context(getdns_context_t context) +getdns_list_create_with_memory_functions(void *(*malloc)(size_t), + void *(*realloc)(void *, size_t), void (*free)(void *)) { struct getdns_list *list; - list = GETDNS_MALLOC(context, struct getdns_list); + if (!malloc || !realloc || !free) + return NULL; + + list = (struct getdns_list *)(*malloc)(sizeof(struct getdns_list)); if (!list) return NULL; - list->context = context; + list->malloc = malloc; + list->realloc = realloc; + list->free = free; list->numalloc = 0; list->numinuse = 0; list->items = NULL; @@ -230,6 +229,18 @@ getdns_list_create_with_context(getdns_context_t context) return NULL; } return list; +} + +/*-------------------------- getdns_list_create_with_context */ +struct getdns_list * +getdns_list_create_with_context(getdns_context_t context) +{ + if (context) + return getdns_list_create_with_memory_functions(context->malloc, + context->realloc, context->free); + else + return getdns_list_create_with_memory_functions(malloc, + realloc, free); } /* getdns_list_create_with_context */ /*---------------------------------------- getdns_list_create */ @@ -259,7 +270,7 @@ getdns_list_destroy(struct getdns_list *list) break; case t_bindata: - getdns_bindata_destroy(list->context, + getdns_bindata_destroy(list->free, list->items[i].data.bindata); break; @@ -269,8 +280,8 @@ getdns_list_destroy(struct getdns_list *list) } if (list->items) - GETDNS_FREE(list->context, list->items); - GETDNS_FREE(list->context, list); + GETDNS_FREE(list, list->items); + GETDNS_FREE(list, list); } /* getdns_list_destroy */ /*---------------------------------------- getdns_list_add_item */ @@ -362,7 +373,8 @@ getdns_list_set_bindata(struct getdns_list * list, size_t index, if (index >= list->numinuse) return GETDNS_RETURN_NO_SUCH_LIST_ITEM; - newbindata = getdns_bindata_copy(list->context, child_bindata); + newbindata = getdns_bindata_copy( + list->malloc, list->free, child_bindata); if (!newbindata) return GETDNS_RETURN_NO_SUCH_LIST_ITEM; diff --git a/src/list.h b/src/list.h index 54cc9233..2119e458 100644 --- a/src/list.h +++ b/src/list.h @@ -63,7 +63,10 @@ struct getdns_list int numalloc; int numinuse; struct getdns_list_item *items; - getdns_context_t context; + void *(*malloc)(size_t); + void *(*realloc)(void *, size_t); + void (*free)(void *); }; + #endif diff --git a/src/test/tests_dict.c b/src/test/tests_dict.c index 7e2ed8b8..84883ff0 100644 --- a/src/test/tests_dict.c +++ b/src/test/tests_dict.c @@ -248,6 +248,11 @@ tst_getnames(void) getdns_dict_get_names(dict, &list); result = getdns_list_get_length(list, &llen); + if (result != GETDNS_RETURN_GOOD) { + tstmsg_case_msg + ("getdns_list_get_length failed, exiting"); + return; + } if (llen != i) { tstmsg_case_msg ("getdns_list_get_length returned unreasonable length, exiting"); diff --git a/src/test/tests_list.c b/src/test/tests_list.c index 9e0dcbd0..3a0d367b 100644 --- a/src/test/tests_list.c +++ b/src/test/tests_list.c @@ -276,6 +276,7 @@ tst_listsetget(void) retval, ans_int); tstmsg_case_msg(msg); + getdns_list_destroy(new_list); getdns_list_destroy(list); tstmsg_case_end(); diff --git a/src/test/tests_stub_async.c b/src/test/tests_stub_async.c index eed8ef79..d03d5931 100644 --- a/src/test/tests_stub_async.c +++ b/src/test/tests_stub_async.c @@ -48,8 +48,8 @@ this_callbackfn(struct getdns_context_t *this_context, } else if (this_callback_type == GETDNS_CALLBACK_CANCEL) fprintf(stderr, - "The callback with ID %lld was cancelled. Exiting.", - this_transaction_id); + "The callback with ID %llu was cancelled. Exiting.", + (unsigned long long)this_transaction_id); else fprintf(stderr, "The callback got a callback_type of %d. Exiting.", diff --git a/src/types-internal.h b/src/types-internal.h index 0c04fe8b..3abe5e4b 100644 --- a/src/types-internal.h +++ b/src/types-internal.h @@ -134,6 +134,21 @@ typedef struct getdns_dns_req } getdns_dns_req; +#define GETDNS_XMALLOC(obj, type, count) \ + ((obj) ? ((type *) (*(obj)->malloc)((count)*sizeof(type))) \ + : ((type *) malloc ((count)*sizeof(type)))) + +#define GETDNS_XREALLOC(obj, ptr, type, count) \ + ((obj) ? ((type *) (*(obj)->realloc)((ptr),(count)*sizeof(type))) \ + : ((type *) realloc ((ptr),(count)*sizeof(type)))) + +#define GETDNS_FREE(obj, ptr) \ + ((obj) ? ((*(obj)->free)(ptr)) : free(ptr)) + +#define GETDNS_MALLOC(obj, type) GETDNS_XMALLOC(obj, type, 1) +#define GETDNS_REALLOC(obj, ptr, type) GETDNS_XREALLOC(obj, ptr, type, 1); + + /* utility methods */ /* network request utilities */