Provide option-struct initialization
This reduces the boilerplate of all the redisConnectXXX functions, and allows us to provide more connection options in the future.
This commit is contained in:
parent
d329cc952a
commit
e4a78006e7
151
hiredis.c
151
hiredis.c
@ -584,14 +584,21 @@ redisReader *redisReaderCreate(void) {
|
|||||||
return redisReaderCreateWithFunctions(&defaultFunctions);
|
return redisReaderCreateWithFunctions(&defaultFunctions);
|
||||||
}
|
}
|
||||||
|
|
||||||
static redisContext *redisContextInit(void) {
|
static redisContext *redisContextInit(const redisOptions *options) {
|
||||||
redisContext *c;
|
redisContext *c;
|
||||||
|
|
||||||
c = calloc(1,sizeof(redisContext));
|
c = calloc(1, sizeof(*c));
|
||||||
if (c == NULL)
|
if (c == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
c->err = 0;
|
||||||
|
c->errstr[0] = '\0';
|
||||||
c->obuf = sdsempty();
|
c->obuf = sdsempty();
|
||||||
|
c->flags = 0;
|
||||||
|
c->tcp.host = NULL;
|
||||||
|
c->tcp.source_addr = NULL;
|
||||||
|
c->unix_sock.path = NULL;
|
||||||
|
c->timeout = NULL;
|
||||||
c->reader = redisReaderCreate();
|
c->reader = redisReaderCreate();
|
||||||
|
|
||||||
if (c->obuf == NULL || c->reader == NULL) {
|
if (c->obuf == NULL || c->reader == NULL) {
|
||||||
@ -655,112 +662,100 @@ int redisReconnect(redisContext *c) {
|
|||||||
return REDIS_ERR;
|
return REDIS_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
redisContext *redisConnectWithOptions(const redisOptions *options) {
|
||||||
|
redisContext *c = redisContextInit(options);
|
||||||
|
if (c == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!(options->options & REDIS_OPT_NONBLOCK)) {
|
||||||
|
c->flags |= REDIS_BLOCK;
|
||||||
|
}
|
||||||
|
if (options->options & REDIS_OPT_REUSEADDR) {
|
||||||
|
c->flags |= REDIS_REUSEADDR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options->type == REDIS_CONN_TCP) {
|
||||||
|
redisContextConnectBindTcp(c, options->endpoint.tcp.ip,
|
||||||
|
options->endpoint.tcp.port, options->timeout,
|
||||||
|
options->endpoint.tcp.source_addr);
|
||||||
|
} else if (options->type == REDIS_CONN_UNIX) {
|
||||||
|
redisContextConnectUnix(c, options->endpoint.unix_socket,
|
||||||
|
options->timeout);
|
||||||
|
} else if (options->type == REDIS_CONN_USERFD) {
|
||||||
|
c->fd = options->endpoint.fd;
|
||||||
|
c->flags |= REDIS_CONNECTED;
|
||||||
|
} else {
|
||||||
|
// Unknown type - FIXME - FREE
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return 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) {
|
redisContext *redisConnect(const char *ip, int port) {
|
||||||
redisContext *c;
|
redisOptions options = {0};
|
||||||
|
REDIS_OPTIONS_SET_TCP(&options, ip, port);
|
||||||
c = redisContextInit();
|
return redisConnectWithOptions(&options);
|
||||||
if (c == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
c->flags |= REDIS_BLOCK;
|
|
||||||
redisContextConnectTcp(c,ip,port,NULL);
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv) {
|
redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv) {
|
||||||
redisContext *c;
|
redisOptions options = {0};
|
||||||
|
REDIS_OPTIONS_SET_TCP(&options, ip, port);
|
||||||
c = redisContextInit();
|
options.timeout = &tv;
|
||||||
if (c == NULL)
|
return redisConnectWithOptions(&options);
|
||||||
return NULL;
|
|
||||||
|
|
||||||
c->flags |= REDIS_BLOCK;
|
|
||||||
redisContextConnectTcp(c,ip,port,&tv);
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
redisContext *redisConnectNonBlock(const char *ip, int port) {
|
redisContext *redisConnectNonBlock(const char *ip, int port) {
|
||||||
redisContext *c;
|
redisOptions options = {0};
|
||||||
|
REDIS_OPTIONS_SET_TCP(&options, ip, port);
|
||||||
c = redisContextInit();
|
options.options |= REDIS_OPT_NONBLOCK;
|
||||||
if (c == NULL)
|
return redisConnectWithOptions(&options);
|
||||||
return NULL;
|
|
||||||
|
|
||||||
c->flags &= ~REDIS_BLOCK;
|
|
||||||
redisContextConnectTcp(c,ip,port,NULL);
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
redisContext *redisConnectBindNonBlock(const char *ip, int port,
|
redisContext *redisConnectBindNonBlock(const char *ip, int port,
|
||||||
const char *source_addr) {
|
const char *source_addr) {
|
||||||
redisContext *c = redisContextInit();
|
redisOptions options = {0};
|
||||||
if (c == NULL)
|
REDIS_OPTIONS_SET_TCP(&options, ip, port);
|
||||||
return NULL;
|
options.endpoint.tcp.source_addr = source_addr;
|
||||||
c->flags &= ~REDIS_BLOCK;
|
options.options |= REDIS_OPT_NONBLOCK;
|
||||||
redisContextConnectBindTcp(c,ip,port,NULL,source_addr);
|
return redisConnectWithOptions(&options);
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port,
|
redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port,
|
||||||
const char *source_addr) {
|
const char *source_addr) {
|
||||||
redisContext *c = redisContextInit();
|
redisOptions options = {0};
|
||||||
if (c == NULL)
|
REDIS_OPTIONS_SET_TCP(&options, ip, port);
|
||||||
return NULL;
|
options.endpoint.tcp.source_addr = source_addr;
|
||||||
c->flags &= ~REDIS_BLOCK;
|
options.options |= REDIS_OPT_NONBLOCK|REDIS_OPT_REUSEADDR;
|
||||||
c->flags |= REDIS_REUSEADDR;
|
return redisConnectWithOptions(&options);
|
||||||
redisContextConnectBindTcp(c,ip,port,NULL,source_addr);
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
redisContext *redisConnectUnix(const char *path) {
|
redisContext *redisConnectUnix(const char *path) {
|
||||||
redisContext *c;
|
redisOptions options = {0};
|
||||||
|
REDIS_OPTIONS_SET_UNIX(&options, path);
|
||||||
c = redisContextInit();
|
return redisConnectWithOptions(&options);
|
||||||
if (c == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
c->flags |= REDIS_BLOCK;
|
|
||||||
redisContextConnectUnix(c,path,NULL);
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv) {
|
redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv) {
|
||||||
redisContext *c;
|
redisOptions options = {0};
|
||||||
|
REDIS_OPTIONS_SET_UNIX(&options, path);
|
||||||
c = redisContextInit();
|
options.timeout = &tv;
|
||||||
if (c == NULL)
|
return redisConnectWithOptions(&options);
|
||||||
return NULL;
|
|
||||||
|
|
||||||
c->flags |= REDIS_BLOCK;
|
|
||||||
redisContextConnectUnix(c,path,&tv);
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
redisContext *redisConnectUnixNonBlock(const char *path) {
|
redisContext *redisConnectUnixNonBlock(const char *path) {
|
||||||
redisContext *c;
|
redisOptions options = {0};
|
||||||
|
REDIS_OPTIONS_SET_UNIX(&options, path);
|
||||||
c = redisContextInit();
|
options.options |= REDIS_OPT_NONBLOCK;
|
||||||
if (c == NULL)
|
return redisConnectWithOptions(&options);
|
||||||
return NULL;
|
|
||||||
|
|
||||||
c->flags &= ~REDIS_BLOCK;
|
|
||||||
redisContextConnectUnix(c,path,NULL);
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
redisContext *redisConnectFd(int fd) {
|
redisContext *redisConnectFd(int fd) {
|
||||||
redisContext *c;
|
redisOptions options = {REDIS_CONN_USERFD};
|
||||||
|
options.endpoint.fd = fd;
|
||||||
c = redisContextInit();
|
return redisConnectWithOptions(&options);
|
||||||
if (c == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
c->fd = fd;
|
|
||||||
c->flags |= REDIS_BLOCK | REDIS_CONNECTED;
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int redisSecureConnection(redisContext *c, const char *caPath,
|
int redisSecureConnection(redisContext *c, const char *caPath,
|
||||||
|
45
hiredis.h
45
hiredis.h
@ -112,11 +112,53 @@ void redisFreeSdsCommand(sds cmd);
|
|||||||
|
|
||||||
enum redisConnectionType {
|
enum redisConnectionType {
|
||||||
REDIS_CONN_TCP,
|
REDIS_CONN_TCP,
|
||||||
REDIS_CONN_UNIX
|
REDIS_CONN_UNIX,
|
||||||
|
REDIS_CONN_USERFD
|
||||||
};
|
};
|
||||||
|
|
||||||
struct redisSsl;
|
struct redisSsl;
|
||||||
|
|
||||||
|
#define REDIS_OPT_NONBLOCK 0x01
|
||||||
|
#define REDIS_OPT_REUSEADDR 0x02
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/*
|
||||||
|
* the type of connection to use. This also indicates which
|
||||||
|
* `endpoint` member field to use
|
||||||
|
*/
|
||||||
|
int type;
|
||||||
|
/* bit field of REDIS_OPT_xxx */
|
||||||
|
int options;
|
||||||
|
/* timeout value. if NULL, no timeout is used */
|
||||||
|
const struct timeval *timeout;
|
||||||
|
union {
|
||||||
|
/** use this field for tcp/ip connections */
|
||||||
|
struct {
|
||||||
|
const char *source_addr;
|
||||||
|
const char *ip;
|
||||||
|
int port;
|
||||||
|
} tcp;
|
||||||
|
/** use this field for unix domain sockets */
|
||||||
|
const char *unix_socket;
|
||||||
|
/**
|
||||||
|
* use this field to have hiredis operate an already-open
|
||||||
|
* file descriptor */
|
||||||
|
int fd;
|
||||||
|
} endpoint;
|
||||||
|
} redisOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper macros to initialize options to their specified fields.
|
||||||
|
*/
|
||||||
|
#define REDIS_OPTIONS_SET_TCP(opts, ip_, port_) \
|
||||||
|
(opts)->type = REDIS_CONN_TCP; \
|
||||||
|
(opts)->endpoint.tcp.ip = ip_; \
|
||||||
|
(opts)->endpoint.tcp.port = port;
|
||||||
|
|
||||||
|
#define REDIS_OPTIONS_SET_UNIX(opts, path) \
|
||||||
|
(opts)->type = REDIS_CONN_UNIX; \
|
||||||
|
(opts)->endpoint.unix_socket = path;
|
||||||
|
|
||||||
/* Context for a connection to Redis */
|
/* Context for a connection to Redis */
|
||||||
typedef struct redisContext {
|
typedef struct redisContext {
|
||||||
int err; /* Error flags, 0 when there is no error */
|
int err; /* Error flags, 0 when there is no error */
|
||||||
@ -147,6 +189,7 @@ typedef struct redisContext {
|
|||||||
|
|
||||||
} redisContext;
|
} redisContext;
|
||||||
|
|
||||||
|
redisContext *redisConnectWithOptions(const redisOptions *options);
|
||||||
redisContext *redisConnect(const char *ip, int port);
|
redisContext *redisConnect(const char *ip, int port);
|
||||||
redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv);
|
redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv);
|
||||||
redisContext *redisConnectNonBlock(const char *ip, int port);
|
redisContext *redisConnectNonBlock(const char *ip, int port);
|
||||||
|
Loading…
Reference in New Issue
Block a user