diff --git a/src/context.c b/src/context.c index a861273d..50ee71c3 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(); @@ -72,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; @@ -237,28 +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 = 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->malloc = malloc; - result->realloc = realloc; - result->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); @@ -304,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 * @@ -330,7 +366,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); @@ -345,7 +381,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 */ @@ -446,10 +482,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)); @@ -783,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 * @@ -794,19 +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->malloc = malloc; - context->realloc = realloc; - context->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*/ @@ -874,7 +933,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 */ @@ -959,7 +1018,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; } @@ -967,7 +1026,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; @@ -983,16 +1042,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, 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 @@ -1000,7 +1059,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; @@ -1008,14 +1067,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); @@ -1023,11 +1082,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 2a04b147..803e90a3 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,9 @@ 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 *); + + struct mem_funcs mf; + struct mem_funcs my_mf; /* Event loop for sync requests */ struct event_base *event_base_sync; @@ -100,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 0592ec32..96523a73 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->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); } @@ -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->malloc, dict->realloc, dict->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,34 +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->malloc = malloc; - dict->realloc = realloc; - dict->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->malloc, - context->realloc, context->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); @@ -251,8 +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->malloc, srcdict->realloc, srcdict->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; @@ -306,7 +333,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, item->data.bindata); break; case t_dict: getdns_dict_destroy(item->data.dict); @@ -318,8 +345,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 */ @@ -331,7 +358,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 */ @@ -397,14 +424,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->malloc, dict->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->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 26a72f96..caee054a 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,7 @@ struct getdns_dict_item struct getdns_dict { ldns_rbtree_t root; - void *(*malloc)(size_t); - void *(*realloc)(void *, size_t); - void (*free)(void *); + struct 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..14a9d8cf 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) @@ -164,8 +164,12 @@ 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->malloc, srclist->realloc, srclist->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; @@ -207,21 +211,32 @@ 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->malloc = malloc; - list->realloc = realloc; - list->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; list->items = NULL; @@ -232,13 +247,30 @@ 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->malloc, - context->realloc, context->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, realloc, free); @@ -271,7 +303,7 @@ getdns_list_destroy(struct getdns_list *list) break; case t_bindata: - getdns_bindata_destroy(list->free, + getdns_bindata_destroy(&list->mf, list->items[i].data.bindata); break; @@ -281,8 +313,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 */ @@ -374,8 +406,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->malloc, list->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 d5267769..b37266ae 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,7 @@ struct getdns_list int numalloc; int numinuse; struct getdns_list_item *items; - void *(*malloc)(size_t); - void *(*realloc)(void *, size_t); - void (*free)(void *); + struct mem_funcs mf; }; - #endif diff --git a/src/request-internal.c b/src/request-internal.c index 093a90db..7a11554a 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->mf, 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->mf + , 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->mf, 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->mf, getdns_dns_req); if (result == NULL) { return NULL; } diff --git a/src/types-internal.h b/src/types-internal.h index 2859f6d2..ecb22a61 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,45 @@ 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; + } mf_union; + +struct mem_funcs { + void *mf_arg; + mf_union mf; +}; + #define GETDNS_XMALLOC(obj, type, count) \ - ((obj) ? ((type *) (*(obj)->malloc)((count)*sizeof(type))) \ - : ((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).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).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);