Return error on socket timeout for a blocking context
This commit is contained in:
parent
ec922cd007
commit
43ab0f8018
11
hiredis.c
11
hiredis.c
@ -851,6 +851,13 @@ redisContext *redisConnectUnixNonBlock(const char *path) {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set read/write timeout on a blocking socket. */
|
||||||
|
int redisSetTimeout(redisContext *c, struct timeval tv) {
|
||||||
|
if (c->flags & REDIS_BLOCK)
|
||||||
|
return redisContextSetTimeout(c,tv);
|
||||||
|
return REDIS_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the replyObjectFunctions to use. Returns REDIS_ERR when the reader
|
/* Set the replyObjectFunctions to use. Returns REDIS_ERR when the reader
|
||||||
* was already initialized and the function set could not be re-set.
|
* was already initialized and the function set could not be re-set.
|
||||||
* Return REDIS_OK when they could be set. */
|
* Return REDIS_OK when they could be set. */
|
||||||
@ -878,7 +885,7 @@ int redisBufferRead(redisContext *c) {
|
|||||||
char buf[2048];
|
char buf[2048];
|
||||||
int nread = read(c->fd,buf,sizeof(buf));
|
int nread = read(c->fd,buf,sizeof(buf));
|
||||||
if (nread == -1) {
|
if (nread == -1) {
|
||||||
if (errno == EAGAIN) {
|
if (errno == EAGAIN && !(c->flags & REDIS_BLOCK)) {
|
||||||
/* Try again later */
|
/* Try again later */
|
||||||
} else {
|
} else {
|
||||||
__redisSetError(c,REDIS_ERR_IO,NULL);
|
__redisSetError(c,REDIS_ERR_IO,NULL);
|
||||||
@ -909,7 +916,7 @@ int redisBufferWrite(redisContext *c, int *done) {
|
|||||||
if (sdslen(c->obuf) > 0) {
|
if (sdslen(c->obuf) > 0) {
|
||||||
nwritten = write(c->fd,c->obuf,sdslen(c->obuf));
|
nwritten = write(c->fd,c->obuf,sdslen(c->obuf));
|
||||||
if (nwritten == -1) {
|
if (nwritten == -1) {
|
||||||
if (errno == EAGAIN) {
|
if (errno == EAGAIN && !(c->flags & REDIS_BLOCK)) {
|
||||||
/* Try again later */
|
/* Try again later */
|
||||||
} else {
|
} else {
|
||||||
__redisSetError(c,REDIS_ERR_IO,NULL);
|
__redisSetError(c,REDIS_ERR_IO,NULL);
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#define __HIREDIS_H
|
#define __HIREDIS_H
|
||||||
#include <stdio.h> /* for size_t */
|
#include <stdio.h> /* for size_t */
|
||||||
#include <stdarg.h> /* for va_list */
|
#include <stdarg.h> /* for va_list */
|
||||||
|
#include <sys/time.h> /* for struct timeval */
|
||||||
|
|
||||||
#define HIREDIS_MAJOR 0
|
#define HIREDIS_MAJOR 0
|
||||||
#define HIREDIS_MINOR 9
|
#define HIREDIS_MINOR 9
|
||||||
@ -146,6 +147,7 @@ redisContext *redisConnect(const char *ip, int port);
|
|||||||
redisContext *redisConnectNonBlock(const char *ip, int port);
|
redisContext *redisConnectNonBlock(const char *ip, int port);
|
||||||
redisContext *redisConnectUnix(const char *path);
|
redisContext *redisConnectUnix(const char *path);
|
||||||
redisContext *redisConnectUnixNonBlock(const char *path);
|
redisContext *redisConnectUnixNonBlock(const char *path);
|
||||||
|
int redisSetTimeout(redisContext *c, struct timeval tv);
|
||||||
int redisSetReplyObjectFunctions(redisContext *c, redisReplyObjectFunctions *fn);
|
int redisSetReplyObjectFunctions(redisContext *c, redisReplyObjectFunctions *fn);
|
||||||
void redisFree(redisContext *c);
|
void redisFree(redisContext *c);
|
||||||
int redisBufferRead(redisContext *c);
|
int redisBufferRead(redisContext *c);
|
||||||
|
14
net.c
14
net.c
@ -98,6 +98,20 @@ static int redisSetTcpNoDelay(redisContext *c, int fd) {
|
|||||||
return REDIS_OK;
|
return REDIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int redisContextSetTimeout(redisContext *c, struct timeval tv) {
|
||||||
|
if (setsockopt(c->fd,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv)) == -1) {
|
||||||
|
__redisSetError(c,REDIS_ERR_IO,
|
||||||
|
sdscatprintf(sdsempty(), "setsockopt(SO_RCVTIMEO): %s", strerror(errno)));
|
||||||
|
return REDIS_ERR;
|
||||||
|
}
|
||||||
|
if (setsockopt(c->fd,SOL_SOCKET,SO_SNDTIMEO,&tv,sizeof(tv)) == -1) {
|
||||||
|
__redisSetError(c,REDIS_ERR_IO,
|
||||||
|
sdscatprintf(sdsempty(), "setsockopt(SO_SNDTIMEO): %s", strerror(errno)));
|
||||||
|
return REDIS_ERR;
|
||||||
|
}
|
||||||
|
return REDIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int redisContextConnectTcp(redisContext *c, const char *addr, int port) {
|
int redisContextConnectTcp(redisContext *c, const char *addr, int port) {
|
||||||
int s;
|
int s;
|
||||||
int blocking = (c->flags & REDIS_BLOCK);
|
int blocking = (c->flags & REDIS_BLOCK);
|
||||||
|
1
net.h
1
net.h
@ -39,6 +39,7 @@
|
|||||||
#define AF_LOCAL AF_UNIX
|
#define AF_LOCAL AF_UNIX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int redisContextSetTimeout(redisContext *c, struct timeval tv);
|
||||||
int redisContextConnectTcp(redisContext *c, const char *addr, int port);
|
int redisContextConnectTcp(redisContext *c, const char *addr, int port);
|
||||||
int redisContextConnectUnix(redisContext *c, const char *path);
|
int redisContextConnectUnix(redisContext *c, const char *path);
|
||||||
|
|
||||||
|
13
test.c
13
test.c
@ -6,6 +6,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include "hiredis.h"
|
#include "hiredis.h"
|
||||||
|
|
||||||
@ -246,9 +247,17 @@ static void test_blocking_connection() {
|
|||||||
* conditions, the error will be set to EOF. */
|
* conditions, the error will be set to EOF. */
|
||||||
assert(c->err == REDIS_ERR_EOF &&
|
assert(c->err == REDIS_ERR_EOF &&
|
||||||
strcmp(c->errstr,"Server closed the connection") == 0);
|
strcmp(c->errstr,"Server closed the connection") == 0);
|
||||||
|
|
||||||
/* Clean up context and reconnect again */
|
|
||||||
redisFree(c);
|
redisFree(c);
|
||||||
|
|
||||||
|
__connect(&c);
|
||||||
|
test("Returns I/O error on socket timeout: ");
|
||||||
|
struct timeval tv = { 0, 1000 };
|
||||||
|
assert(redisSetTimeout(c,tv) == REDIS_OK);
|
||||||
|
test_cond(redisGetReply(c,(void**)&reply) == REDIS_ERR &&
|
||||||
|
c->err == REDIS_ERR_IO && errno == EAGAIN);
|
||||||
|
redisFree(c);
|
||||||
|
|
||||||
|
/* Context should be connected */
|
||||||
__connect(&c);
|
__connect(&c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user