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) \