From 8e0264cfd6889b73c241b60736fe96ba1322ee6e Mon Sep 17 00:00:00 2001 From: Michael Grunder Date: Fri, 22 May 2020 09:27:49 -0700 Subject: Allow users to replace allocator and handle OOM everywhere. (#800) * Adds an indirection to every allocation/deallocation to allow users to plug in ones of their choosing (use custom functions, jemalloc, etc). * Gracefully handle OOM everywhere in hiredis. This should make it possible for users of the library to have more flexibility in how they handle such situations. * Changes `redisReaderTask->elements` from an `int` to a `long long` to prevent a possible overflow when transferring the task elements into a `redisReply`. * Adds a configurable `max elements` member to `redisReader` that defaults to 2^32 - 1. This can be set to "unlimited" by setting the value to zero. --- alloc.c | 59 ++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 19 deletions(-) (limited to 'alloc.c') diff --git a/alloc.c b/alloc.c index 55c3020..2b19c48 100644 --- a/alloc.c +++ b/alloc.c @@ -31,35 +31,56 @@ #include "fmacros.h" #include "alloc.h" #include +#include -void *hi_malloc(size_t size) { - void *ptr = malloc(size); - if (ptr == NULL) - HIREDIS_OOM_HANDLER; +hiredisAllocFuncs hiredisAllocFns = { + .malloc = malloc, + .calloc = calloc, + .realloc = realloc, + .strdup = strdup, + .free = free, +}; + +/* Override hiredis' allocators with ones supplied by the user */ +hiredisAllocFuncs hiredisSetAllocators(hiredisAllocFuncs *override) { + hiredisAllocFuncs orig = hiredisAllocFns; - return ptr; + hiredisAllocFns = *override; + + return orig; } -void *hi_calloc(size_t nmemb, size_t size) { - void *ptr = calloc(nmemb, size); - if (ptr == NULL) - HIREDIS_OOM_HANDLER; +/* Reset allocators to use libc defaults */ +void hiredisResetAllocators(void) { + hiredisAllocFns = (hiredisAllocFuncs) { + .malloc = malloc, + .calloc = calloc, + .realloc = realloc, + .strdup = strdup, + .free = free, + }; +} + +#ifdef _WIN32 - return ptr; +void *hi_malloc(size_t size) { + return hiredisAllocFns.malloc(size); } -void *hi_realloc(void *ptr, size_t size) { - void *newptr = realloc(ptr, size); - if (newptr == NULL) - HIREDIS_OOM_HANDLER; +void *hi_calloc(size_t nmemb, size_t size) { + return hiredisAllocFns.calloc(nmemb, size); +} - return newptr; +void *hi_realloc(void *ptr, size_t size) { + return hiredisAllocFns.realloc(ptr, size); } char *hi_strdup(const char *str) { - char *newstr = strdup(str); - if (newstr == NULL) - HIREDIS_OOM_HANDLER; + return hiredisAllocFns.strdup(str); +} - return newstr; +void hi_free(void *ptr) { + hiredisAllocFns.free(ptr); } + +#endif -- cgit v1.2.3