mirror of https://github.com/getdnsapi/getdns.git
Custom mem funcs per dict/list
This commit is contained in:
parent
7158291e05
commit
373e0e4952
|
@ -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 */
|
||||
|
|
|
@ -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_ */
|
||||
|
|
67
src/dict.c
67
src/dict.c
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
48
src/list.c
48
src/list.c
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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.",
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue