Use a windows specific keepalive function. (#1104)
Use a windows specific keepalive function. While it is possible to toggle `TCP_KEEPALIVE` in windows via setsockopt, you have to use `WSAIoctl` to set the interval. Since `WSAIoctl` can actually do all of this in one call (toggle the option, and set the corresponding interval), just use that in Windows and avoid the call to `setsockopt` alltogether. Fixes: #1100
This commit is contained in:
parent
fce8abc1c1
commit
61b5b299f0
9
net.c
9
net.c
@ -168,6 +168,7 @@ int redisKeepAlive(redisContext *c, int interval) {
|
||||
int val = 1;
|
||||
redisFD fd = c->fd;
|
||||
|
||||
#ifndef _WIN32
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1){
|
||||
__redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
|
||||
return REDIS_ERR;
|
||||
@ -201,7 +202,15 @@ int redisKeepAlive(redisContext *c, int interval) {
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
int res;
|
||||
|
||||
res = win32_redisKeepAlive(fd, interval * 1000);
|
||||
if (res != 0) {
|
||||
__redisSetError(c, REDIS_ERR_OTHER, strerror(res));
|
||||
return REDIS_ERR;
|
||||
}
|
||||
#endif
|
||||
return REDIS_OK;
|
||||
}
|
||||
|
||||
|
17
sockcompat.c
17
sockcompat.c
@ -260,4 +260,21 @@ int win32_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
|
||||
_updateErrno(ret != SOCKET_ERROR);
|
||||
return ret != SOCKET_ERROR ? ret : -1;
|
||||
}
|
||||
|
||||
int win32_redisKeepAlive(SOCKET sockfd, int interval_ms) {
|
||||
struct tcp_keepalive cfg;
|
||||
DWORD bytes_in;
|
||||
int res;
|
||||
|
||||
cfg.onoff = 1;
|
||||
cfg.keepaliveinterval = interval_ms;
|
||||
cfg.keepalivetime = interval_ms;
|
||||
|
||||
res = WSAIoctl(sockfd, SIO_KEEPALIVE_VALS, &cfg,
|
||||
sizeof(struct tcp_keepalive), NULL, 0,
|
||||
&bytes_in, NULL, NULL);
|
||||
|
||||
return res == 0 ? 0 : _wsaErrorToErrno(res);
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include <ws2tcpip.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
#include <Mstcpip.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef long long ssize_t;
|
||||
@ -71,6 +72,8 @@ ssize_t win32_send(SOCKET sockfd, const void *buf, size_t len, int flags);
|
||||
typedef ULONG nfds_t;
|
||||
int win32_poll(struct pollfd *fds, nfds_t nfds, int timeout);
|
||||
|
||||
int win32_redisKeepAlive(SOCKET sockfd, int interval_ms);
|
||||
|
||||
#ifndef REDIS_SOCKCOMPAT_IMPLEMENTATION
|
||||
#define getaddrinfo(node, service, hints, res) win32_getaddrinfo(node, service, hints, res)
|
||||
#undef gai_strerror
|
||||
|
11
test.c
11
test.c
@ -405,6 +405,16 @@ static void test_append_formatted_commands(struct config config) {
|
||||
disconnect(c, 0);
|
||||
}
|
||||
|
||||
static void test_tcp_options(struct config cfg) {
|
||||
redisContext *c;
|
||||
|
||||
c = do_connect(cfg);
|
||||
test("We can enable TCP_KEEPALIVE: ");
|
||||
test_cond(redisEnableKeepAlive(c) == REDIS_OK);
|
||||
|
||||
disconnect(c, 0);
|
||||
}
|
||||
|
||||
static void test_reply_reader(void) {
|
||||
redisReader *reader;
|
||||
void *reply, *root;
|
||||
@ -2261,6 +2271,7 @@ int main(int argc, char **argv) {
|
||||
test_blocking_io_errors(cfg);
|
||||
test_invalid_timeout_errors(cfg);
|
||||
test_append_formatted_commands(cfg);
|
||||
test_tcp_options(cfg);
|
||||
if (throughput) test_throughput(cfg);
|
||||
|
||||
printf("\nTesting against Unix socket connection (%s): ", cfg.unix_sock.path);
|
||||
|
Loading…
x
Reference in New Issue
Block a user