diff --git a/rmutil/alloc.c b/rmutil/alloc.c new file mode 100644 index 0000000..f272454 --- /dev/null +++ b/rmutil/alloc.c @@ -0,0 +1,34 @@ +#include +#include +#include + +#include "../redismodule.h" +#include "alloc.h" + +/* A patched implementation of strdup that will use our patched calloc */ +char *rmalloc_strndup(const char *s, size_t n) { + char *ret = calloc(n + 1, sizeof(char)); + if (ret) + memcpy(ret, s, n); + return ret; +} + +/* + * Re-patching RedisModule_Alloc and friends to the original malloc functions + * + * This function shold be called if you are working with malloc-patched code + * ouside of redis, usually for unit tests. Call it once when entering your unit + * tests' main(). + * + * Since including "alloc.h" while defining REDIS_MODULE_TARGET + * replaces all malloc functions in redis with the RM_Alloc family of functions, + * when running that code outside of redis, your app will crash. This function + * patches the RM_Alloc functions back to the original mallocs. */ +void RMUTil_InitAlloc() { + + RedisModule_Alloc = malloc; + RedisModule_Realloc = realloc; + RedisModule_Calloc = calloc; + RedisModule_Free = free; + RedisModule_Strdup = strdup; +} diff --git a/rmutil/alloc.h b/rmutil/alloc.h new file mode 100644 index 0000000..8c5cec6 --- /dev/null +++ b/rmutil/alloc.h @@ -0,0 +1,46 @@ +#ifndef __RMUTIL_ALLOC__ +#define __RMUTIL_ALLOC__ + +/* Automatic Redis Module Allocation functions monkey-patching. + * + * Including this file while REDIS_MODULE_TARGET is defined, will explicitly + * override malloc, calloc, realloc & free with RedisModule_Alloc, + * RedisModule_Callc, etc implementations, that allow Redis better control and + * reporting over allocations per module. + * + * You should include this file in all c files AS THE LAST INCLUDED FILE + * + * This only has effect when when compiling with the macro REDIS_MODULE_TARGET + * defined. The idea is that for unit tests it will not be defined, but for the + * module build target it will be. + * + */ + +#include +#include "../redismodule.h" + +char *rmalloc_strndup(const char *s, size_t n); + +#ifdef REDIS_MODULE_TARGET /* Set this when compiling your code as a module */ + +#define malloc(size) RedisModule_Alloc(size) +#define calloc(count, size) RedisModule_Calloc(count, size) +#define realloc(ptr, size) RedisModule_Realloc(ptr, size) +#define free(ptr) RedisModule_Free(ptr) +#define strdup(ptr) RedisModule_Strdup(ptr) + +// /* More overriding */ +// // needed to avoid calling strndup->malloc +#ifdef strndup +#undef strndup +#endif +#define strndup(s, n) rmalloc_strndup(s, n) + +#else +/* This function shold be called if you are working with malloc-patched code + * ouside of redis, usually for unit tests. Call it once when entering your unit + * tests' main() */ +void RMUTil_InitAlloc(); +#endif /* REDIS_MODULE_TARGET */ + +#endif /* __RMUTIL_ALLOC__ */ \ No newline at end of file diff --git a/rmutil/logging.h b/rmutil/logging.h new file mode 100644 index 0000000..ed92cb3 --- /dev/null +++ b/rmutil/logging.h @@ -0,0 +1,11 @@ +#ifndef __RMUTIL_LOGGING_H__ +#define __RMUTIL_LOGGING_H__ + +/* Convenience macros for redis logging */ + +#define RM_LOG_DEBUG(ctx, ...) RedisModule_Log(ctx, "debug", __VA_ARGS__) +#define RM_LOG_VERBOSE(ctx, ...) RedisModule_Log(ctx, "verbose", __VA_ARGS__) +#define RM_LOG_NOTICE(ctx, ...) RedisModule_Log(ctx, "notice", __VA_ARGS__) +#define RM_LOG_WARNING(ctx, ...) RedisModule_Log(ctx, "warning", __VA_ARGS__) + +#endif \ No newline at end of file