Commit e25db30f authored by Pieter Noordhuis's avatar Pieter Noordhuis
Browse files

Run pending callbacks with NULL reply on error

parent 8b0fddcb
......@@ -68,6 +68,25 @@ int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallba
return REDIS_ERR;
}
/* Helper functions to push/shift callbacks */
static void __redisPushCallback(redisCallbackList *list, redisCallback *cb) {
if (list->head == NULL)
list->head = cb;
if (list->tail != NULL)
list->tail->next = cb;
list->tail = cb;
}
static redisCallback *__redisShiftCallback(redisCallbackList *list) {
redisCallback *cb = list->head;
if (cb != NULL) {
list->head = cb->next;
if (cb == list->tail)
list->tail = NULL;
}
return cb;
}
/* Tries to do a clean disconnect from Redis, meaning it stops new commands
* from being issued, but tries to flush the output buffer and execute
* callbacks for all remaining replies.
......@@ -83,39 +102,38 @@ void redisAsyncDisconnect(redisAsyncContext *ac) {
/* Helper function to make the disconnect happen and clean up. */
static void __redisAsyncDisconnect(redisAsyncContext *ac) {
redisContext *c = &(ac->c);
redisCallback *cb;
int status;
/* Make sure error is accessible if there is any */
__redisAsyncCopyError(ac);
status = (ac->error == NULL) ? REDIS_OK : REDIS_ERR;
if (status == REDIS_OK) {
/* When the connection is cleanly disconnected, there should not
* be pending callbacks. */
assert((cb = __redisShiftCallback(&ac->replies)) == NULL);
} else {
/* Callbacks should not be able to issue new commands. */
c->flags |= REDIS_DISCONNECTING;
/* Execute pending callbacks with NULL reply. */
while ((cb = __redisShiftCallback(&ac->replies)) != NULL) {
if (cb->fn != NULL)
cb->fn(ac,NULL,cb->privdata);
}
}
/* Signal event lib to clean up */
if (ac->evCleanup) ac->evCleanup(ac->data);
/* Execute callback with proper status */
__redisAsyncCopyError(ac);
status = (ac->error == NULL) ? REDIS_OK : REDIS_ERR;
if (ac->onDisconnect) ac->onDisconnect(ac,status);
/* Cleanup self */
redisFree(c);
}
/* Helper functions to push/shift callbacks */
static void __redisPushCallback(redisCallbackList *list, redisCallback *cb) {
if (list->head == NULL)
list->head = cb;
if (list->tail != NULL)
list->tail->next = cb;
list->tail = cb;
}
static redisCallback *__redisShiftCallback(redisCallbackList *list) {
redisCallback *cb = list->head;
if (cb != NULL) {
list->head = cb->next;
if (cb == list->tail)
list->tail = NULL;
}
return cb;
}
void redisProcessCallbacks(redisAsyncContext *ac) {
redisContext *c = &(ac->c);
redisCallback *cb;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment