Custom mem funcs per dict/list

This commit is contained in:
Willem Toorop 2013-11-12 17:00:19 +01:00
parent 7158291e05
commit 373e0e4952
12 changed files with 128 additions and 78 deletions

View File

@ -985,10 +985,10 @@ getdns_context_clear_outbound_request(getdns_dns_req * req)
} }
char * 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; size_t sz = strlen(s) + 1;
char *r = GETDNS_XMALLOC(context, char, sz); char *r = (char *)(*malloc)(sizeof(char) * sz);
if (r) if (r)
return memcpy(r, s, sz); return memcpy(r, s, sz);
else else
@ -996,7 +996,7 @@ getdns_strdup(getdns_context_t context, const char *s)
} }
struct getdns_bindata * 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) const struct getdns_bindata *src)
{ {
struct getdns_bindata *dst; struct getdns_bindata *dst;
@ -1004,14 +1004,14 @@ getdns_bindata_copy(getdns_context_t context,
if (!src) if (!src)
return NULL; return NULL;
dst = GETDNS_MALLOC(context, struct getdns_bindata); dst = (struct getdns_bindata *)(*malloc)(sizeof(struct getdns_bindata));
if (!dst) if (!dst)
return NULL; return NULL;
dst->size = src->size; 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) { if (!dst->data) {
GETDNS_FREE(context, dst); (*free)(dst);
return NULL; return NULL;
} }
(void) memcpy(dst->data, src->data, src->size); (void) memcpy(dst->data, src->data, src->size);
@ -1019,12 +1019,11 @@ getdns_bindata_copy(getdns_context_t context,
} }
void void
getdns_bindata_destroy(getdns_context_t context, getdns_bindata_destroy(void (*free)(void *), struct getdns_bindata *bindata)
struct getdns_bindata *bindata)
{ {
if (!bindata) if (!bindata)
return; return;
GETDNS_FREE(context, bindata->data); (*free)(bindata->data);
GETDNS_FREE(context, bindata); (*free)(bindata);
} }
/* getdns_context.c */ /* getdns_context.c */

View File

@ -39,9 +39,6 @@ struct ub_ctx;
/** function pointer typedefs */ /** function pointer typedefs */
typedef void (*getdns_update_callback) (getdns_context_t, uint16_t); 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 struct getdns_context_t
{ {
@ -62,9 +59,9 @@ struct getdns_context_t
uint8_t edns_do_bit; uint8_t edns_do_bit;
getdns_update_callback update_callback; getdns_update_callback update_callback;
getdns_memory_allocator malloc; void *(*malloc)(size_t);
getdns_memory_reallocator realloc; void *(*realloc)(void *, size_t);
getdns_memory_deallocator free; void (*free)(void *);
/* Event loop for sync requests */ /* Event loop for sync requests */
struct event_base *event_base_sync; struct event_base *event_base_sync;
@ -87,19 +84,6 @@ struct getdns_context_t
struct ldns_rbtree_t *outbound_requests; 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 **/ /** internal functions **/
/** /**
* Sets up the unbound contexts with stub or recursive behavior * 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_return_t getdns_context_cancel_request(getdns_context_t context,
getdns_transaction_t transaction_id, int fire_callback); 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); const struct getdns_bindata *src);
void getdns_bindata_destroy(getdns_context_t context, void getdns_bindata_destroy(void (*free)(void *),
struct getdns_bindata *bindata); struct getdns_bindata *bindata);
#endif /* _GETDNS_CONTEXT_H_ */ #endif /* _GETDNS_CONTEXT_H_ */

View File

@ -37,7 +37,7 @@
#include <ctype.h> #include <ctype.h>
#include <ldns/buffer.h> #include <ldns/buffer.h>
#include "context.h" #include "types-internal.h"
#include "dict.h" #include "dict.h"
/*---------------------------------------- getdns_dict_find */ /*---------------------------------------- getdns_dict_find */
@ -62,8 +62,8 @@ getdns_dict_find(struct getdns_dict *dict, char *key, bool addifnotfnd)
if (!item && addifnotfnd) { if (!item && addifnotfnd) {
/* tsearch will add a node automatically for us */ /* tsearch will add a node automatically for us */
item = GETDNS_MALLOC(dict->context, struct getdns_dict_item); item = GETDNS_MALLOC(dict, struct getdns_dict_item);
item->node.key = getdns_strdup(dict->context, key); item->node.key = getdns_strdup(dict->malloc, key);
item->data.n = 0; item->data.n = 0;
ldns_rbtree_insert(&(dict->root), (ldns_rbnode_t *) item); 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) if (!dict || !answer)
return GETDNS_RETURN_NO_SUCH_DICT_NAME; 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) if (!*answer)
return GETDNS_RETURN_NO_SUCH_DICT_NAME; 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; return GETDNS_RETURN_GOOD;
} /* getdns_dict_get_int */ } /* 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 */ /*-------------------------- getdns_dict_create_with_context */
struct getdns_dict * struct getdns_dict *
getdns_dict_create_with_context(getdns_context_t context) getdns_dict_create_with_context(getdns_context_t context)
{ {
struct getdns_dict *dict; if (context)
return getdns_dict_create_with_memory_functions(context->malloc,
dict = GETDNS_MALLOC(context, struct getdns_dict); context->realloc, context->free);
if (!dict) else
return NULL; return getdns_dict_create_with_memory_functions(&malloc,
&realloc, &free);
dict->context = context;
ldns_rbtree_init(&(dict->root), (int (*)(const void *,
const void *)) strcmp);
return dict;
} /* getdns_dict_create_with_context */ } /* getdns_dict_create_with_context */
/*---------------------------------------- getdns_dict_create */ /*---------------------------------------- getdns_dict_create */
@ -231,7 +250,8 @@ getdns_dict_copy(struct getdns_dict * srcdict, struct getdns_dict ** dstdict)
*dstdict = NULL; *dstdict = NULL;
return GETDNS_RETURN_GOOD; 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) if (!*dstdict)
return GETDNS_RETURN_NO_SUCH_DICT_NAME; return GETDNS_RETURN_NO_SUCH_DICT_NAME;
@ -278,14 +298,14 @@ void
getdns_dict_item_free(ldns_rbnode_t * node, void *arg) getdns_dict_item_free(ldns_rbnode_t * node, void *arg)
{ {
struct getdns_dict_item *item = (struct getdns_dict_item *) node; 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) if (!item)
return; return;
switch (item->dtype) { switch (item->dtype) {
case t_bindata: case t_bindata:
getdns_bindata_destroy(context, item->data.bindata); getdns_bindata_destroy(dict->free, item->data.bindata);
break; break;
case t_dict: case t_dict:
getdns_dict_destroy(item->data.dict); getdns_dict_destroy(item->data.dict);
@ -297,8 +317,8 @@ getdns_dict_item_free(ldns_rbnode_t * node, void *arg)
break; break;
} }
if (item->node.key) if (item->node.key)
GETDNS_FREE(context, (void *)item->node.key); GETDNS_FREE(dict, (void *)item->node.key);
GETDNS_FREE(context, item); GETDNS_FREE(dict, item);
} /* getdns_dict_item_free */ } /* getdns_dict_item_free */
/*---------------------------------------- getdns_dict_destroy */ /*---------------------------------------- getdns_dict_destroy */
@ -309,8 +329,8 @@ getdns_dict_destroy(struct getdns_dict *dict)
return; return;
ldns_traverse_postorder(&(dict->root), ldns_traverse_postorder(&(dict->root),
getdns_dict_item_free, dict->context); getdns_dict_item_free, dict);
GETDNS_FREE(dict->context, dict); GETDNS_FREE(dict, dict);
} /* getdns_dict_destroy */ } /* getdns_dict_destroy */
/*---------------------------------------- getdns_dict_set_dict */ /*---------------------------------------- getdns_dict_set_dict */
@ -376,13 +396,14 @@ getdns_dict_set_bindata(struct getdns_dict * dict, char *name,
if (!dict || !name || !child_bindata) if (!dict || !name || !child_bindata)
return GETDNS_RETURN_NO_SUCH_DICT_NAME; 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) if (!newbindata)
return GETDNS_RETURN_NO_SUCH_DICT_NAME; return GETDNS_RETURN_NO_SUCH_DICT_NAME;
item = getdns_dict_find(dict, name, true); item = getdns_dict_find(dict, name, true);
if (!item) { if (!item) {
getdns_bindata_destroy(dict->context, newbindata); getdns_bindata_destroy(dict->free, newbindata);
return GETDNS_RETURN_NO_SUCH_DICT_NAME; return GETDNS_RETURN_NO_SUCH_DICT_NAME;
} }
item->dtype = t_bindata; item->dtype = t_bindata;

View File

@ -66,7 +66,9 @@ struct getdns_dict_item
struct getdns_dict struct getdns_dict
{ {
ldns_rbtree_t root; ldns_rbtree_t root;
getdns_context_t context; void *(*malloc)(size_t);
void *(*realloc)(void *, size_t);
void (*free)(void *);
}; };
#endif #endif

View File

@ -110,8 +110,8 @@ main()
} }
/* Clean up */ /* Clean up */
getdns_free_sync_request_memory(this_response);
getdns_context_destroy(this_context); getdns_context_destroy(this_context);
getdns_free_sync_request_memory(this_response);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} /* main */ } /* main */

View File

@ -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();
struct getdns_list *getdns_list_create_with_context(getdns_context_t context); 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) * 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_* * 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();
struct getdns_dict *getdns_dict_create_with_context(getdns_context_t context); 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 * private function used to make a copy of a dict structure, the caller is responsible

View File

@ -35,7 +35,7 @@
*/ */
#include <string.h> #include <string.h>
#include "context.h" #include "types-internal.h"
#include "list.h" #include "list.h"
/*---------------------------------------- getdns_list_get_length */ /*---------------------------------------- getdns_list_get_length */
@ -133,12 +133,11 @@ getdns_return_t
getdns_list_realloc(struct getdns_list *list) getdns_list_realloc(struct getdns_list *list)
{ {
struct getdns_list_item *newlist; struct getdns_list_item *newlist;
int i;
if (!list) if (!list)
return GETDNS_RETURN_GENERIC_ERROR; return GETDNS_RETURN_GENERIC_ERROR;
newlist = GETDNS_XREALLOC(list->context, list->items, newlist = GETDNS_XREALLOC(list, list->items,
struct getdns_list_item, struct getdns_list_item,
list->numalloc + GETDNS_LIST_BLOCKSZ); list->numalloc + GETDNS_LIST_BLOCKSZ);
if (!newlist) if (!newlist)
@ -146,12 +145,6 @@ getdns_list_realloc(struct getdns_list *list)
list->items = newlist; list->items = newlist;
list->numalloc += GETDNS_LIST_BLOCKSZ; 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; return GETDNS_RETURN_GOOD;
} /* getdns_list_realloc */ } /* getdns_list_realloc */
@ -170,7 +163,8 @@ getdns_list_copy(struct getdns_list * srclist, struct getdns_list ** dstlist)
*dstlist = NULL; *dstlist = NULL;
return GETDNS_RETURN_GOOD; 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) if (!dstlist)
return GETDNS_RETURN_NO_SUCH_LIST_ITEM; 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; return GETDNS_RETURN_GOOD;
} /* getdns_list_copy */ } /* getdns_list_copy */
/*-------------------------- getdns_list_create_with_context */
struct getdns_list * 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; 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) if (!list)
return NULL; return NULL;
list->context = context; list->malloc = malloc;
list->realloc = realloc;
list->free = free;
list->numalloc = 0; list->numalloc = 0;
list->numinuse = 0; list->numinuse = 0;
list->items = NULL; list->items = NULL;
@ -230,6 +229,18 @@ getdns_list_create_with_context(getdns_context_t context)
return NULL; return NULL;
} }
return list; 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_with_context */
/*---------------------------------------- getdns_list_create */ /*---------------------------------------- getdns_list_create */
@ -259,7 +270,7 @@ getdns_list_destroy(struct getdns_list *list)
break; break;
case t_bindata: case t_bindata:
getdns_bindata_destroy(list->context, getdns_bindata_destroy(list->free,
list->items[i].data.bindata); list->items[i].data.bindata);
break; break;
@ -269,8 +280,8 @@ getdns_list_destroy(struct getdns_list *list)
} }
if (list->items) if (list->items)
GETDNS_FREE(list->context, list->items); GETDNS_FREE(list, list->items);
GETDNS_FREE(list->context, list); GETDNS_FREE(list, list);
} /* getdns_list_destroy */ } /* getdns_list_destroy */
/*---------------------------------------- getdns_list_add_item */ /*---------------------------------------- getdns_list_add_item */
@ -362,7 +373,8 @@ getdns_list_set_bindata(struct getdns_list * list, size_t index,
if (index >= list->numinuse) if (index >= list->numinuse)
return GETDNS_RETURN_NO_SUCH_LIST_ITEM; 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) if (!newbindata)
return GETDNS_RETURN_NO_SUCH_LIST_ITEM; return GETDNS_RETURN_NO_SUCH_LIST_ITEM;

View File

@ -63,7 +63,10 @@ struct getdns_list
int numalloc; int numalloc;
int numinuse; int numinuse;
struct getdns_list_item *items; struct getdns_list_item *items;
getdns_context_t context; void *(*malloc)(size_t);
void *(*realloc)(void *, size_t);
void (*free)(void *);
}; };
#endif #endif

View File

@ -248,6 +248,11 @@ tst_getnames(void)
getdns_dict_get_names(dict, &list); getdns_dict_get_names(dict, &list);
result = getdns_list_get_length(list, &llen); 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) { if (llen != i) {
tstmsg_case_msg tstmsg_case_msg
("getdns_list_get_length returned unreasonable length, exiting"); ("getdns_list_get_length returned unreasonable length, exiting");

View File

@ -276,6 +276,7 @@ tst_listsetget(void)
retval, ans_int); retval, ans_int);
tstmsg_case_msg(msg); tstmsg_case_msg(msg);
getdns_list_destroy(new_list);
getdns_list_destroy(list); getdns_list_destroy(list);
tstmsg_case_end(); tstmsg_case_end();

View File

@ -48,8 +48,8 @@ this_callbackfn(struct getdns_context_t *this_context,
} else if (this_callback_type == GETDNS_CALLBACK_CANCEL) } else if (this_callback_type == GETDNS_CALLBACK_CANCEL)
fprintf(stderr, fprintf(stderr,
"The callback with ID %lld was cancelled. Exiting.", "The callback with ID %llu was cancelled. Exiting.",
this_transaction_id); (unsigned long long)this_transaction_id);
else else
fprintf(stderr, fprintf(stderr,
"The callback got a callback_type of %d. Exiting.", "The callback got a callback_type of %d. Exiting.",

View File

@ -134,6 +134,21 @@ typedef struct getdns_dns_req
} 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 */ /* utility methods */
/* network request utilities */ /* network request utilities */