Remove reply object functions from connect functions

This commit is contained in:
Pieter Noordhuis 2010-10-31 12:51:59 +01:00
parent 47e1f77149
commit f463734e91
3 changed files with 31 additions and 11 deletions

View File

@ -633,12 +633,12 @@ static int redisContextConnect(redisContext *c, const char *ip, int port) {
return REDIS_OK; return REDIS_OK;
} }
static redisContext *redisContextInit(redisReplyObjectFunctions *fn) { static redisContext *redisContextInit() {
redisContext *c = calloc(sizeof(redisContext),1); redisContext *c = calloc(sizeof(redisContext),1);
c->error = NULL; c->error = NULL;
c->obuf = sdsempty(); c->obuf = sdsempty();
c->fn = fn == NULL ? &defaultFunctions : fn; c->fn = &defaultFunctions;
c->reader = redisReplyReaderCreate(c->fn); c->reader = NULL;
return c; return c;
} }
@ -661,29 +661,46 @@ void redisFree(redisContext *c) {
sdsfree(c->error); sdsfree(c->error);
if (c->obuf != NULL) if (c->obuf != NULL)
sdsfree(c->obuf); sdsfree(c->obuf);
redisReplyReaderFree(c->reader); if (c->reader != NULL)
redisReplyReaderFree(c->reader);
free(c); free(c);
} }
/* Connect to a Redis instance. On error the field error in the returned /* Connect to a Redis instance. On error the field error in the returned
* context will be set to the return value of the error function. * context will be set to the return value of the error function.
* When no set of reply functions is given, the default set will be used. */ * When no set of reply functions is given, the default set will be used. */
redisContext *redisConnect(const char *ip, int port, redisReplyObjectFunctions *fn) { redisContext *redisConnect(const char *ip, int port) {
redisContext *c = redisContextInit(fn); redisContext *c = redisContextInit();
c->flags |= REDIS_BLOCK; c->flags |= REDIS_BLOCK;
c->flags |= REDIS_CONNECTED; c->flags |= REDIS_CONNECTED;
redisContextConnect(c,ip,port); redisContextConnect(c,ip,port);
return c; return c;
} }
redisContext *redisConnectNonBlock(const char *ip, int port, redisReplyObjectFunctions *fn) { redisContext *redisConnectNonBlock(const char *ip, int port) {
redisContext *c = redisContextInit(fn); redisContext *c = redisContextInit();
c->flags &= ~REDIS_BLOCK; c->flags &= ~REDIS_BLOCK;
c->flags |= REDIS_CONNECTED; c->flags |= REDIS_CONNECTED;
redisContextConnect(c,ip,port); redisContextConnect(c,ip,port);
return c; return c;
} }
/* Set the replyObjectFunctions to use. Returns REDIS_ERR when the reader
* was already initialized and the function set could not be re-set.
* Return REDIS_OK when they could be set. */
int redisSetReplyObjectFunctions(redisContext *c, redisReplyObjectFunctions *fn) {
if (c->reader != NULL)
return REDIS_ERR;
c->fn = fn;
return REDIS_OK;
}
/* Helper function to lazily create a reply reader. */
static void __redisCreateReplyReader(redisContext *c) {
if (c->reader == NULL)
c->reader = redisReplyReaderCreate(c->fn);
}
/* Register callback that is triggered when redisDisconnect is called. */ /* Register callback that is triggered when redisDisconnect is called. */
void redisSetDisconnectCallback(redisContext *c, redisContextCallbackFn *fn, void *privdata) { void redisSetDisconnectCallback(redisContext *c, redisContextCallbackFn *fn, void *privdata) {
c->cbDisconnect.fn = fn; c->cbDisconnect.fn = fn;
@ -725,6 +742,7 @@ int redisBufferRead(redisContext *c) {
"read: Server closed the connection"); "read: Server closed the connection");
return REDIS_ERR; return REDIS_ERR;
} else { } else {
__redisCreateReplyReader(c);
redisReplyReaderFeed(c->reader,buf,nread); redisReplyReaderFeed(c->reader,buf,nread);
} }
return REDIS_OK; return REDIS_OK;
@ -768,6 +786,7 @@ int redisBufferWrite(redisContext *c, int *done) {
/* Internal helper function to try and get a reply from the reader, /* Internal helper function to try and get a reply from the reader,
* or set an error in the context otherwise. */ * or set an error in the context otherwise. */
static int __redisGetReply(redisContext *c, void **reply) { static int __redisGetReply(redisContext *c, void **reply) {
__redisCreateReplyReader(c);
if (redisReplyReaderGetReply(c->reader,reply) == REDIS_ERR) { if (redisReplyReaderGetReply(c->reader,reply) == REDIS_ERR) {
/* Copy the (protocol) error from the reader to the context. */ /* Copy the (protocol) error from the reader to the context. */
c->error = sdsnew(((redisReader*)c->reader)->error); c->error = sdsnew(((redisReader*)c->reader)->error);

View File

@ -114,8 +114,9 @@ int redisvFormatCommand(char **target, const char *format, va_list ap);
int redisFormatCommand(char **target, const char *format, ...); int redisFormatCommand(char **target, const char *format, ...);
int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen); int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen);
redisContext *redisConnect(const char *ip, int port, redisReplyObjectFunctions *fn); redisContext *redisConnect(const char *ip, int port);
redisContext *redisConnectNonBlock(const char *ip, int port, redisReplyObjectFunctions *fn); redisContext *redisConnectNonBlock(const char *ip, int port);
int redisSetReplyObjectFunctions(redisContext *c, redisReplyObjectFunctions *fn);
void redisDisconnect(redisContext *c); void redisDisconnect(redisContext *c);
void redisFree(redisContext *c); void redisFree(redisContext *c);
int redisBufferRead(redisContext *c); int redisBufferRead(redisContext *c);

2
test.c
View File

@ -21,7 +21,7 @@ static long long usec(void) {
static redisContext *blocking_context = NULL; static redisContext *blocking_context = NULL;
static void __connect(redisContext **target) { static void __connect(redisContext **target) {
*target = blocking_context = redisConnect((char*)"127.0.0.1", 6379, NULL); *target = blocking_context = redisConnect((char*)"127.0.0.1", 6379);
if (blocking_context->error != NULL) { if (blocking_context->error != NULL) {
printf("Connection error: %s\n", blocking_context->error); printf("Connection error: %s\n", blocking_context->error);
exit(1); exit(1);