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

View File

@ -39,9 +39,6 @@ struct ub_ctx;
/** function pointer typedefs */
typedef void (*getdns_update_callback) (getdns_context_t, uint16_t);
typedef void *(*getdns_memory_allocator) (size_t);
typedef void (*getdns_memory_deallocator) (void *);
typedef void *(*getdns_memory_reallocator) (void *, size_t);
struct getdns_context_t
{
@ -62,9 +59,9 @@ struct getdns_context_t
uint8_t edns_do_bit;
getdns_update_callback update_callback;
getdns_memory_allocator malloc;
getdns_memory_reallocator realloc;
getdns_memory_deallocator free;
void *(*malloc)(size_t);
void *(*realloc)(void *, size_t);
void (*free)(void *);
/* Event loop for sync requests */
struct event_base *event_base_sync;
@ -87,19 +84,6 @@ struct getdns_context_t
struct ldns_rbtree_t *outbound_requests;
};
#define GETDNS_XMALLOC(context, type, count) \
((context) ? ((type *) (*(context)->malloc)((count) * sizeof(type))) \
: ((type *) malloc((count) * sizeof(type))))
#define GETDNS_MALLOC(context, type) \
GETDNS_XMALLOC(context, type, 1)
#define GETDNS_XREALLOC(context, ptr, type, count) \
((context) ? ((type *) (*(context)->realloc)((ptr), (count) * sizeof(type))) \
: ((type *) realloc((ptr), (count) * sizeof(type))))
#define GETDNS_REALLOC(context, ptr, type) \
GETDNS_XREALLOC(context, ptr, type, 1);
#define GETDNS_FREE(context, ptr) \
((context) ? ((*(context)->free)(ptr)) : free(ptr))
/** internal functions **/
/**
* Sets up the unbound contexts with stub or recursive behavior
@ -118,12 +102,13 @@ getdns_return_t getdns_context_clear_outbound_request(struct getdns_dns_req
getdns_return_t getdns_context_cancel_request(getdns_context_t context,
getdns_transaction_t transaction_id, int fire_callback);
char *getdns_strdup(getdns_context_t, const char *str);
char *getdns_strdup(void *(*malloc)(size_t), const char *str);
struct getdns_bindata *getdns_bindata_copy(getdns_context_t,
struct getdns_bindata *getdns_bindata_copy(
void *(*malloc)(size_t), void (*free)(void *),
const struct getdns_bindata *src);
void getdns_bindata_destroy(getdns_context_t context,
void getdns_bindata_destroy(void (*free)(void *),
struct getdns_bindata *bindata);
#endif /* _GETDNS_CONTEXT_H_ */

View File

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

View File

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

View File

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

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_with_context(getdns_context_t context);
struct getdns_list *getdns_list_create_with_memory_functions(
void *(*malloc) (size_t), void *(*realloc) (void *, size_t),
void (*free) (void *));
/**
* free memory allocated to the list (also frees all children of the list)
* note that lists and bindata retrieved from the list via the getdns_list_get_*
@ -615,6 +619,9 @@ getdns_return_t getdns_list_set_int(struct getdns_list *list, size_t index,
*/
struct getdns_dict *getdns_dict_create();
struct getdns_dict *getdns_dict_create_with_context(getdns_context_t context);
struct getdns_dict *getdns_dict_create_with_memory_functions(
void *(*malloc) (size_t), void *(*realloc) (void *, size_t),
void (*free) (void *));
/**
* private function used to make a copy of a dict structure, the caller is responsible

View File

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

View File

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

View File

@ -248,6 +248,11 @@ tst_getnames(void)
getdns_dict_get_names(dict, &list);
result = getdns_list_get_length(list, &llen);
if (result != GETDNS_RETURN_GOOD) {
tstmsg_case_msg
("getdns_list_get_length failed, exiting");
return;
}
if (llen != i) {
tstmsg_case_msg
("getdns_list_get_length returned unreasonable length, exiting");

View File

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

View File

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

View File

@ -134,6 +134,21 @@ typedef struct getdns_dns_req
} getdns_dns_req;
#define GETDNS_XMALLOC(obj, type, count) \
((obj) ? ((type *) (*(obj)->malloc)((count)*sizeof(type))) \
: ((type *) malloc ((count)*sizeof(type))))
#define GETDNS_XREALLOC(obj, ptr, type, count) \
((obj) ? ((type *) (*(obj)->realloc)((ptr),(count)*sizeof(type))) \
: ((type *) realloc ((ptr),(count)*sizeof(type))))
#define GETDNS_FREE(obj, ptr) \
((obj) ? ((*(obj)->free)(ptr)) : free(ptr))
#define GETDNS_MALLOC(obj, type) GETDNS_XMALLOC(obj, type, 1)
#define GETDNS_REALLOC(obj, ptr, type) GETDNS_XREALLOC(obj, ptr, type, 1);
/* utility methods */
/* network request utilities */