Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
hiredis
Commits
43ab0f80
Commit
43ab0f80
authored
Jan 07, 2011
by
Pieter Noordhuis
Browse files
Return error on socket timeout for a blocking context
parent
ec922cd0
Changes
5
Hide whitespace changes
Inline
Side-by-side
hiredis.c
View file @
43ab0f80
...
@@ -851,6 +851,13 @@ redisContext *redisConnectUnixNonBlock(const char *path) {
...
@@ -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) {
...
@@ -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) {
...
@@ -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
);
...
...
hiredis.h
View file @
43ab0f80
...
@@ -33,6 +33,7 @@
...
@@ -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);
...
@@ -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
);
...
...
net.c
View file @
43ab0f80
...
@@ -98,6 +98,20 @@ static int redisSetTcpNoDelay(redisContext *c, int fd) {
...
@@ -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
);
...
...
net.h
View file @
43ab0f80
...
@@ -39,6 +39,7 @@
...
@@ -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
);
...
...
test.c
View file @
43ab0f80
...
@@ -6,6 +6,7 @@
...
@@ -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() {
...
@@ -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
);
redisFree
(
c
);
/* Clean up context and reconnect again */
__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
);
redisFree
(
c
);
/* Context should be connected */
__connect
(
&
c
);
__connect
(
&
c
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment