Fix decrRefCount() prototype from void to robj pointer.
decrRefCount used to get its argument as a void* pointer in order to be used as destructor where a 'void free_object(void*)' prototype is expected. However this made simpler to introduce bugs by freeing the wrong pointer. This commit fixes the argument type and introduces a new wrapper called decrRefCountVoid() that can be used when the void* argument is needed.
This commit is contained in:
parent
2d20e68fe4
commit
8766e81079
@ -456,7 +456,7 @@ struct redisClient *createFakeClient(void) {
|
|||||||
c->reply_bytes = 0;
|
c->reply_bytes = 0;
|
||||||
c->obuf_soft_limit_reached_time = 0;
|
c->obuf_soft_limit_reached_time = 0;
|
||||||
c->watched_keys = listCreate();
|
c->watched_keys = listCreate();
|
||||||
listSetFreeMethod(c->reply,decrRefCount);
|
listSetFreeMethod(c->reply,decrRefCountVoid);
|
||||||
listSetDupMethod(c->reply,dupClientReplyValue);
|
listSetDupMethod(c->reply,dupClientReplyValue);
|
||||||
initClientMultiState(c);
|
initClientMultiState(c);
|
||||||
return c;
|
return c;
|
||||||
|
@ -89,17 +89,17 @@ redisClient *createClient(int fd) {
|
|||||||
c->reply = listCreate();
|
c->reply = listCreate();
|
||||||
c->reply_bytes = 0;
|
c->reply_bytes = 0;
|
||||||
c->obuf_soft_limit_reached_time = 0;
|
c->obuf_soft_limit_reached_time = 0;
|
||||||
listSetFreeMethod(c->reply,decrRefCount);
|
listSetFreeMethod(c->reply,decrRefCountVoid);
|
||||||
listSetDupMethod(c->reply,dupClientReplyValue);
|
listSetDupMethod(c->reply,dupClientReplyValue);
|
||||||
c->bpop.keys = dictCreate(&setDictType,NULL);
|
c->bpop.keys = dictCreate(&setDictType,NULL);
|
||||||
c->bpop.timeout = 0;
|
c->bpop.timeout = 0;
|
||||||
c->bpop.target = NULL;
|
c->bpop.target = NULL;
|
||||||
c->io_keys = listCreate();
|
c->io_keys = listCreate();
|
||||||
c->watched_keys = listCreate();
|
c->watched_keys = listCreate();
|
||||||
listSetFreeMethod(c->io_keys,decrRefCount);
|
listSetFreeMethod(c->io_keys,decrRefCountVoid);
|
||||||
c->pubsub_channels = dictCreate(&setDictType,NULL);
|
c->pubsub_channels = dictCreate(&setDictType,NULL);
|
||||||
c->pubsub_patterns = listCreate();
|
c->pubsub_patterns = listCreate();
|
||||||
listSetFreeMethod(c->pubsub_patterns,decrRefCount);
|
listSetFreeMethod(c->pubsub_patterns,decrRefCountVoid);
|
||||||
listSetMatchMethod(c->pubsub_patterns,listMatchObjects);
|
listSetMatchMethod(c->pubsub_patterns,listMatchObjects);
|
||||||
if (fd != -1) listAddNodeTail(server.clients,c);
|
if (fd != -1) listAddNodeTail(server.clients,c);
|
||||||
initClientMultiState(c);
|
initClientMultiState(c);
|
||||||
|
11
src/object.c
11
src/object.c
@ -215,9 +215,7 @@ void incrRefCount(robj *o) {
|
|||||||
o->refcount++;
|
o->refcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void decrRefCount(void *obj) {
|
void decrRefCount(robj *o) {
|
||||||
robj *o = obj;
|
|
||||||
|
|
||||||
if (o->refcount <= 0) redisPanic("decrRefCount against refcount <= 0");
|
if (o->refcount <= 0) redisPanic("decrRefCount against refcount <= 0");
|
||||||
if (o->refcount == 1) {
|
if (o->refcount == 1) {
|
||||||
switch(o->type) {
|
switch(o->type) {
|
||||||
@ -234,6 +232,13 @@ void decrRefCount(void *obj) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This variant of decrRefCount() gets its argument as void, and is useful
|
||||||
|
* as free method in data structures that expect a 'void free_object(void*)'
|
||||||
|
* prototype for the free method. */
|
||||||
|
void decrRefCountVoid(void *o) {
|
||||||
|
decrRefCount(o);
|
||||||
|
}
|
||||||
|
|
||||||
/* This function set the ref count to zero without freeing the object.
|
/* This function set the ref count to zero without freeing the object.
|
||||||
* It is useful in order to pass a new object to functions incrementing
|
* It is useful in order to pass a new object to functions incrementing
|
||||||
* the ref count of the received object. Example:
|
* the ref count of the received object. Example:
|
||||||
|
@ -989,7 +989,8 @@ void discardTransaction(redisClient *c);
|
|||||||
void flagTransaction(redisClient *c);
|
void flagTransaction(redisClient *c);
|
||||||
|
|
||||||
/* Redis object implementation */
|
/* Redis object implementation */
|
||||||
void decrRefCount(void *o);
|
void decrRefCount(robj *o);
|
||||||
|
void decrRefCountVoid(void *o);
|
||||||
void incrRefCount(robj *o);
|
void incrRefCount(robj *o);
|
||||||
robj *resetRefCount(robj *obj);
|
robj *resetRefCount(robj *obj);
|
||||||
void freeStringObject(robj *o);
|
void freeStringObject(robj *o);
|
||||||
|
@ -275,7 +275,7 @@ void listTypeConvert(robj *subject, int enc) {
|
|||||||
|
|
||||||
if (enc == REDIS_ENCODING_LINKEDLIST) {
|
if (enc == REDIS_ENCODING_LINKEDLIST) {
|
||||||
list *l = listCreate();
|
list *l = listCreate();
|
||||||
listSetFreeMethod(l,decrRefCount);
|
listSetFreeMethod(l,decrRefCountVoid);
|
||||||
|
|
||||||
/* listTypeGet returns a robj with incremented refcount */
|
/* listTypeGet returns a robj with incremented refcount */
|
||||||
li = listTypeInitIterator(subject,0,REDIS_TAIL);
|
li = listTypeInitIterator(subject,0,REDIS_TAIL);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user