diff options
author | Michael Grunder <michael.grunder@gmail.com> | 2020-05-22 09:27:49 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-22 09:27:49 -0700 |
commit | 8e0264cfd6889b73c241b60736fe96ba1322ee6e (patch) | |
tree | c7a8f050a2e6966c45f7af919056b9653f831579 /alloc.c | |
parent | 83bba659b9dbd6c77baf2ff27ff6342317869a3e (diff) |
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.
Diffstat (limited to 'alloc.c')
-rw-r--r-- | alloc.c | 59 |
1 files changed, 40 insertions, 19 deletions
@@ -31,35 +31,56 @@ #include "fmacros.h" #include "alloc.h" #include <string.h> +#include <stdlib.h> -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 |