From 8fe9da650306a1f9ca40113e164c0ab530d0d550 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Sun, 8 Dec 2013 22:56:34 +0100 Subject: [PATCH 1/4] Header functions, structs/unions and macro's --- src/context.c | 17 +++++++++----- src/context.h | 6 ++--- src/dict.c | 25 ++++++++++++--------- src/dict.h | 6 ++--- src/getdns/getdns.h | 51 +++++++++++++++++++++++++++++++++++------- src/list.c | 19 +++++++++------- src/list.h | 7 +++--- src/request-internal.c | 13 +++++------ src/types-internal.h | 42 ++++++++++++++++++++++++++++------ 9 files changed, 128 insertions(+), 58 deletions(-) diff --git a/src/context.c b/src/context.c index a861273d..4985aaff 100644 --- a/src/context.c +++ b/src/context.c @@ -46,6 +46,8 @@ #include "types-internal.h" #include "util-internal.h" +void *plain_mem_funcs_user_arg = MF_PLAIN; + /* Private functions */ static uint16_t *create_default_namespaces(struct getdns_context *context); static struct getdns_list *create_default_root_servers(); @@ -256,9 +258,11 @@ getdns_context_create_with_memory_functions(struct getdns_context ** context, } result->update_callback = NULL; - result->malloc = malloc; - result->realloc = realloc; - result->free = free; + + result->mf_arg = MF_PLAIN; + result->mf.pln.malloc = malloc; + result->mf.pln.realloc = realloc; + result->mf.pln.free = free; result->event_base_sync = event_base_new(); result->unbound_sync = ub_ctx_create_event(result->event_base_sync); @@ -800,9 +804,10 @@ getdns_context_set_memory_functions(struct getdns_context *context, if (!malloc || !realloc || !free) return GETDNS_RETURN_CONTEXT_UPDATE_FAIL; - context->malloc = malloc; - context->realloc = realloc; - context->free = free; + context->mf_arg = MF_PLAIN; + context->mf.pln.malloc = malloc; + context->mf.pln.realloc = realloc; + context->mf.pln.free = free; dispatch_updated(context, GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS); diff --git a/src/context.h b/src/context.h index 2a04b147..1e5f3964 100644 --- a/src/context.h +++ b/src/context.h @@ -31,6 +31,7 @@ #define _GETDNS_CONTEXT_H_ #include +#include "types-internal.h" struct event_base; struct getdns_dns_req; @@ -58,9 +59,8 @@ struct getdns_context { uint8_t edns_do_bit; getdns_update_callback update_callback; - void *(*malloc)(size_t); - void *(*realloc)(void *, size_t); - void (*free)(void *); + void *mf_arg; + mem_funcs mf; /* Event loop for sync requests */ struct event_base *event_base_sync; diff --git a/src/dict.c b/src/dict.c index 0592ec32..97345010 100644 --- a/src/dict.c +++ b/src/dict.c @@ -64,7 +64,7 @@ getdns_dict_find(struct getdns_dict *dict, char *key, int addifnotfnd) if (!item && addifnotfnd) { /* tsearch will add a node automatically for us */ item = GETDNS_MALLOC(dict, struct getdns_dict_item); - item->node.key = getdns_strdup(dict->malloc, key); + item->node.key = getdns_strdup(dict->mf.pln.malloc, key); item->data.n = 0; ldns_rbtree_insert(&(dict->root), (ldns_rbnode_t *) item); } @@ -84,7 +84,7 @@ getdns_dict_get_names(struct getdns_dict * dict, struct getdns_list ** answer) return GETDNS_RETURN_NO_SUCH_DICT_NAME; *answer = getdns_list_create_with_memory_functions( - dict->malloc, dict->realloc, dict->free); + dict->mf.pln.malloc, dict->mf.pln.realloc, dict->mf.pln.free); if (!*answer) return GETDNS_RETURN_NO_SUCH_DICT_NAME; @@ -200,9 +200,11 @@ getdns_dict_create_with_memory_functions(void *(*malloc)(size_t), if (!dict) return NULL; - dict->malloc = malloc; - dict->realloc = realloc; - dict->free = free; + dict->mf_arg = MF_PLAIN; + dict->mf.pln.malloc = malloc; + dict->mf.pln.realloc = realloc; + dict->mf.pln.free = free; + ldns_rbtree_init(&(dict->root), (int (*)(const void *, const void *)) strcmp); return dict; @@ -214,8 +216,9 @@ struct getdns_dict * getdns_dict_create_with_context(struct getdns_context *context) { if (context) - return getdns_dict_create_with_memory_functions(context->malloc, - context->realloc, context->free); + return getdns_dict_create_with_memory_functions( + context->mf.pln.malloc, + context->mf.pln.realloc, context->mf.pln.free); else return getdns_dict_create_with_memory_functions(&malloc, &realloc, &free); @@ -252,7 +255,7 @@ getdns_dict_copy(struct getdns_dict * srcdict, struct getdns_dict ** dstdict) return GETDNS_RETURN_GOOD; } *dstdict = getdns_dict_create_with_memory_functions( - srcdict->malloc, srcdict->realloc, srcdict->free); + srcdict->mf.pln.malloc, srcdict->mf.pln.realloc, srcdict->mf.pln.free); if (!*dstdict) return GETDNS_RETURN_NO_SUCH_DICT_NAME; @@ -306,7 +309,7 @@ getdns_dict_item_free(ldns_rbnode_t * node, void *arg) switch (item->dtype) { case t_bindata: - getdns_bindata_destroy(dict->free, item->data.bindata); + getdns_bindata_destroy(dict->mf.pln.free, item->data.bindata); break; case t_dict: getdns_dict_destroy(item->data.dict); @@ -398,13 +401,13 @@ getdns_dict_set_bindata(struct getdns_dict * dict, char *name, return GETDNS_RETURN_NO_SUCH_DICT_NAME; newbindata = getdns_bindata_copy( - dict->malloc, dict->free, child_bindata); + dict->mf.pln.malloc, dict->mf.pln.free, child_bindata); if (!newbindata) return GETDNS_RETURN_NO_SUCH_DICT_NAME; item = getdns_dict_find(dict, name, 1); if (!item) { - getdns_bindata_destroy(dict->free, newbindata); + getdns_bindata_destroy(dict->mf.pln.free, newbindata); return GETDNS_RETURN_NO_SUCH_DICT_NAME; } item->dtype = t_bindata; diff --git a/src/dict.h b/src/dict.h index 26a72f96..c21a7bff 100644 --- a/src/dict.h +++ b/src/dict.h @@ -37,6 +37,7 @@ #include #include +#include "types-internal.h" union getdns_item { @@ -66,9 +67,8 @@ struct getdns_dict_item struct getdns_dict { ldns_rbtree_t root; - void *(*malloc)(size_t); - void *(*realloc)(void *, size_t); - void (*free)(void *); + void *mf_arg; + mem_funcs mf; }; #endif diff --git a/src/getdns/getdns.h b/src/getdns/getdns.h index 121aadd8..0ef5c5f3 100644 --- a/src/getdns/getdns.h +++ b/src/getdns/getdns.h @@ -506,8 +506,16 @@ 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(struct getdns_context *context); struct getdns_list *getdns_list_create_with_memory_functions( - void *(*malloc) (size_t), void *(*realloc) (void *, size_t), - void (*free) (void *)); + void *(*malloc) (size_t), + void *(*realloc) (void *, size_t), + void (*free) (void *) +); +struct getdns_list *getdns_list_create_with_extended_memory_functions( + void *userarg, + void *(*malloc) (void *userarg, size_t), + void *(*realloc) (void *userarg, void *, size_t), + void (*free) (void *userarg, void *) +); /** * free memory allocated to the list (also frees all children of the list) @@ -567,8 +575,16 @@ getdns_return_t getdns_list_set_int(struct getdns_list *this_list, size_t index, struct getdns_dict *getdns_dict_create(); struct getdns_dict *getdns_dict_create_with_context(struct getdns_context *context); struct getdns_dict *getdns_dict_create_with_memory_functions( - void *(*malloc) (size_t), void *(*realloc) (void *, size_t), - void (*free) (void *)); + void *(*malloc) (size_t), + void *(*realloc) (void *, size_t), + void (*free) (void *) +); +struct getdns_dict *getdns_dict_create_with_extended_memory_functions( + void *userarg, + void *(*malloc) (void *userarg, size_t), + void *(*realloc) (void *userarg, void *, size_t), + void (*free) (void *userarg, void *) +); /** * destroy a dictionary and all items within that dictionary @@ -643,16 +659,27 @@ getdns_service(struct getdns_context *context, void *userarg, getdns_transaction_t * transaction_id, getdns_callback_t callbackfn); -getdns_return_t getdns_context_create_with_memory_functions( +getdns_return_t +getdns_context_create(struct getdns_context ** context, int set_from_os); + +getdns_return_t +getdns_context_create_with_memory_functions( struct getdns_context ** context, int set_from_os, void *(*malloc) (size_t), void *(*realloc) (void *, size_t), void (*free) (void *) - ); +); -getdns_return_t getdns_context_create(struct getdns_context ** context, - int set_from_os); +getdns_return_t +getdns_context_create_with_extended_memory_functions( + struct getdns_context **context, + int set_from_os, + void *userarg, + void *(*malloc) (void *userarg, size_t), + void *(*realloc) (void *userarg, void *, size_t), + void (*free) (void *userarg, void *) +); void getdns_context_destroy(struct getdns_context *context); @@ -832,6 +859,14 @@ getdns_context_set_memory_functions(struct getdns_context *context, void (*free) (void *) ); +getdns_return_t +getdns_context_set_extended_memory_functions(struct getdns_context *context, + void *userarg, + void *(*malloc) (void *userarg, size_t sz), + void *(*realloc) (void *userarg, void *ptr, size_t sz), + void (*free) (void *userarg, void *ptr) + ); + /* Extension - refactor to abstract async evt loop */ /* For libevent, which we are using for these examples */ getdns_return_t diff --git a/src/list.c b/src/list.c index c3890487..70099bfb 100644 --- a/src/list.c +++ b/src/list.c @@ -165,7 +165,7 @@ getdns_list_copy(struct getdns_list * srclist, struct getdns_list ** dstlist) return GETDNS_RETURN_GOOD; } *dstlist = getdns_list_create_with_memory_functions( - srclist->malloc, srclist->realloc, srclist->free); + srclist->mf.pln.malloc, srclist->mf.pln.realloc, srclist->mf.pln.free); if (!dstlist) return GETDNS_RETURN_NO_SUCH_LIST_ITEM; @@ -219,9 +219,11 @@ getdns_list_create_with_memory_functions(void *(*malloc)(size_t), if (!list) return NULL; - list->malloc = malloc; - list->realloc = realloc; - list->free = free; + list->mf_arg = MF_PLAIN; + list->mf.pln.malloc = malloc; + list->mf.pln.realloc = realloc; + list->mf.pln.free = free; + list->numalloc = 0; list->numinuse = 0; list->items = NULL; @@ -237,8 +239,9 @@ struct getdns_list * getdns_list_create_with_context(struct getdns_context *context) { if (context) - return getdns_list_create_with_memory_functions(context->malloc, - context->realloc, context->free); + return getdns_list_create_with_memory_functions( + context->mf.pln.malloc, + context->mf.pln.realloc, context->mf.pln.free); else return getdns_list_create_with_memory_functions(malloc, realloc, free); @@ -271,7 +274,7 @@ getdns_list_destroy(struct getdns_list *list) break; case t_bindata: - getdns_bindata_destroy(list->free, + getdns_bindata_destroy(list->mf.pln.free, list->items[i].data.bindata); break; @@ -375,7 +378,7 @@ getdns_list_set_bindata(struct getdns_list * list, size_t index, return GETDNS_RETURN_NO_SUCH_LIST_ITEM; newbindata = getdns_bindata_copy( - list->malloc, list->free, child_bindata); + list->mf.pln.malloc, list->mf.pln.free, child_bindata); if (!newbindata) return GETDNS_RETURN_NO_SUCH_LIST_ITEM; diff --git a/src/list.h b/src/list.h index d5267769..88d5b02b 100644 --- a/src/list.h +++ b/src/list.h @@ -31,6 +31,7 @@ #define _GETDNS_LIST_H_ #include +#include "types-internal.h" #define GETDNS_LIST_BLOCKSZ 10 @@ -63,10 +64,8 @@ struct getdns_list int numalloc; int numinuse; struct getdns_list_item *items; - void *(*malloc)(size_t); - void *(*realloc)(void *, size_t); - void (*free)(void *); + void *mf_arg; + mem_funcs mf; }; - #endif diff --git a/src/request-internal.c b/src/request-internal.c index 093a90db..edbd85f6 100644 --- a/src/request-internal.c +++ b/src/request-internal.c @@ -44,10 +44,6 @@ #include "util-internal.h" #include -/* useful macros */ -#define gd_malloc(sz) context->malloc(sz) -#define gd_free(ptr) context->free(ptr) - void network_req_free(getdns_network_req * net_req) { @@ -58,7 +54,7 @@ network_req_free(getdns_network_req * net_req) if (net_req->result) { ldns_pkt_free(net_req->result); } - gd_free(net_req); + GETDNS_FREE(context, net_req); } getdns_network_req * @@ -68,7 +64,8 @@ network_req_new(getdns_dns_req * owner, { struct getdns_context *context = owner->context; - getdns_network_req *net_req = gd_malloc(sizeof(getdns_network_req)); + getdns_network_req *net_req = GETDNS_MALLOC( context + , getdns_network_req); if (!net_req) { return NULL; } @@ -120,7 +117,7 @@ dns_req_free(getdns_dns_req * req) /* free strduped name */ free(req->name); - gd_free(req); + GETDNS_FREE(context, req); } /* create a new dns req to be submitted */ @@ -135,7 +132,7 @@ dns_req_new(struct getdns_context *context, getdns_return_t r; uint32_t both = GETDNS_EXTENSION_FALSE; - result = gd_malloc(sizeof(getdns_dns_req)); + result = GETDNS_MALLOC(context, getdns_dns_req); if (result == NULL) { return NULL; } diff --git a/src/types-internal.h b/src/types-internal.h index 2859f6d2..59709572 100644 --- a/src/types-internal.h +++ b/src/types-internal.h @@ -36,8 +36,9 @@ #ifndef TYPES_INTERNAL_H_ #define TYPES_INTERNAL_H_ -#include "context.h" +#include #include +struct getdns_context; /** * \defgroup strings String Constants @@ -175,16 +176,43 @@ typedef struct getdns_dns_req } getdns_dns_req; +#define MF_PLAIN ((void *)&plain_mem_funcs_user_arg) +extern void *plain_mem_funcs_user_arg; + +typedef union { + struct { + void *(*malloc)(size_t); + void *(*realloc)(void *, size_t); + void (*free)(void *); + } pln; + struct { + void *(*malloc)(void *userarg, size_t); + void *(*realloc)(void *userarg, void *, size_t); + void (*free)(void *userarg, void *); + } ext; +} mem_funcs; + #define GETDNS_XMALLOC(obj, type, count) \ - ((obj) ? ((type *) (*(obj)->malloc)((count)*sizeof(type))) \ - : ((type *) malloc ((count)*sizeof(type)))) + ((!(obj)) ? ((type *)malloc((count)*sizeof(type))) \ + : ((obj)->mf_arg == MF_PLAIN \ + ? ((type *)(*(obj)->mf.pln.malloc)( (count)*sizeof(type))) \ + : ((type *)(*(obj)->mf.ext.malloc)((obj)->mf_arg, (count)*sizeof(type))) \ + )) #define GETDNS_XREALLOC(obj, ptr, type, count) \ - ((obj) ? ((type *) (*(obj)->realloc)((ptr),(count)*sizeof(type))) \ - : ((type *) realloc ((ptr),(count)*sizeof(type)))) + ((!(obj)) ? ((type *)realloc((ptr), (count)*sizeof(type))) \ + : ((obj)->mf_arg == MF_PLAIN \ + ? ((type *)(*(obj)->mf.pln.realloc)( (ptr), (count)*sizeof(type))) \ + : ((type *)(*(obj)->mf.ext.realloc)( (obj)->mf_arg \ + , (ptr), (count)*sizeof(type))) \ + )) -#define GETDNS_FREE(obj, ptr) \ - ((obj) ? ((*(obj)->free)(ptr)) : free(ptr)) +#define GETDNS_FREE(obj, ptr) \ + ((!(obj)) ? free(ptr) \ + : ((obj)->mf_arg == MF_PLAIN \ + ? ((*(obj)->mf.pln.free)( (ptr))) \ + : ((*(obj)->mf.ext.free)((obj)->mf_arg, (ptr))) \ + )) #define GETDNS_MALLOC(obj, type) GETDNS_XMALLOC(obj, type, 1) #define GETDNS_REALLOC(obj, ptr, type) GETDNS_XREALLOC(obj, ptr, type, 1); From 70e5193b3fd928233b9a177e55e0e7984a27d298 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Sun, 8 Dec 2013 23:15:57 +0100 Subject: [PATCH 2/4] Context has own mem-funcs It keeps using mem funcs for internal state that were given upon context creation. Only dicts and lists are created with mem funcs set by getdns_context_set_memory_functions --- src/context.c | 22 +++++++++++++--------- src/context.h | 5 +++++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/context.c b/src/context.c index 4985aaff..76fb2bf3 100644 --- a/src/context.c +++ b/src/context.c @@ -74,7 +74,7 @@ static void cancel_dns_req(getdns_dns_req *); static uint16_t * create_default_namespaces(struct getdns_context *context) { - uint16_t *result = GETDNS_XMALLOC(context, uint16_t, 2); + uint16_t *result = GETDNS_XMALLOC(&context->my_mf, uint16_t, 2); result[0] = GETDNS_CONTEXT_NAMESPACE_LOCALNAMES; result[1] = GETDNS_CONTEXT_NAMESPACE_DNS; return result; @@ -256,6 +256,10 @@ getdns_context_create_with_memory_functions(struct getdns_context ** context, if (!result) { return GETDNS_RETURN_GENERIC_ERROR; } + result->my_mf.mf_arg = MF_PLAIN; + result->my_mf.mf.pln.malloc = malloc; + result->my_mf.mf.pln.realloc = realloc; + result->my_mf.mf.pln.free = free; result->update_callback = NULL; @@ -334,7 +338,7 @@ getdns_context_destroy(struct getdns_context *context) return; } if (context->namespaces) - GETDNS_FREE(context, context->namespaces); + GETDNS_FREE(&context->my_mf, context->namespaces); getdns_list_destroy(context->dns_root_servers); getdns_list_destroy(context->suffix); @@ -349,7 +353,7 @@ getdns_context_destroy(struct getdns_context *context) ldns_rbtree_free(context->outbound_requests); - GETDNS_FREE(context, context); + GETDNS_FREE(&context->my_mf, context); return; } /* getdns_context_destroy */ @@ -450,10 +454,10 @@ getdns_context_set_namespaces(struct getdns_context *context, } /** clean up old namespaces **/ - GETDNS_FREE(context, context->namespaces); + GETDNS_FREE(&context->my_mf, context->namespaces); /** duplicate **/ - context->namespaces = GETDNS_XMALLOC(context, uint16_t, + context->namespaces = GETDNS_XMALLOC(&context->my_mf, uint16_t, namespace_count); memcpy(context->namespaces, namespaces, namespace_count * sizeof(uint16_t)); @@ -879,7 +883,7 @@ getdns_context_cancel_request(struct getdns_context *context, user_pointer = req->user_pointer; /* clean up */ - GETDNS_FREE(context, node); + GETDNS_FREE(&context->my_mf, node); dns_req_free(req); /* fire callback */ @@ -964,7 +968,7 @@ getdns_context_track_outbound_request(getdns_dns_req * req) return GETDNS_RETURN_GENERIC_ERROR; } struct getdns_context *context = req->context; - ldns_rbnode_t *node = GETDNS_MALLOC(context, ldns_rbnode_t); + ldns_rbnode_t *node = GETDNS_MALLOC(&context->my_mf, ldns_rbnode_t); if (!node) { return GETDNS_RETURN_GENERIC_ERROR; } @@ -972,7 +976,7 @@ getdns_context_track_outbound_request(getdns_dns_req * req) node->data = req; if (!ldns_rbtree_insert(context->outbound_requests, node)) { /* free the node */ - GETDNS_FREE(context, node); + GETDNS_FREE(&context->my_mf, node); return GETDNS_RETURN_GENERIC_ERROR; } return GETDNS_RETURN_GOOD; @@ -988,7 +992,7 @@ getdns_context_clear_outbound_request(getdns_dns_req * req) ldns_rbnode_t *node = ldns_rbtree_delete(context->outbound_requests, &(req->trans_id)); if (node) { - GETDNS_FREE(context, node); + GETDNS_FREE(&context->my_mf, node); } return GETDNS_RETURN_GOOD; } diff --git a/src/context.h b/src/context.h index 1e5f3964..dc5c23f9 100644 --- a/src/context.h +++ b/src/context.h @@ -62,6 +62,11 @@ struct getdns_context { void *mf_arg; mem_funcs mf; + struct { + void *mf_arg; + mem_funcs mf; + } my_mf; + /* Event loop for sync requests */ struct event_base *event_base_sync; /* Event loop for async requests */ From c80cab692935955dcfdb5f83204cab80f288fc67 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 9 Dec 2013 00:05:18 +0100 Subject: [PATCH 3/4] getdns_strdup, getdns_bindata_(copy|destroy) Restructure a bit to make that work too --- src/context.c | 53 +++++++++++++++++++-------------------- src/context.h | 15 +++++------ src/dict.c | 35 +++++++++++++------------- src/dict.h | 3 +-- src/list.c | 30 ++++++++++++---------- src/list.h | 3 +-- src/request-internal.c | 8 +++--- src/types-internal.h | 56 +++++++++++++++++++++--------------------- 8 files changed, 102 insertions(+), 101 deletions(-) diff --git a/src/context.c b/src/context.c index 76fb2bf3..61291768 100644 --- a/src/context.c +++ b/src/context.c @@ -74,7 +74,7 @@ static void cancel_dns_req(getdns_dns_req *); static uint16_t * create_default_namespaces(struct getdns_context *context) { - uint16_t *result = GETDNS_XMALLOC(&context->my_mf, uint16_t, 2); + uint16_t *result = GETDNS_XMALLOC(context->my_mf, uint16_t, 2); result[0] = GETDNS_CONTEXT_NAMESPACE_LOCALNAMES; result[1] = GETDNS_CONTEXT_NAMESPACE_DNS; return result; @@ -263,10 +263,10 @@ getdns_context_create_with_memory_functions(struct getdns_context ** context, result->update_callback = NULL; - result->mf_arg = MF_PLAIN; - result->mf.pln.malloc = malloc; - result->mf.pln.realloc = realloc; - result->mf.pln.free = free; + result->mf.mf_arg = MF_PLAIN; + result->mf.mf.pln.malloc = malloc; + result->mf.mf.pln.realloc = realloc; + result->mf.mf.pln.free = free; result->event_base_sync = event_base_new(); result->unbound_sync = ub_ctx_create_event(result->event_base_sync); @@ -338,7 +338,7 @@ getdns_context_destroy(struct getdns_context *context) return; } if (context->namespaces) - GETDNS_FREE(&context->my_mf, context->namespaces); + GETDNS_FREE(context->my_mf, context->namespaces); getdns_list_destroy(context->dns_root_servers); getdns_list_destroy(context->suffix); @@ -353,7 +353,7 @@ getdns_context_destroy(struct getdns_context *context) ldns_rbtree_free(context->outbound_requests); - GETDNS_FREE(&context->my_mf, context); + GETDNS_FREE(context->my_mf, context); return; } /* getdns_context_destroy */ @@ -454,10 +454,10 @@ getdns_context_set_namespaces(struct getdns_context *context, } /** clean up old namespaces **/ - GETDNS_FREE(&context->my_mf, context->namespaces); + GETDNS_FREE(context->my_mf, context->namespaces); /** duplicate **/ - context->namespaces = GETDNS_XMALLOC(&context->my_mf, uint16_t, + context->namespaces = GETDNS_XMALLOC(context->my_mf, uint16_t, namespace_count); memcpy(context->namespaces, namespaces, namespace_count * sizeof(uint16_t)); @@ -808,10 +808,10 @@ getdns_context_set_memory_functions(struct getdns_context *context, if (!malloc || !realloc || !free) return GETDNS_RETURN_CONTEXT_UPDATE_FAIL; - context->mf_arg = MF_PLAIN; - context->mf.pln.malloc = malloc; - context->mf.pln.realloc = realloc; - context->mf.pln.free = free; + context->mf.mf_arg = MF_PLAIN; + context->mf.mf.pln.malloc = malloc; + context->mf.mf.pln.realloc = realloc; + context->mf.mf.pln.free = free; dispatch_updated(context, GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS); @@ -883,7 +883,7 @@ getdns_context_cancel_request(struct getdns_context *context, user_pointer = req->user_pointer; /* clean up */ - GETDNS_FREE(&context->my_mf, node); + GETDNS_FREE(context->my_mf, node); dns_req_free(req); /* fire callback */ @@ -968,7 +968,7 @@ getdns_context_track_outbound_request(getdns_dns_req * req) return GETDNS_RETURN_GENERIC_ERROR; } struct getdns_context *context = req->context; - ldns_rbnode_t *node = GETDNS_MALLOC(&context->my_mf, ldns_rbnode_t); + ldns_rbnode_t *node = GETDNS_MALLOC(context->my_mf, ldns_rbnode_t); if (!node) { return GETDNS_RETURN_GENERIC_ERROR; } @@ -976,7 +976,7 @@ getdns_context_track_outbound_request(getdns_dns_req * req) node->data = req; if (!ldns_rbtree_insert(context->outbound_requests, node)) { /* free the node */ - GETDNS_FREE(&context->my_mf, node); + GETDNS_FREE(context->my_mf, node); return GETDNS_RETURN_GENERIC_ERROR; } return GETDNS_RETURN_GOOD; @@ -992,16 +992,16 @@ getdns_context_clear_outbound_request(getdns_dns_req * req) ldns_rbnode_t *node = ldns_rbtree_delete(context->outbound_requests, &(req->trans_id)); if (node) { - GETDNS_FREE(&context->my_mf, node); + GETDNS_FREE(context->my_mf, node); } return GETDNS_RETURN_GOOD; } char * -getdns_strdup(void *(*malloc)(size_t), const char *s) +getdns_strdup(struct mem_funcs *mfs, const char *s) { size_t sz = strlen(s) + 1; - char *r = (char *)(*malloc)(sizeof(char) * sz); + char *r = GETDNS_XMALLOC(*mfs, char, sz); if (r) return memcpy(r, s, sz); else @@ -1009,7 +1009,7 @@ getdns_strdup(void *(*malloc)(size_t), const char *s) } struct getdns_bindata * -getdns_bindata_copy(void *(*malloc)(size_t), void (*free)(void *), +getdns_bindata_copy(struct mem_funcs *mfs, const struct getdns_bindata *src) { struct getdns_bindata *dst; @@ -1017,14 +1017,14 @@ getdns_bindata_copy(void *(*malloc)(size_t), void (*free)(void *), if (!src) return NULL; - dst = (struct getdns_bindata *)(*malloc)(sizeof(struct getdns_bindata)); + dst = GETDNS_MALLOC(*mfs, struct getdns_bindata); if (!dst) return NULL; dst->size = src->size; - dst->data = (uint8_t *)(*malloc)(sizeof(uint8_t) * src->size); + dst->data = GETDNS_XMALLOC(*mfs, uint8_t, src->size); if (!dst->data) { - (*free)(dst); + GETDNS_FREE(*mfs, dst); return NULL; } (void) memcpy(dst->data, src->data, src->size); @@ -1032,11 +1032,12 @@ getdns_bindata_copy(void *(*malloc)(size_t), void (*free)(void *), } void -getdns_bindata_destroy(void (*free)(void *), struct getdns_bindata *bindata) +getdns_bindata_destroy(struct mem_funcs *mfs, + struct getdns_bindata *bindata) { if (!bindata) return; - (*free)(bindata->data); - (*free)(bindata); + GETDNS_FREE(*mfs, bindata->data); + GETDNS_FREE(*mfs, bindata); } /* getdns_context.c */ diff --git a/src/context.h b/src/context.h index dc5c23f9..803e90a3 100644 --- a/src/context.h +++ b/src/context.h @@ -59,13 +59,9 @@ struct getdns_context { uint8_t edns_do_bit; getdns_update_callback update_callback; - void *mf_arg; - mem_funcs mf; - struct { - void *mf_arg; - mem_funcs mf; - } my_mf; + struct mem_funcs mf; + struct mem_funcs my_mf; /* Event loop for sync requests */ struct event_base *event_base_sync; @@ -105,13 +101,14 @@ getdns_return_t getdns_context_clear_outbound_request(struct getdns_dns_req getdns_return_t getdns_context_cancel_request(struct getdns_context *context, getdns_transaction_t transaction_id, int fire_callback); -char *getdns_strdup(void *(*malloc)(size_t), const char *str); +char *getdns_strdup(struct mem_funcs *mfs, const char *str); struct getdns_bindata *getdns_bindata_copy( - void *(*malloc)(size_t), void (*free)(void *), + struct mem_funcs *mfs, const struct getdns_bindata *src); -void getdns_bindata_destroy(void (*free)(void *), +void getdns_bindata_destroy( + struct mem_funcs *mfs, struct getdns_bindata *bindata); #endif /* _GETDNS_CONTEXT_H_ */ diff --git a/src/dict.c b/src/dict.c index 97345010..ed414167 100644 --- a/src/dict.c +++ b/src/dict.c @@ -63,8 +63,8 @@ getdns_dict_find(struct getdns_dict *dict, char *key, int addifnotfnd) if (!item && addifnotfnd) { /* tsearch will add a node automatically for us */ - item = GETDNS_MALLOC(dict, struct getdns_dict_item); - item->node.key = getdns_strdup(dict->mf.pln.malloc, key); + item = GETDNS_MALLOC(dict->mf, struct getdns_dict_item); + item->node.key = getdns_strdup(&dict->mf, key); item->data.n = 0; ldns_rbtree_insert(&(dict->root), (ldns_rbnode_t *) item); } @@ -84,7 +84,7 @@ getdns_dict_get_names(struct getdns_dict * dict, struct getdns_list ** answer) return GETDNS_RETURN_NO_SUCH_DICT_NAME; *answer = getdns_list_create_with_memory_functions( - dict->mf.pln.malloc, dict->mf.pln.realloc, dict->mf.pln.free); + dict->mf.mf.pln.malloc, dict->mf.mf.pln.realloc, dict->mf.mf.pln.free); if (!*answer) return GETDNS_RETURN_NO_SUCH_DICT_NAME; @@ -200,10 +200,10 @@ getdns_dict_create_with_memory_functions(void *(*malloc)(size_t), if (!dict) return NULL; - dict->mf_arg = MF_PLAIN; - dict->mf.pln.malloc = malloc; - dict->mf.pln.realloc = realloc; - dict->mf.pln.free = free; + dict->mf.mf_arg = MF_PLAIN; + dict->mf.mf.pln.malloc = malloc; + dict->mf.mf.pln.realloc = realloc; + dict->mf.mf.pln.free = free; ldns_rbtree_init(&(dict->root), (int (*)(const void *, const void *)) strcmp); @@ -217,8 +217,8 @@ getdns_dict_create_with_context(struct getdns_context *context) { if (context) return getdns_dict_create_with_memory_functions( - context->mf.pln.malloc, - context->mf.pln.realloc, context->mf.pln.free); + context->mf.mf.pln.malloc, + context->mf.mf.pln.realloc, context->mf.mf.pln.free); else return getdns_dict_create_with_memory_functions(&malloc, &realloc, &free); @@ -255,7 +255,9 @@ getdns_dict_copy(struct getdns_dict * srcdict, struct getdns_dict ** dstdict) return GETDNS_RETURN_GOOD; } *dstdict = getdns_dict_create_with_memory_functions( - srcdict->mf.pln.malloc, srcdict->mf.pln.realloc, srcdict->mf.pln.free); + srcdict->mf.mf.pln.malloc, + srcdict->mf.mf.pln.realloc, + srcdict->mf.mf.pln.free); if (!*dstdict) return GETDNS_RETURN_NO_SUCH_DICT_NAME; @@ -309,7 +311,7 @@ getdns_dict_item_free(ldns_rbnode_t * node, void *arg) switch (item->dtype) { case t_bindata: - getdns_bindata_destroy(dict->mf.pln.free, item->data.bindata); + getdns_bindata_destroy(&dict->mf, item->data.bindata); break; case t_dict: getdns_dict_destroy(item->data.dict); @@ -321,8 +323,8 @@ getdns_dict_item_free(ldns_rbnode_t * node, void *arg) break; } if (item->node.key) - GETDNS_FREE(dict, (void *)item->node.key); - GETDNS_FREE(dict, item); + GETDNS_FREE(dict->mf, (void *)item->node.key); + GETDNS_FREE(dict->mf, item); } /* getdns_dict_item_free */ /*---------------------------------------- getdns_dict_destroy */ @@ -334,7 +336,7 @@ getdns_dict_destroy(struct getdns_dict *dict) ldns_traverse_postorder(&(dict->root), getdns_dict_item_free, dict); - GETDNS_FREE(dict, dict); + GETDNS_FREE(dict->mf, dict); } /* getdns_dict_destroy */ /*---------------------------------------- getdns_dict_set_dict */ @@ -400,14 +402,13 @@ 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->mf.pln.malloc, dict->mf.pln.free, child_bindata); + newbindata = getdns_bindata_copy(&dict->mf, child_bindata); if (!newbindata) return GETDNS_RETURN_NO_SUCH_DICT_NAME; item = getdns_dict_find(dict, name, 1); if (!item) { - getdns_bindata_destroy(dict->mf.pln.free, newbindata); + getdns_bindata_destroy(&dict->mf, newbindata); return GETDNS_RETURN_NO_SUCH_DICT_NAME; } item->dtype = t_bindata; diff --git a/src/dict.h b/src/dict.h index c21a7bff..caee054a 100644 --- a/src/dict.h +++ b/src/dict.h @@ -67,8 +67,7 @@ struct getdns_dict_item struct getdns_dict { ldns_rbtree_t root; - void *mf_arg; - mem_funcs mf; + struct mem_funcs mf; }; #endif diff --git a/src/list.c b/src/list.c index 70099bfb..ec81d7d9 100644 --- a/src/list.c +++ b/src/list.c @@ -138,7 +138,7 @@ getdns_list_realloc(struct getdns_list *list) if (!list) return GETDNS_RETURN_GENERIC_ERROR; - newlist = GETDNS_XREALLOC(list, list->items, + newlist = GETDNS_XREALLOC(list->mf, list->items, struct getdns_list_item, list->numalloc + GETDNS_LIST_BLOCKSZ); if (!newlist) @@ -165,7 +165,10 @@ getdns_list_copy(struct getdns_list * srclist, struct getdns_list ** dstlist) return GETDNS_RETURN_GOOD; } *dstlist = getdns_list_create_with_memory_functions( - srclist->mf.pln.malloc, srclist->mf.pln.realloc, srclist->mf.pln.free); + srclist->mf.mf.pln.malloc, + srclist->mf.mf.pln.realloc, + srclist->mf.mf.pln.free + ); if (!dstlist) return GETDNS_RETURN_NO_SUCH_LIST_ITEM; @@ -219,10 +222,10 @@ getdns_list_create_with_memory_functions(void *(*malloc)(size_t), if (!list) return NULL; - list->mf_arg = MF_PLAIN; - list->mf.pln.malloc = malloc; - list->mf.pln.realloc = realloc; - list->mf.pln.free = free; + list->mf.mf_arg = MF_PLAIN; + list->mf.mf.pln.malloc = malloc; + list->mf.mf.pln.realloc = realloc; + list->mf.mf.pln.free = free; list->numalloc = 0; list->numinuse = 0; @@ -240,8 +243,10 @@ getdns_list_create_with_context(struct getdns_context *context) { if (context) return getdns_list_create_with_memory_functions( - context->mf.pln.malloc, - context->mf.pln.realloc, context->mf.pln.free); + context->mf.mf.pln.malloc, + context->mf.mf.pln.realloc, + context->mf.mf.pln.free + ); else return getdns_list_create_with_memory_functions(malloc, realloc, free); @@ -274,7 +279,7 @@ getdns_list_destroy(struct getdns_list *list) break; case t_bindata: - getdns_bindata_destroy(list->mf.pln.free, + getdns_bindata_destroy(&list->mf, list->items[i].data.bindata); break; @@ -284,8 +289,8 @@ getdns_list_destroy(struct getdns_list *list) } if (list->items) - GETDNS_FREE(list, list->items); - GETDNS_FREE(list, list); + GETDNS_FREE(list->mf, list->items); + GETDNS_FREE(list->mf, list); } /* getdns_list_destroy */ /*---------------------------------------- getdns_list_add_item */ @@ -377,8 +382,7 @@ 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->mf.pln.malloc, list->mf.pln.free, child_bindata); + newbindata = getdns_bindata_copy(&list->mf, child_bindata); if (!newbindata) return GETDNS_RETURN_NO_SUCH_LIST_ITEM; diff --git a/src/list.h b/src/list.h index 88d5b02b..b37266ae 100644 --- a/src/list.h +++ b/src/list.h @@ -64,8 +64,7 @@ struct getdns_list int numalloc; int numinuse; struct getdns_list_item *items; - void *mf_arg; - mem_funcs mf; + struct mem_funcs mf; }; #endif diff --git a/src/request-internal.c b/src/request-internal.c index edbd85f6..7a11554a 100644 --- a/src/request-internal.c +++ b/src/request-internal.c @@ -54,7 +54,7 @@ network_req_free(getdns_network_req * net_req) if (net_req->result) { ldns_pkt_free(net_req->result); } - GETDNS_FREE(context, net_req); + GETDNS_FREE(context->mf, net_req); } getdns_network_req * @@ -64,7 +64,7 @@ network_req_new(getdns_dns_req * owner, { struct getdns_context *context = owner->context; - getdns_network_req *net_req = GETDNS_MALLOC( context + getdns_network_req *net_req = GETDNS_MALLOC( context->mf , getdns_network_req); if (!net_req) { return NULL; @@ -117,7 +117,7 @@ dns_req_free(getdns_dns_req * req) /* free strduped name */ free(req->name); - GETDNS_FREE(context, req); + GETDNS_FREE(context->mf, req); } /* create a new dns req to be submitted */ @@ -132,7 +132,7 @@ dns_req_new(struct getdns_context *context, getdns_return_t r; uint32_t both = GETDNS_EXTENSION_FALSE; - result = GETDNS_MALLOC(context, getdns_dns_req); + result = GETDNS_MALLOC(context->mf, getdns_dns_req); if (result == NULL) { return NULL; } diff --git a/src/types-internal.h b/src/types-internal.h index 59709572..73c21cd2 100644 --- a/src/types-internal.h +++ b/src/types-internal.h @@ -179,40 +179,40 @@ typedef struct getdns_dns_req #define MF_PLAIN ((void *)&plain_mem_funcs_user_arg) extern void *plain_mem_funcs_user_arg; -typedef union { - struct { - void *(*malloc)(size_t); - void *(*realloc)(void *, size_t); - void (*free)(void *); - } pln; - struct { - void *(*malloc)(void *userarg, size_t); - void *(*realloc)(void *userarg, void *, size_t); - void (*free)(void *userarg, void *); - } ext; -} mem_funcs; +struct mem_funcs { + void *mf_arg; + union { + struct { + void *(*malloc)(size_t); + void *(*realloc)(void *, size_t); + void (*free)(void *); + } pln; + struct { + void *(*malloc)(void *userarg, size_t); + void *(*realloc)(void *userarg, void *, size_t); + void (*free)(void *userarg, void *); + } ext; + } mf; +}; #define GETDNS_XMALLOC(obj, type, count) \ - ((!(obj)) ? ((type *)malloc((count)*sizeof(type))) \ - : ((obj)->mf_arg == MF_PLAIN \ - ? ((type *)(*(obj)->mf.pln.malloc)( (count)*sizeof(type))) \ - : ((type *)(*(obj)->mf.ext.malloc)((obj)->mf_arg, (count)*sizeof(type))) \ - )) + ((obj).mf_arg == MF_PLAIN \ + ? ((type *)(*(obj).mf.pln.malloc)( (count)*sizeof(type))) \ + : ((type *)(*(obj).mf.ext.malloc)((obj).mf_arg, (count)*sizeof(type))) \ + ) #define GETDNS_XREALLOC(obj, ptr, type, count) \ - ((!(obj)) ? ((type *)realloc((ptr), (count)*sizeof(type))) \ - : ((obj)->mf_arg == MF_PLAIN \ - ? ((type *)(*(obj)->mf.pln.realloc)( (ptr), (count)*sizeof(type))) \ - : ((type *)(*(obj)->mf.ext.realloc)( (obj)->mf_arg \ - , (ptr), (count)*sizeof(type))) \ - )) + ((obj).mf_arg == MF_PLAIN \ + ? ((type *)(*(obj).mf.pln.realloc)( (ptr), (count)*sizeof(type))) \ + : ((type *)(*(obj).mf.ext.realloc)( (obj).mf_arg \ + , (ptr), (count)*sizeof(type))) \ + ) #define GETDNS_FREE(obj, ptr) \ - ((!(obj)) ? free(ptr) \ - : ((obj)->mf_arg == MF_PLAIN \ - ? ((*(obj)->mf.pln.free)( (ptr))) \ - : ((*(obj)->mf.ext.free)((obj)->mf_arg, (ptr))) \ - )) + ((obj).mf_arg == MF_PLAIN \ + ? ((*(obj).mf.pln.free)( (ptr))) \ + : ((*(obj).mf.ext.free)((obj).mf_arg, (ptr))) \ + ) #define GETDNS_MALLOC(obj, type) GETDNS_XMALLOC(obj, type, 1) #define GETDNS_REALLOC(obj, ptr, type) GETDNS_XREALLOC(obj, ptr, type, 1); From 3dfe92da6498b89fd2d8dabdc2fd0781796acfcf Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 9 Dec 2013 00:52:38 +0100 Subject: [PATCH 4/4] extended memory functions --- src/context.c | 104 ++++++++++++++++++++++++++++++++----------- src/dict.c | 54 +++++++++++++++------- src/list.c | 54 +++++++++++++++------- src/types-internal.h | 10 +++-- 4 files changed, 160 insertions(+), 62 deletions(-) diff --git a/src/context.c b/src/context.c index 61291768..50ee71c3 100644 --- a/src/context.c +++ b/src/context.c @@ -239,34 +239,40 @@ transaction_id_cmp(const void *id1, const void *id2) * Call this to initialize the context that is used in other getdns calls. */ getdns_return_t -getdns_context_create_with_memory_functions(struct getdns_context ** context, +getdns_context_create_with_extended_memory_functions( + struct getdns_context ** context, int set_from_os, - void *(*malloc)(size_t), - void *(*realloc)(void *, size_t), - void (*free)(void *) + void *userarg, + void *(*malloc)(void *userarg, size_t), + void *(*realloc)(void *userarg, void *, size_t), + void (*free)(void *userarg, void *) ) { struct getdns_context *result = NULL; + mf_union mf; if (!context || !malloc || !realloc || !free) return GETDNS_RETURN_GENERIC_ERROR; /** default init **/ - result = (*malloc)(sizeof(struct getdns_context)); + mf.ext.malloc = malloc; + result = userarg == MF_PLAIN + ? (*mf.pln.malloc)( sizeof(struct getdns_context)) + : (*mf.ext.malloc)(userarg, sizeof(struct getdns_context)); if (!result) { return GETDNS_RETURN_GENERIC_ERROR; } - result->my_mf.mf_arg = MF_PLAIN; - result->my_mf.mf.pln.malloc = malloc; - result->my_mf.mf.pln.realloc = realloc; - result->my_mf.mf.pln.free = free; + result->my_mf.mf_arg = userarg; + result->my_mf.mf.ext.malloc = malloc; + result->my_mf.mf.ext.realloc = realloc; + result->my_mf.mf.ext.free = free; result->update_callback = NULL; - result->mf.mf_arg = MF_PLAIN; - result->mf.mf.pln.malloc = malloc; - result->mf.mf.pln.realloc = realloc; - result->mf.mf.pln.free = free; + result->mf.mf_arg = userarg; + result->mf.mf.ext.malloc = malloc; + result->mf.mf.ext.realloc = realloc; + result->mf.mf.ext.free = free; result->event_base_sync = event_base_new(); result->unbound_sync = ub_ctx_create_event(result->event_base_sync); @@ -312,6 +318,28 @@ getdns_context_create_with_memory_functions(struct getdns_context ** context, return GETDNS_RETURN_GOOD; } /* getdns_context_create */ +/* + * getdns_context_create + * + * Call this to initialize the context that is used in other getdns calls. + */ +getdns_return_t +getdns_context_create_with_memory_functions(struct getdns_context ** context, + int set_from_os, + void *(*malloc)(size_t), + void *(*realloc)(void *, size_t), + void (*free)(void *) + ) +{ + mf_union mf; + mf.pln.malloc = malloc; + mf.pln.realloc = realloc; + mf.pln.free = free; + return getdns_context_create_with_extended_memory_functions( + context, set_from_os, MF_PLAIN, + mf.ext.malloc, mf.ext.realloc, mf.ext.free); +} /* getdns_context_create */ + /* * getdns_context_create * @@ -791,6 +819,36 @@ getdns_context_set_edns_do_bit(struct getdns_context *context, uint8_t value) return GETDNS_RETURN_GOOD; } /* getdns_context_set_edns_do_bit */ +/* + * getdns_context_set_extended_memory_functions + * + */ +getdns_return_t +getdns_context_set_extended_memory_functions( + struct getdns_context *context, + void *userarg, + void *(*malloc) (void *userarg, size_t), + void *(*realloc) (void *userarg, void *, size_t), + void (*free) (void *userarg, void *) + ) +{ + if (!context) + return GETDNS_RETURN_BAD_CONTEXT; + + if (!malloc || !realloc || !free) + return GETDNS_RETURN_CONTEXT_UPDATE_FAIL; + + context->mf.mf_arg = userarg; + context->mf.mf.ext.malloc = malloc; + context->mf.mf.ext.realloc = realloc; + context->mf.mf.ext.free = free; + + dispatch_updated(context, GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS); + + return GETDNS_RETURN_GOOD; +} /* getdns_context_set_extended_memory_functions*/ + + /* * getdns_context_set_memory_functions * @@ -802,20 +860,12 @@ getdns_context_set_memory_functions(struct getdns_context *context, void (*free) (void *) ) { - if (!context) - return GETDNS_RETURN_BAD_CONTEXT; - - if (!malloc || !realloc || !free) - return GETDNS_RETURN_CONTEXT_UPDATE_FAIL; - - context->mf.mf_arg = MF_PLAIN; - context->mf.mf.pln.malloc = malloc; - context->mf.mf.pln.realloc = realloc; - context->mf.mf.pln.free = free; - - dispatch_updated(context, GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS); - - return GETDNS_RETURN_GOOD; + mf_union mf; + mf.pln.malloc = malloc; + mf.pln.realloc = realloc; + mf.pln.free = free; + return getdns_context_set_extended_memory_functions( + context, MF_PLAIN, mf.ext.malloc, mf.ext.realloc, mf.ext.free); } /* getdns_context_set_memory_functions*/ diff --git a/src/dict.c b/src/dict.c index ed414167..96523a73 100644 --- a/src/dict.c +++ b/src/dict.c @@ -83,8 +83,9 @@ 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_memory_functions( - dict->mf.mf.pln.malloc, dict->mf.mf.pln.realloc, dict->mf.mf.pln.free); + *answer = getdns_list_create_with_extended_memory_functions( + dict->mf.mf_arg, dict->mf.mf.ext.malloc, + dict->mf.mf.ext.realloc, dict->mf.mf.ext.free); if (!*answer) return GETDNS_RETURN_NO_SUCH_DICT_NAME; @@ -188,37 +189,57 @@ getdns_dict_get_int(struct getdns_dict * dict, char *name, uint32_t * answer) } /* 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 *)) +getdns_dict_create_with_extended_memory_functions( + void *userarg, + void *(*malloc)(void *userarg, size_t), + void *(*realloc)(void *userarg, void *, size_t), + void (*free)(void *userarg, void *)) { struct getdns_dict *dict; + mf_union mf; if (!malloc || !realloc || !free) return NULL; - dict = (struct getdns_dict *)(*malloc)(sizeof(struct getdns_dict)); + mf.ext.malloc = malloc; + dict = userarg == MF_PLAIN + ? (struct getdns_dict*)(*mf.pln.malloc)( + sizeof(struct getdns_dict)) + : (struct getdns_dict*)(*mf.ext.malloc)(userarg, + sizeof(struct getdns_dict)); if (!dict) return NULL; - dict->mf.mf_arg = MF_PLAIN; - dict->mf.mf.pln.malloc = malloc; - dict->mf.mf.pln.realloc = realloc; - dict->mf.mf.pln.free = free; + dict->mf.mf_arg = userarg; + dict->mf.mf.ext.malloc = malloc; + dict->mf.mf.ext.realloc = realloc; + dict->mf.mf.ext.free = free; ldns_rbtree_init(&(dict->root), (int (*)(const void *, const void *)) strcmp); return dict; } +struct getdns_dict * +getdns_dict_create_with_memory_functions(void *(*malloc)(size_t), + void *(*realloc)(void *, size_t), void (*free)(void *)) +{ + mf_union mf; + mf.pln.malloc = malloc; + mf.pln.realloc = realloc; + mf.pln.free = free; + return getdns_dict_create_with_extended_memory_functions( + MF_PLAIN, mf.ext.malloc, mf.ext.realloc, mf.ext.free); +} /*-------------------------- getdns_dict_create_with_context */ struct getdns_dict * getdns_dict_create_with_context(struct getdns_context *context) { if (context) - return getdns_dict_create_with_memory_functions( - context->mf.mf.pln.malloc, - context->mf.mf.pln.realloc, context->mf.mf.pln.free); + return getdns_dict_create_with_extended_memory_functions( + context->mf.mf_arg, context->mf.mf.ext.malloc, + context->mf.mf.ext.realloc, context->mf.mf.ext.free); else return getdns_dict_create_with_memory_functions(&malloc, &realloc, &free); @@ -254,10 +275,11 @@ getdns_dict_copy(struct getdns_dict * srcdict, struct getdns_dict ** dstdict) *dstdict = NULL; return GETDNS_RETURN_GOOD; } - *dstdict = getdns_dict_create_with_memory_functions( - srcdict->mf.mf.pln.malloc, - srcdict->mf.mf.pln.realloc, - srcdict->mf.mf.pln.free); + *dstdict = getdns_dict_create_with_extended_memory_functions( + srcdict->mf.mf_arg, + srcdict->mf.mf.ext.malloc, + srcdict->mf.mf.ext.realloc, + srcdict->mf.mf.ext.free); if (!*dstdict) return GETDNS_RETURN_NO_SUCH_DICT_NAME; diff --git a/src/list.c b/src/list.c index ec81d7d9..14a9d8cf 100644 --- a/src/list.c +++ b/src/list.c @@ -164,10 +164,11 @@ getdns_list_copy(struct getdns_list * srclist, struct getdns_list ** dstlist) *dstlist = NULL; return GETDNS_RETURN_GOOD; } - *dstlist = getdns_list_create_with_memory_functions( - srclist->mf.mf.pln.malloc, - srclist->mf.mf.pln.realloc, - srclist->mf.mf.pln.free + *dstlist = getdns_list_create_with_extended_memory_functions( + srclist->mf.mf_arg, + srclist->mf.mf.ext.malloc, + srclist->mf.mf.ext.realloc, + srclist->mf.mf.ext.free ); if (!dstlist) return GETDNS_RETURN_NO_SUCH_LIST_ITEM; @@ -210,22 +211,31 @@ getdns_list_copy(struct getdns_list * srclist, struct getdns_list ** dstlist) } /* getdns_list_copy */ struct getdns_list * -getdns_list_create_with_memory_functions(void *(*malloc)(size_t), - void *(*realloc)(void *, size_t), void (*free)(void *)) +getdns_list_create_with_extended_memory_functions( + void *userarg, + void *(*malloc)(void *userarg, size_t), + void *(*realloc)(void *userarg, void *, size_t), + void (*free)(void *userarg, void *)) { struct getdns_list *list; + mf_union mf; if (!malloc || !realloc || !free) return NULL; - list = (struct getdns_list *)(*malloc)(sizeof(struct getdns_list)); + mf.ext.malloc = malloc; + list = userarg == MF_PLAIN + ? (struct getdns_list *)(*mf.pln.malloc)( + sizeof(struct getdns_list)) + : (struct getdns_list *)(*mf.ext.malloc)(userarg, + sizeof(struct getdns_list)); if (!list) return NULL; - list->mf.mf_arg = MF_PLAIN; - list->mf.mf.pln.malloc = malloc; - list->mf.mf.pln.realloc = realloc; - list->mf.mf.pln.free = free; + list->mf.mf_arg = userarg; + list->mf.mf.ext.malloc = malloc; + list->mf.mf.ext.realloc = realloc; + list->mf.mf.ext.free = free; list->numalloc = 0; list->numinuse = 0; @@ -237,15 +247,29 @@ getdns_list_create_with_memory_functions(void *(*malloc)(size_t), return list; } +struct getdns_list * +getdns_list_create_with_memory_functions(void *(*malloc)(size_t), + void *(*realloc)(void *, size_t), void (*free)(void *)) +{ + mf_union mf; + mf.pln.malloc = malloc; + mf.pln.realloc = realloc; + mf.pln.free = free; + return getdns_list_create_with_extended_memory_functions( + MF_PLAIN, mf.ext.malloc, mf.ext.realloc, mf.ext.free); +} + + /*-------------------------- getdns_list_create_with_context */ struct getdns_list * getdns_list_create_with_context(struct getdns_context *context) { if (context) - return getdns_list_create_with_memory_functions( - context->mf.mf.pln.malloc, - context->mf.mf.pln.realloc, - context->mf.mf.pln.free + return getdns_list_create_with_extended_memory_functions( + context->mf.mf_arg, + context->mf.mf.ext.malloc, + context->mf.mf.ext.realloc, + context->mf.mf.ext.free ); else return getdns_list_create_with_memory_functions(malloc, diff --git a/src/types-internal.h b/src/types-internal.h index 73c21cd2..ecb22a61 100644 --- a/src/types-internal.h +++ b/src/types-internal.h @@ -179,9 +179,7 @@ typedef struct getdns_dns_req #define MF_PLAIN ((void *)&plain_mem_funcs_user_arg) extern void *plain_mem_funcs_user_arg; -struct mem_funcs { - void *mf_arg; - union { +typedef union { struct { void *(*malloc)(size_t); void *(*realloc)(void *, size_t); @@ -192,7 +190,11 @@ struct mem_funcs { void *(*realloc)(void *userarg, void *, size_t); void (*free)(void *userarg, void *); } ext; - } mf; + } mf_union; + +struct mem_funcs { + void *mf_arg; + mf_union mf; }; #define GETDNS_XMALLOC(obj, type, count) \