mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 08:08:53 -05:00
Add RM_TryCalloc() and RM_TryRealloc() (#12985)
Modules may want to handle allocation failures gracefully. Adding RM_TryCalloc() and RM_TryRealloc() for it. RM_TryAlloc() was added before: https://github.com/redis/redis/pull/10541
This commit is contained in:
parent
acd9605223
commit
c5273cae18
14
src/module.c
14
src/module.c
@ -545,11 +545,23 @@ void *RM_Calloc(size_t nmemb, size_t size) {
|
|||||||
return zcalloc_usable(nmemb*size,NULL);
|
return zcalloc_usable(nmemb*size,NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Similar to RM_Calloc, but returns NULL in case of allocation failure, instead
|
||||||
|
* of panicking. */
|
||||||
|
void *RM_TryCalloc(size_t nmemb, size_t size) {
|
||||||
|
return ztrycalloc_usable(nmemb*size,NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Use like realloc() for memory obtained with RedisModule_Alloc(). */
|
/* Use like realloc() for memory obtained with RedisModule_Alloc(). */
|
||||||
void* RM_Realloc(void *ptr, size_t bytes) {
|
void* RM_Realloc(void *ptr, size_t bytes) {
|
||||||
return zrealloc_usable(ptr,bytes,NULL);
|
return zrealloc_usable(ptr,bytes,NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Similar to RM_Realloc, but returns NULL in case of allocation failure,
|
||||||
|
* instead of panicking. */
|
||||||
|
void *RM_TryRealloc(void *ptr, size_t bytes) {
|
||||||
|
return ztryrealloc_usable(ptr,bytes,NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Use like free() for memory obtained by RedisModule_Alloc() and
|
/* Use like free() for memory obtained by RedisModule_Alloc() and
|
||||||
* RedisModule_Realloc(). However you should never try to free with
|
* RedisModule_Realloc(). However you should never try to free with
|
||||||
* RedisModule_Free() memory allocated with malloc() inside your module. */
|
* RedisModule_Free() memory allocated with malloc() inside your module. */
|
||||||
@ -13590,7 +13602,9 @@ void moduleRegisterCoreAPI(void) {
|
|||||||
REGISTER_API(Alloc);
|
REGISTER_API(Alloc);
|
||||||
REGISTER_API(TryAlloc);
|
REGISTER_API(TryAlloc);
|
||||||
REGISTER_API(Calloc);
|
REGISTER_API(Calloc);
|
||||||
|
REGISTER_API(TryCalloc);
|
||||||
REGISTER_API(Realloc);
|
REGISTER_API(Realloc);
|
||||||
|
REGISTER_API(TryRealloc);
|
||||||
REGISTER_API(Free);
|
REGISTER_API(Free);
|
||||||
REGISTER_API(Strdup);
|
REGISTER_API(Strdup);
|
||||||
REGISTER_API(CreateCommand);
|
REGISTER_API(CreateCommand);
|
||||||
|
@ -959,8 +959,10 @@ typedef struct RedisModuleTypeMethods {
|
|||||||
REDISMODULE_API void * (*RedisModule_Alloc)(size_t bytes) REDISMODULE_ATTR;
|
REDISMODULE_API void * (*RedisModule_Alloc)(size_t bytes) REDISMODULE_ATTR;
|
||||||
REDISMODULE_API void * (*RedisModule_TryAlloc)(size_t bytes) REDISMODULE_ATTR;
|
REDISMODULE_API void * (*RedisModule_TryAlloc)(size_t bytes) REDISMODULE_ATTR;
|
||||||
REDISMODULE_API void * (*RedisModule_Realloc)(void *ptr, size_t bytes) REDISMODULE_ATTR;
|
REDISMODULE_API void * (*RedisModule_Realloc)(void *ptr, size_t bytes) REDISMODULE_ATTR;
|
||||||
|
REDISMODULE_API void * (*RedisModule_TryRealloc)(void *ptr, size_t bytes) REDISMODULE_ATTR;
|
||||||
REDISMODULE_API void (*RedisModule_Free)(void *ptr) REDISMODULE_ATTR;
|
REDISMODULE_API void (*RedisModule_Free)(void *ptr) REDISMODULE_ATTR;
|
||||||
REDISMODULE_API void * (*RedisModule_Calloc)(size_t nmemb, size_t size) REDISMODULE_ATTR;
|
REDISMODULE_API void * (*RedisModule_Calloc)(size_t nmemb, size_t size) REDISMODULE_ATTR;
|
||||||
|
REDISMODULE_API void * (*RedisModule_TryCalloc)(size_t nmemb, size_t size) REDISMODULE_ATTR;
|
||||||
REDISMODULE_API char * (*RedisModule_Strdup)(const char *str) REDISMODULE_ATTR;
|
REDISMODULE_API char * (*RedisModule_Strdup)(const char *str) REDISMODULE_ATTR;
|
||||||
REDISMODULE_API int (*RedisModule_GetApi)(const char *, void *) REDISMODULE_ATTR;
|
REDISMODULE_API int (*RedisModule_GetApi)(const char *, void *) REDISMODULE_ATTR;
|
||||||
REDISMODULE_API int (*RedisModule_CreateCommand)(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc cmdfunc, const char *strflags, int firstkey, int lastkey, int keystep) REDISMODULE_ATTR;
|
REDISMODULE_API int (*RedisModule_CreateCommand)(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc cmdfunc, const char *strflags, int firstkey, int lastkey, int keystep) REDISMODULE_ATTR;
|
||||||
@ -1322,8 +1324,10 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int
|
|||||||
REDISMODULE_GET_API(Alloc);
|
REDISMODULE_GET_API(Alloc);
|
||||||
REDISMODULE_GET_API(TryAlloc);
|
REDISMODULE_GET_API(TryAlloc);
|
||||||
REDISMODULE_GET_API(Calloc);
|
REDISMODULE_GET_API(Calloc);
|
||||||
|
REDISMODULE_GET_API(TryCalloc);
|
||||||
REDISMODULE_GET_API(Free);
|
REDISMODULE_GET_API(Free);
|
||||||
REDISMODULE_GET_API(Realloc);
|
REDISMODULE_GET_API(Realloc);
|
||||||
|
REDISMODULE_GET_API(TryRealloc);
|
||||||
REDISMODULE_GET_API(Strdup);
|
REDISMODULE_GET_API(Strdup);
|
||||||
REDISMODULE_GET_API(CreateCommand);
|
REDISMODULE_GET_API(CreateCommand);
|
||||||
REDISMODULE_GET_API(GetCommand);
|
REDISMODULE_GET_API(GetCommand);
|
||||||
|
@ -503,6 +503,27 @@ final:
|
|||||||
return REDISMODULE_OK;
|
return REDISMODULE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int test_malloc_api(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||||
|
UNUSED(argv);
|
||||||
|
UNUSED(argc);
|
||||||
|
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
p = RedisModule_TryAlloc(1024);
|
||||||
|
memset(p, 0, 1024);
|
||||||
|
RedisModule_Free(p);
|
||||||
|
|
||||||
|
p = RedisModule_TryCalloc(1, 1024);
|
||||||
|
memset(p, 1, 1024);
|
||||||
|
|
||||||
|
p = RedisModule_TryRealloc(p, 5 * 1024);
|
||||||
|
memset(p, 1, 5 * 1024);
|
||||||
|
RedisModule_Free(p);
|
||||||
|
|
||||||
|
RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||||
|
return REDISMODULE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||||
REDISMODULE_NOT_USED(argv);
|
REDISMODULE_NOT_USED(argv);
|
||||||
REDISMODULE_NOT_USED(argc);
|
REDISMODULE_NOT_USED(argc);
|
||||||
@ -566,6 +587,8 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
|||||||
return REDISMODULE_ERR;
|
return REDISMODULE_ERR;
|
||||||
if (RedisModule_CreateCommand(ctx, "test.clear_n_events", test_clear_n_events,"", 0, 0, 0) == REDISMODULE_ERR)
|
if (RedisModule_CreateCommand(ctx, "test.clear_n_events", test_clear_n_events,"", 0, 0, 0) == REDISMODULE_ERR)
|
||||||
return REDISMODULE_ERR;
|
return REDISMODULE_ERR;
|
||||||
|
if (RedisModule_CreateCommand(ctx, "test.malloc_api", test_malloc_api,"", 0, 0, 0) == REDISMODULE_ERR)
|
||||||
|
return REDISMODULE_ERR;
|
||||||
|
|
||||||
return REDISMODULE_OK;
|
return REDISMODULE_OK;
|
||||||
}
|
}
|
||||||
|
@ -493,6 +493,10 @@ start_server {overrides {save {900 1}} tags {"modules"}} {
|
|||||||
# server is writable again
|
# server is writable again
|
||||||
r set x y
|
r set x y
|
||||||
} {OK}
|
} {OK}
|
||||||
|
|
||||||
|
test "malloc API" {
|
||||||
|
assert_equal {OK} [r test.malloc_api 0]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
start_server {tags {"modules"}} {
|
start_server {tags {"modules"}} {
|
||||||
|
Loading…
Reference in New Issue
Block a user