diff options
| author | Pieter Noordhuis <pcnoordhuis@gmail.com> | 2011-06-27 23:52:29 +0200 | 
|---|---|---|
| committer | Pieter Noordhuis <pcnoordhuis@gmail.com> | 2011-06-27 23:52:29 +0200 | 
| commit | 3313bcd1912abdced96bc995ede22836c67bcd9d (patch) | |
| tree | 920ea23330d6d075cc21e9f3228fe23236f110e8 | |
| parent | e6d997a96f9af10f08c9c9e52fb545420650b05b (diff) | |
| download | hiredict-3313bcd1912abdced96bc995ede22836c67bcd9d.tar.xz | |
Change prototype of connect callback
This commit adds a status argument to the connect callback. It will be
called in the event of an unsuccessful connection as well, where the
status argument is set to REDIS_ERR. It is set to REDIS_OK otherwise.
| -rw-r--r-- | async.c | 48 | ||||
| -rw-r--r-- | async.h | 2 | 
2 files changed, 43 insertions, 7 deletions
| @@ -34,7 +34,9 @@  #include <strings.h>  #include <assert.h>  #include <ctype.h> +#include <errno.h>  #include "async.h" +#include "net.h"  #include "dict.c"  #include "sds.h" @@ -419,12 +421,43 @@ void redisProcessCallbacks(redisAsyncContext *ac) {          __redisAsyncDisconnect(ac);  } +/* Internal helper function to detect socket status the first time a read or + * write event fires. When connecting was not succesful, the connect callback + * is called with a REDIS_ERR status and the context is free'd. */ +static int __redisAsyncHandleConnect(redisAsyncContext *ac) { +    redisContext *c = &(ac->c); + +    if (redisCheckSocketError(c,c->fd) == REDIS_ERR) { +        /* Try again later when connect(2) is still in progress. */ +        if (errno == EINPROGRESS) +            return REDIS_OK; + +        if (ac->onConnect) ac->onConnect(ac,REDIS_ERR); +        __redisAsyncDisconnect(ac); +        return REDIS_ERR; +    } + +    /* Mark context as connected. */ +    c->flags |= REDIS_CONNECTED; +    if (ac->onConnect) ac->onConnect(ac,REDIS_OK); +    return REDIS_OK; +} +  /* This function should be called when the socket is readable.   * It processes all replies that can be read and executes their callbacks.   */  void redisAsyncHandleRead(redisAsyncContext *ac) {      redisContext *c = &(ac->c); +    if (!(c->flags & REDIS_CONNECTED)) { +        /* Abort connect was not successful. */ +        if (__redisAsyncHandleConnect(ac) != REDIS_OK) +            return; +        /* Try again later when the context is still not connected. */ +        if (!(c->flags & REDIS_CONNECTED)) +            return; +    } +      if (redisBufferRead(c) == REDIS_ERR) {          __redisAsyncDisconnect(ac);      } else { @@ -438,6 +471,15 @@ void redisAsyncHandleWrite(redisAsyncContext *ac) {      redisContext *c = &(ac->c);      int done = 0; +    if (!(c->flags & REDIS_CONNECTED)) { +        /* Abort connect was not successful. */ +        if (__redisAsyncHandleConnect(ac) != REDIS_OK) +            return; +        /* Try again later when the context is still not connected. */ +        if (!(c->flags & REDIS_CONNECTED)) +            return; +    } +      if (redisBufferWrite(c,&done) == REDIS_ERR) {          __redisAsyncDisconnect(ac);      } else { @@ -449,12 +491,6 @@ void redisAsyncHandleWrite(redisAsyncContext *ac) {          /* Always schedule reads after writes */          _EL_ADD_READ(ac); - -        /* Fire onConnect when this is the first write event. */ -        if (!(c->flags & REDIS_CONNECTED)) { -            c->flags |= REDIS_CONNECTED; -            if (ac->onConnect) ac->onConnect(ac); -        }      }  } @@ -55,7 +55,7 @@ typedef struct redisCallbackList {  /* Connection callback prototypes */  typedef void (redisDisconnectCallback)(const struct redisAsyncContext*, int status); -typedef void (redisConnectCallback)(const struct redisAsyncContext*); +typedef void (redisConnectCallback)(const struct redisAsyncContext*, int status);  /* Context for an async connection to Redis */  typedef struct redisAsyncContext { | 
