[Cleanup] Code refacoring.

This commit is contained in:
Enrico Giordani
2015-08-20 13:20:57 +02:00
parent bc3251aa8a
commit 7bf5ba87e2
9 changed files with 172 additions and 253 deletions
+9 -10
View File
@@ -160,16 +160,15 @@ int redisKeepAlive(redisContext *c, int interval) {
settings.keepalivetime = interval*1000;
settings.keepaliveinterval = interval*1000/3;
overlapped.hEvent = NULL;
WSAIoctl(
fd,
SIO_KEEPALIVE_VALS,
&settings,
sizeof(struct tcp_keepalive),
NULL,
0,
&bytesReturned,
&overlapped,
NULL);
FDAPI_WSAIoctl(fd,
SIO_KEEPALIVE_VALS,
&settings,
sizeof(struct tcp_keepalive),
NULL,
0,
&bytesReturned,
&overlapped,
NULL);
}
#else
val = interval;
+16
View File
@@ -46,3 +46,19 @@ void EnsureMemoryIsMapped(const void *buffer, size_t size) {
}
}
}
bool IsWindowsVersionAtLeast(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) {
OSVERSIONINFOEXW osvi = {sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0};
DWORDLONG const dwlConditionMask = VerSetConditionMask(
VerSetConditionMask(
VerSetConditionMask(
0, VER_MAJORVERSION, VER_GREATER_EQUAL),
VER_MINORVERSION, VER_GREATER_EQUAL),
VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
osvi.dwMajorVersion = wMajorVersion;
osvi.dwMinorVersion = wMinorVersion;
osvi.wServicePackMajor = wServicePackMajor;
return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
}
+4 -1
View File
@@ -23,11 +23,14 @@
#ifndef WIN32_COMMON_H
#define WIN32_COMMON_H
void EnsureMemoryIsMapped(const void *buffer, size_t size);
#include <Windows.h>
namespace Globals {
// forward declarations only
extern size_t pageSize;
}
void EnsureMemoryIsMapped(const void *buffer, size_t size);
bool IsWindowsVersionAtLeast(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor);
#endif
+106 -160
View File
@@ -33,15 +33,14 @@
#include "win32_util.h"
#include <string>
#include "Win32_RedisLog.h"
#include "Win32_Common.h"
using namespace std;
#define CATCH_AND_REPORT() catch(const std::exception &){::redisLog(REDIS_WARNING, "FDAPI: std exception");}catch(...){::redisLog(REDIS_WARNING, "FDAPI: other exception");}
extern "C" {
// FD lookup Winsock equivalents for Win32_wsiocp.c
redis_WSASetLastError WSASetLastError = NULL;
redis_WSAGetLastError WSAGetLastError = NULL;
redis_WSAIoctl WSAIoctl = NULL;
redis_WSASend WSASend = NULL;
redis_WSARecv WSARecv = NULL;
redis_WSAGetOverlappedResult WSAGetOverlappedResult = NULL;
@@ -92,7 +91,11 @@ redis_freeaddrinfo freeaddrinfo = NULL;
redis_getaddrinfo getaddrinfo = NULL;
redis_inet_ntop inet_ntop = NULL;
redis_inet_pton inet_pton = NULL;
redis_FD_ISSET FD_ISSET = NULL;
}
auto f_WSAGetLastError = dllfunctor_stdcall<int>("ws2_32.dll", "WSAGetLastError");
int FDAPI_WSAGetLastError(void) {
return f_WSAGetLastError();
}
void FDAPI_SaveSocketAddrStorage(int rfd, SOCKADDR_STORAGE* socketAddrStorage) {
@@ -102,23 +105,52 @@ void FDAPI_SaveSocketAddrStorage(int rfd, SOCKADDR_STORAGE* socketAddrStorage) {
}
}
BOOL FDAPI_SetFDInformation(int rfd, DWORD mask, DWORD flags) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
return SetHandleInformation((HANDLE) socket, mask, flags);
}
} CATCH_AND_REPORT();
auto f_ioctlsocket = dllfunctor_stdcall<int, SOCKET, long, u_long*>("ws2_32.dll", "ioctlsocket");
BOOL FDAPI_SocketAttachIOCP(int rfd, HANDLE iocph) {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
// Set the socket to nonblocking mode
DWORD yes = 1;
if (f_ioctlsocket(socket, FIONBIO, &yes) != SOCKET_ERROR) {
// Make the socket non-inheritable
if (SetHandleInformation((HANDLE) socket, HANDLE_FLAG_INHERIT, 0)) {
// Associate it with the I/O completion port.
// Use the rfd as the completion key.
if (CreateIoCompletionPort((HANDLE) socket,
iocph,
(ULONG_PTR) rfd,
0) != NULL) {
return TRUE;
}
}
}
errno = f_WSAGetLastError();
} else {
errno = EBADF;
}
return FALSE;
}
auto f_ioctlsocket = dllfunctor_stdcall<int, SOCKET, long, u_long*>("ws2_32.dll", "ioctlsocket");
int FDAPI_ioctlsocket(int rfd, long cmd, u_long *argp) {
auto f_WSAIoctl = dllfunctor_stdcall<int, SOCKET, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPVOID, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE>("ws2_32.dll", "WSAIoctl");
int FDAPI_WSAIoctl(int rfd, DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
return f_ioctlsocket(socket, cmd, argp);
if (f_WSAIoctl(socket,
dwIoControlCode,
lpvInBuffer,
cbInBuffer,
lpvOutBuffer,
cbOutBuffer,
lpcbBytesReturned,
lpOverlapped,
lpCompletionRoutine) == 0) {
return 0;
} else {
errno = f_WSAGetLastError();
return SOCKET_ERROR;
}
}
} CATCH_AND_REPORT();
@@ -126,18 +158,6 @@ int FDAPI_ioctlsocket(int rfd, long cmd, u_long *argp) {
return SOCKET_ERROR;
}
HANDLE FDAPI_CreateIoCompletionPortOnFD(int rfd, HANDLE ExistingCompletionPort, ULONG_PTR CompletionKey, DWORD NumberOfConcurrentThreads) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
return CreateIoCompletionPort((HANDLE) socket, ExistingCompletionPort, CompletionKey, NumberOfConcurrentThreads);
}
} CATCH_AND_REPORT();
return INVALID_HANDLE_VALUE;
}
auto f_WSAIoctl = dllfunctor_stdcall<int, SOCKET, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPVOID, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE>("ws2_32.dll", "WSAIoctl");
BOOL FDAPI_AcceptEx(int listenFD, int acceptFD, PVOID lpOutputBuffer, DWORD dwReceiveDataLength, DWORD dwLocalAddressLength, DWORD dwRemoteAddressLength, LPDWORD lpdwBytesReceived, LPOVERLAPPED lpOverlapped) {
try {
SOCKET sListen = RFDMap::getInstance().lookupSocket(listenFD);
@@ -165,38 +185,18 @@ BOOL FDAPI_AcceptEx(int listenFD, int acceptFD, PVOID lpOutputBuffer, DWORD dwRe
return FALSE;
}
bool IsWindowsVersionAtLeast(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) {
OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, { 0 }, 0, 0 };
DWORDLONG const dwlConditionMask = VerSetConditionMask(
VerSetConditionMask(
VerSetConditionMask(
0, VER_MAJORVERSION, VER_GREATER_EQUAL),
VER_MINORVERSION, VER_GREATER_EQUAL),
VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
osvi.dwMajorVersion = wMajorVersion;
osvi.dwMinorVersion = wMinorVersion;
osvi.wServicePackMajor = wServicePackMajor;
return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
}
#ifndef _WIN32_WINNT_WIN8
#define _WIN32_WINNT_WIN8 0x0602
#endif
#ifndef SIO_LOOPBACK_FAST_PATH
const DWORD SIO_LOOPBACK_FAST_PATH = 0x98000010; // from Win8 SDK
#endif
void EnableFastLoopback(SOCKET socket) {
// If Win8+, use fast path option on loopback
if (IsWindowsVersionAtLeast(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0)) {
// If Win8+ (6.2), use fast path option on loopback
if (IsWindowsVersionAtLeast(6, 2, 0)) {
int enabled = 1;
DWORD result_byte_count = -1;
int result = f_WSAIoctl(socket, SIO_LOOPBACK_FAST_PATH, &enabled, sizeof(enabled), NULL, 0, &result_byte_count, NULL, NULL);
if (result != 0) {
throw std::system_error(WSAGetLastError(), system_category(), "WSAIoctl failed");
throw std::system_error(f_WSAGetLastError(), system_category(), "WSAIoctl failed");
}
}
}
@@ -209,15 +209,15 @@ BOOL FDAPI_ConnectEx(int rfd, const struct sockaddr *name, int namelen, PVOID lp
const GUID wsaid_connectex = WSAID_CONNECTEX;
DWORD bytes;
if (SOCKET_ERROR == WSAIoctl(rfd,
SIO_GET_EXTENSION_FUNCTION_POINTER,
(void *) &wsaid_connectex,
sizeof(GUID),
&connectex,
sizeof(LPFN_ACCEPTEX),
&bytes,
NULL,
NULL)) {
if (SOCKET_ERROR == f_WSAIoctl(socket,
SIO_GET_EXTENSION_FUNCTION_POINTER,
(void *) &wsaid_connectex,
sizeof(GUID),
&connectex,
sizeof(LPFN_ACCEPTEX),
&bytes,
NULL,
NULL)) {
return FALSE;
}
@@ -243,15 +243,15 @@ void FDAPI_GetAcceptExSockaddrs(int rfd, PVOID lpOutputBuffer, DWORD dwReceiveDa
const GUID wsaid_getacceptsockaddrs = WSAID_GETACCEPTEXSOCKADDRS;
DWORD bytes;
if (SOCKET_ERROR == WSAIoctl(rfd,
SIO_GET_EXTENSION_FUNCTION_POINTER,
(void *) &wsaid_getacceptsockaddrs,
sizeof(GUID),
&getacceptsockaddrs,
sizeof(LPFN_ACCEPTEX),
&bytes,
NULL,
NULL)) {
if (SOCKET_ERROR == f_WSAIoctl(socket,
SIO_GET_EXTENSION_FUNCTION_POINTER,
(void *) &wsaid_getacceptsockaddrs,
sizeof(GUID),
&getacceptsockaddrs,
sizeof(LPFN_ACCEPTEX),
&bytes,
NULL,
NULL)) {
return;
}
@@ -267,17 +267,20 @@ void FDAPI_GetAcceptExSockaddrs(int rfd, PVOID lpOutputBuffer, DWORD dwReceiveDa
} CATCH_AND_REPORT();
}
auto f_setsockopt = dllfunctor_stdcall<int, SOCKET, int, int, const char*, int>("ws2_32.dll", "setsockopt");
int FDAPI_UpdateAcceptContext(int rfd) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
return setsockopt(rfd,
SOL_SOCKET,
SO_UPDATE_ACCEPT_CONTEXT,
(char*) &socket,
sizeof(SOCKET));
return f_setsockopt(socket,
SOL_SOCKET,
SO_UPDATE_ACCEPT_CONTEXT,
(char*) &socket,
sizeof(SOCKET));
}
} CATCH_AND_REPORT();
errno = EBADF;
return SOCKET_ERROR;
}
@@ -304,19 +307,6 @@ void FDAPI_ClearSocketState(int rfd) {
}
}
auto f_socket = dllfunctor_stdcall<SOCKET, int, int, int>("ws2_32.dll", "socket");
int redis_socket_impl(int af, int type, int protocol) {
try {
SOCKET socket = f_socket(af, type, protocol);
if (socket != INVALID_SOCKET) {
return RFDMap::getInstance().addSocket(socket);
}
} CATCH_AND_REPORT();
errno = EBADF;
return -1;
}
int FDAPI_PipeSetNonBlock(int rfd, int non_blocking) {
try {
int posixFD = RFDMap::getInstance().lookupPosixFD(rfd);
@@ -381,6 +371,22 @@ int redis_pipe_impl(int *pfds) {
return result;
}
auto f_socket = dllfunctor_stdcall<SOCKET, int, int, int>("ws2_32.dll", "socket");
int redis_socket_impl(int af, int type, int protocol) {
try {
SOCKET socket = f_socket(af, type, protocol);
if (socket != INVALID_SOCKET) {
return RFDMap::getInstance().addSocket(socket);
} else {
errno = f_WSAGetLastError();
return -1;
}
} CATCH_AND_REPORT();
errno = EBADF;
return -1;
}
// In unix a fd is a fd. All are closed with close().
auto f_closesocket = dllfunctor_stdcall<int, SOCKET>("ws2_32.dll", "closesocket");
int redis_close_impl(RFD rfd) {
@@ -429,7 +435,7 @@ int redis_accept_impl(int rfd, struct sockaddr *addr, socklen_t *addrlen) {
if (sAccept != INVALID_SOCKET) {
return RFDMap::getInstance().addSocket(sAccept);
} else {
errno = WSAGetLastError();
errno = f_WSAGetLastError();
if ((errno == ENOENT) || (errno == WSAEWOULDBLOCK)) {
errno = EAGAIN;
return -1;
@@ -442,12 +448,16 @@ int redis_accept_impl(int rfd, struct sockaddr *addr, socklen_t *addrlen) {
return -1;
}
auto f_setsockopt = dllfunctor_stdcall<int, SOCKET, int, int, const char*, int>("ws2_32.dll", "setsockopt");
int redis_setsockopt_impl(int rfd, int level, int optname, const void *optval, socklen_t optlen) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
return f_setsockopt(socket, level, optname, (const char*) optval, optlen);
if (f_setsockopt(socket, level, optname, (const char*) optval, optlen) == 0) {
return 0;
} else {
errno = f_WSAGetLastError();
return -1;
}
}
} CATCH_AND_REPORT();
@@ -469,7 +479,7 @@ int redis_fcntl_impl(int rfd, int cmd, int flags = 0 ) {
{
u_long fionbio_flags = (flags & O_NONBLOCK);
if (f_ioctlsocket(socket, FIONBIO, &fionbio_flags) == SOCKET_ERROR) {
errno = WSAGetLastError();
errno = f_WSAGetLastError();
return -1;
} else {
RFDMap::getInstance().SetSocketFlags(socket, flags);
@@ -490,25 +500,6 @@ int redis_fcntl_impl(int rfd, int cmd, int flags = 0 ) {
}
static auto f_WSAFDIsSet = dllfunctor_stdcall<int, SOCKET, fd_set*>("ws2_32.dll", "__WSAFDIsSet");
#define FD_ISSET(fd, set) f_WSAFDIsSet((SOCKET)(fd), (fd_set *)(set))
int redis_FD_ISSET_impl(int rfd, fd_set* pSet) {
fd_set copy;
FD_ZERO(&copy);
for (u_int n = 0; n < pSet->fd_count; n++) {
SOCKET socket = RFDMap::getInstance().lookupSocket((RFD) (pSet->fd_array[n]));
if (socket == INVALID_SOCKET) {
errno = EBADF;
return -1;
}
FD_SET(socket, &copy);
}
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket == INVALID_SOCKET) {
errno = EBADF;
return -1;
}
return f_WSAFDIsSet(socket, &copy);
}
int redis_poll_impl(struct pollfd *fds, nfds_t nfds, int timeout) {
try {
@@ -525,7 +516,7 @@ int redis_poll_impl(struct pollfd *fds, nfds_t nfds, int timeout) {
pollCopy[n].revents = fds[n].revents;
}
if (IsWindowsVersionAtLeast(HIBYTE(_WIN32_WINNT_WIN6), LOBYTE(_WIN32_WINNT_WIN6), 0)) {
if (IsWindowsVersionAtLeast(6, 0, 0)) {
static auto f_WSAPoll = dllfunctor_stdcall<int, WSAPOLLFD*, ULONG, INT>("ws2_32.dll", "WSAPoll");
// WSAPoll implementation has a bug that cause the client to wait forever on a non-existant endpoint
@@ -587,9 +578,9 @@ int redis_poll_impl(struct pollfd *fds, nfds_t nfds, int timeout) {
for (i = 0; i < nfds; i++) {
fds[i].revents = 0;
if (FD_ISSET(pollCopy[i].fd, &readSet)) fds[i].revents |= POLLIN;
if (FD_ISSET(pollCopy[i].fd, &writeSet)) fds[i].revents |= POLLOUT;
if (FD_ISSET(pollCopy[i].fd, &excepSet)) fds[i].revents |= POLLERR;
if (f_WSAFDIsSet(pollCopy[i].fd, &readSet)) fds[i].revents |= POLLIN;
if (f_WSAFDIsSet(pollCopy[i].fd, &writeSet)) fds[i].revents |= POLLOUT;
if (f_WSAFDIsSet(pollCopy[i].fd, &excepSet)) fds[i].revents |= POLLERR;
}
delete pollCopy;
@@ -624,7 +615,7 @@ int redis_connect_impl(int rfd, const struct sockaddr *addr, size_t addrlen) {
if (socket != INVALID_SOCKET) {
EnableFastLoopback(socket);
int result = f_connect(socket, addr, (int) addrlen);
errno = WSAGetLastError();
errno = f_WSAGetLastError();
if ((errno == WSAEINVAL) || (errno == WSAEWOULDBLOCK) || (errno == WSA_IO_PENDING)) {
errno = EINPROGRESS;
}
@@ -831,16 +822,6 @@ int redis_shutdown_impl(int rfd, int how) {
return -1;
}
auto f_WSASetLastError = dllfunctor_stdcall<void, int>("ws2_32.dll", "WSASetLastError");
void redis_WSASetLastError_impl(int iError) {
f_WSASetLastError(iError);
}
auto f_WSAGetLastError = dllfunctor_stdcall<int>("ws2_32.dll", "WSAGetLastError");
int redis_WSAGetLastError_impl(void) {
return f_WSAGetLastError();
}
auto f_WSAGetOverlappedResult = dllfunctor_stdcall<BOOL, SOCKET, LPWSAOVERLAPPED, LPDWORD, BOOL, LPDWORD>("ws2_32.dll", "WSAGetOverlappedResult");
BOOL redis_WSAGetOverlappedResult_impl(int rfd, LPWSAOVERLAPPED lpOverlapped, LPDWORD lpcbTransfer, BOOL fWait, LPDWORD lpdwFlags) {
try {
@@ -885,26 +866,6 @@ int redis_WSASocket_impl(int af, int type, int protocol, LPWSAPROTOCOL_INFO lpPr
return -1;
}
int redis_WSAIoctl_impl(RFD rfd, DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
return f_WSAIoctl(socket,
dwIoControlCode,
lpvInBuffer,
cbInBuffer,
lpvOutBuffer,
cbOutBuffer,
lpcbBytesReturned,
lpOverlapped,
lpCompletionRoutine);
}
} CATCH_AND_REPORT();
errno = EBADF;
return SOCKET_ERROR;
}
auto f_WSASend = dllfunctor_stdcall<int, SOCKET, LPWSABUF, DWORD, LPDWORD, DWORD, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE>("ws2_32.dll", "WSASend");
int redis_WSASend_impl(int rfd, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) {
try {
@@ -1130,7 +1091,7 @@ int redis_getaddrinfo_impl(const char *node, const char *service, const struct a
}
const char* redis_inet_ntop_impl(int af, const void *src, char *dst, size_t size) {
if (IsWindowsVersionAtLeast(HIBYTE(_WIN32_WINNT_WIN6), LOBYTE(_WIN32_WINNT_WIN6), 0)) {
if (IsWindowsVersionAtLeast(6, 0, 0)) {
static auto f_inet_ntop = dllfunctor_stdcall<const char*, int, const void*, char*, size_t>("ws2_32.dll", "inet_ntop");
return f_inet_ntop(af, src, dst, size);
} else {
@@ -1149,7 +1110,7 @@ const char* redis_inet_ntop_impl(int af, const void *src, char *dst, size_t size
}
int redis_inet_pton_impl(int family, const char* src, void* dst) {
if (IsWindowsVersionAtLeast(HIBYTE(_WIN32_WINNT_WIN6), LOBYTE(_WIN32_WINNT_WIN6), 0)) {
if (IsWindowsVersionAtLeast(6, 0, 0)) {
static auto f_inet_pton = dllfunctor_stdcall<int, int, const char*, const void*>("ws2_32.dll", "inet_pton");
return f_inet_pton(family, src, dst);
} else {
@@ -1200,17 +1161,6 @@ BOOL ParseStorageAddress(const char *ip, int port, SOCKADDR_STORAGE* pStorageAdd
return TRUE;
}
int StorageSize(const SOCKADDR_STORAGE *ss) {
switch (ss->ss_family) {
case AF_INET:
return sizeof(SOCKADDR_IN);
case AF_INET6:
return sizeof(SOCKADDR_IN6);
default:
return SOCKET_ERROR;
}
}
auto f_WSAStartup = dllfunctor_stdcall<int, WORD, LPWSADATA>("ws2_32.dll", "WSAStartup");
int InitWinsock() {
WSADATA t_wsa;
@@ -1273,9 +1223,6 @@ private:
fdapi_fclose = redis_fclose_impl;
fdapi_fileno = redis_fileno_impl;
fdapi_setmode = redis_setmode_impl;
WSASetLastError = redis_WSASetLastError_impl;
WSAGetLastError = redis_WSAGetLastError_impl;
WSAIoctl = redis_WSAIoctl_impl;
WSASend = redis_WSASend_impl;
WSARecv = redis_WSARecv_impl;
WSAGetOverlappedResult = redis_WSAGetOverlappedResult_impl;
@@ -1291,7 +1238,6 @@ private:
freeaddrinfo = redis_freeaddrinfo_impl;
getaddrinfo = redis_getaddrinfo_impl;
inet_ntop = redis_inet_ntop_impl;
FD_ISSET = redis_FD_ISSET_impl;
accept = redis_accept_impl;
}
+6 -27
View File
@@ -36,27 +36,10 @@ typedef unsigned long nfds_t;
#define INCL_WINSOCK_API_PROTOTYPES 0 // Important! Do not include Winsock API definitions to avoid conflicts with API entry points defined below.
#include "win32_types.h"
#include <WinSock2.h>
#undef FD_ISSET
#include <fcntl.h>
#include <stdio.h>
// the following are required to be defined before WS2tcpip is included.
typedef void (*redis_WSASetLastError)(int iError);
typedef int (*redis_WSAGetLastError)(void);
typedef int (*redis_WSAIoctl)(int rfd,DWORD dwIoControlCode,LPVOID lpvInBuffer,DWORD cbInBuffer,LPVOID lpvOutBuffer,DWORD cbOutBuffer,LPDWORD lpcbBytesReturned,LPWSAOVERLAPPED lpOverlapped,LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
#ifdef __cplusplus
extern "C"
{
#endif
extern redis_WSASetLastError WSASetLastError;
extern redis_WSAGetLastError WSAGetLastError;
extern redis_WSAIoctl WSAIoctl;
#ifdef __cplusplus
}
#endif
// including a version of this file modified to eliminate prototype definitions not removed by INCL_WINSOCK_API_PROTOTYPES
#include "WS2tcpip.h"
@@ -189,7 +172,6 @@ typedef int (*redis_access)(const char *pathname, int mode);
typedef u_int64 (*redis_lseek64)(int fd, u_int64 offset, int whence);
typedef intptr_t (*redis_get_osfhandle)(int fd);
typedef int (*redis_open_osfhandle)(intptr_t osfhandle, int flags);
typedef int(*redis_FD_ISSET)(int fd, fd_set *);
// access() mode definitions
#define X_OK 0
@@ -204,10 +186,11 @@ extern "C"
// API replacements
extern redis_pipe pipe;
extern redis_socket socket;
extern redis_WSASend WSASend;
extern redis_WSARecv WSARecv;
extern redis_inet_addr inet_addr;
extern redis_inet_ntoa inet_ntoa;
extern redis_WSASend WSASend;
extern redis_WSARecv WSARecv;
extern redis_WSAGetOverlappedResult WSAGetOverlappedResult;
extern redis_WSADuplicateSocket WSADuplicateSocket;
extern redis_WSASocket WSASocket;
@@ -250,13 +233,10 @@ extern redis_freeaddrinfo freeaddrinfo;
extern redis_getaddrinfo getaddrinfo;
extern redis_inet_ntop inet_ntop;
extern redis_inet_pton inet_pton;
extern redis_FD_ISSET FD_ISSET;
// other FD based APIs
void FDAPI_SaveSocketAddrStorage(int rfd, SOCKADDR_STORAGE* socketAddrStorage);
BOOL FDAPI_SetFDInformation(int FD, DWORD mask, DWORD flags);
int FDAPI_ioctlsocket(int rfd, long cmd, u_long *argp);
HANDLE FDAPI_CreateIoCompletionPortOnFD(int FD, HANDLE ExistingCompletionPort, ULONG_PTR CompletionKey, DWORD NumberOfConcurrentThreads);
BOOL FDAPI_SocketAttachIOCP(int rfd, HANDLE iocph);
BOOL FDAPI_AcceptEx(int listenFD,int acceptFD,PVOID lpOutputBuffer,DWORD dwReceiveDataLength,DWORD dwLocalAddressLength,DWORD dwRemoteAddressLength,LPDWORD lpdwBytesReceived,LPOVERLAPPED lpOverlapped);
BOOL FDAPI_ConnectEx(int fd,const struct sockaddr *name,int namelen,PVOID lpSendBuffer,DWORD dwSendDataLength,LPDWORD lpdwBytesSent,LPOVERLAPPED lpOverlapped);
void FDAPI_GetAcceptExSockaddrs(int fd, PVOID lpOutputBuffer,DWORD dwReceiveDataLength,DWORD dwLocalAddressLength,DWORD dwRemoteAddressLength,LPSOCKADDR *LocalSockaddr,LPINT LocalSockaddrLength,LPSOCKADDR *RemoteSockaddr,LPINT RemoteSockaddrLength);
@@ -264,10 +244,11 @@ int FDAPI_UpdateAcceptContext( int fd );
int FDAPI_PipeSetNonBlock(int rfd, int non_blocking);
void** FDAPI_GetSocketStatePtr(int rfd);
void FDAPI_ClearSocketState(int fd);
int FDAPI_WSAIoctl(int rfd, DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
int FDAPI_WSAGetLastError(void);
// other networking functions
BOOL ParseStorageAddress(const char *ip, int port, SOCKADDR_STORAGE* pSotrageAddr);
int StorageSize(const SOCKADDR_STORAGE *ss);
// macroize CRT definitions to point to our own
#ifndef FDAPI_NOCRTREDEFS
@@ -283,7 +264,5 @@ int StorageSize(const SOCKADDR_STORAGE *ss);
#endif
#ifdef __cplusplus
bool IsWindowsVersionAtLeast(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor);
}
#endif
+29 -49
View File
@@ -78,44 +78,21 @@ BOOL aeWinDelSocketState(aeSockState* pSocketState) {
/* For each asynch socket, need to associate completion port */
int aeWinSocketAttach(int fd, aeSockState *socketState) {
if (iocph == NULL) {
return -1;
}
if (socketState == NULL) {
socketState = aeWinGetSocketState(fd);
if (socketState == NULL) {
errno = WSAEINVAL;
return -1;
}
if (iocph != NULL && socketState != NULL) {
if (FDAPI_SocketAttachIOCP(fd, iocph)) {
socketState->masks = SOCKET_ATTACHED;
socketState->wreqs = 0;
return 0;
}
} else {
errno = WSAEINVAL;
}
// Set the socket to nonblocking mode
DWORD yes = 1;
if (FDAPI_ioctlsocket(fd, FIONBIO, &yes) == SOCKET_ERROR) {
errno = WSAGetLastError();
return -1;
}
// Make the socket non-inheritable
if (!FDAPI_SetFDInformation(fd, HANDLE_FLAG_INHERIT, 0)) {
errno = WSAGetLastError();
return -1;
}
// Associate it with the I/O completion port.
// Use FD as completion key.
if (FDAPI_CreateIoCompletionPortOnFD(fd,
iocph,
(ULONG_PTR) fd,
0) == NULL) {
errno = WSAGetLastError();
return -1;
}
socketState->masks = SOCKET_ATTACHED;
socketState->wreqs = 0;
return 0;
return -1;
}
int aeWinQueueAccept(int listenfd) {
@@ -157,7 +134,7 @@ int aeWinQueueAccept(int listenfd) {
if (SUCCEEDED_WITH_IOCP(result)){
sockstate->masks |= ACCEPT_PENDING;
} else {
errno = WSAGetLastError();
errno = FDAPI_WSAGetLastError();
sockstate->masks &= ~ACCEPT_PENDING;
close(acceptfd);
accsockstate->masks = 0;
@@ -185,11 +162,11 @@ int aeWinListen(int rfd, int backlog) {
if (listen(rfd, backlog) == 0) {
if (aeWinQueueAccept(rfd) == -1) {
errno = WSAGetLastError();
errno = FDAPI_WSAGetLastError();
return SOCKET_ERROR;
}
} else {
errno = WSAGetLastError();
errno = FDAPI_WSAGetLastError();
}
return 0;
@@ -223,7 +200,7 @@ int aeWinAccept(int fd, struct sockaddr *sa, socklen_t *len) {
result = FDAPI_UpdateAcceptContext(acceptfd);
if (result == SOCKET_ERROR) {
errno = WSAGetLastError();
errno = FDAPI_WSAGetLastError();
FreeMemoryNoCOW(areq->buf);
FreeMemoryNoCOW(areq);
return SOCKET_ERROR;
@@ -296,7 +273,7 @@ int aeWinReceiveDone(int fd) {
if (SUCCEEDED_WITH_IOCP(result == 0)){
sockstate->masks |= READ_QUEUED;
} else {
errno = WSAGetLastError();
errno = FDAPI_WSAGetLastError();
sockstate->masks &= ~READ_QUEUED;
return -1;
}
@@ -326,7 +303,7 @@ int aeWinSocketSend(int fd, char *buf, int len,
proc == NULL) {
result = (int) write(fd, buf, len);
if (result == SOCKET_ERROR) {
errno = WSAGetLastError();
errno = FDAPI_WSAGetLastError();
}
return result;
}
@@ -355,7 +332,7 @@ int aeWinSocketSend(int fd, char *buf, int len,
sockstate->wreqs++;
listAddNodeTail(&sockstate->wreqlist, areq);
} else {
errno = WSAGetLastError();
errno = FDAPI_WSAGetLastError();
FreeMemoryNoCOW(areq);
}
return SOCKET_ERROR;
@@ -407,7 +384,7 @@ int aeWinSocketConnect(int fd, const SOCKADDR_STORAGE *ss) {
}
if (result != TRUE) {
result = WSAGetLastError();
result = FDAPI_WSAGetLastError();
if (result == ERROR_IO_PENDING) {
errno = WSA_IO_PENDING;
sockstate->masks |= CONNECT_PENDING;
@@ -419,7 +396,7 @@ int aeWinSocketConnect(int fd, const SOCKADDR_STORAGE *ss) {
return 0;
}
int aeWinSocketConnectBind(int fd, const SOCKADDR_STORAGE *ss, const char* source_addr) {
int aeWinSocketConnectBind(int fd, const SOCKADDR_STORAGE *socketAddrStorage, const char* source_addr) {
const GUID wsaid_connectex = WSAID_CONNECTEX;
DWORD result;
aeSockState *sockstate;
@@ -436,12 +413,14 @@ int aeWinSocketConnectBind(int fd, const SOCKADDR_STORAGE *ss, const char* sourc
memset(&sockstate->ov_read, 0, sizeof(sockstate->ov_read));
// Need to bind sock before connectex
switch (ss->ss_family) {
int storageSize = 0;
switch (socketAddrStorage->ss_family) {
case AF_INET:
{
storageSize = sizeof(SOCKADDR_IN);
SOCKADDR_IN addr;
memset(&addr, 0, sizeof(SOCKADDR_IN));
addr.sin_family = ss->ss_family;
memset(&addr, 0, storageSize);
addr.sin_family = socketAddrStorage->ss_family;
addr.sin_addr.S_un.S_addr = INADDR_ANY;
addr.sin_port = 0;
result = bind(fd, (SOCKADDR*) &addr, sizeof(addr));
@@ -449,9 +428,10 @@ int aeWinSocketConnectBind(int fd, const SOCKADDR_STORAGE *ss, const char* sourc
}
case AF_INET6:
{
storageSize = sizeof(SOCKADDR_IN6);
SOCKADDR_IN6 addr;
memset(&addr, 0, sizeof(SOCKADDR_IN6));
addr.sin6_family = ss->ss_family;
memset(&addr, 0, storageSize);
addr.sin6_family = socketAddrStorage->ss_family;
memset(&(addr.sin6_addr.u.Byte), 0, 16);
addr.sin6_port = 0;
result = bind(fd, (SOCKADDR*) &addr, sizeof(addr));
@@ -463,9 +443,9 @@ int aeWinSocketConnectBind(int fd, const SOCKADDR_STORAGE *ss, const char* sourc
}
}
result = FDAPI_ConnectEx(fd, (const LPSOCKADDR) ss, StorageSize(ss), NULL, 0, NULL, &sockstate->ov_read);
result = FDAPI_ConnectEx(fd, (const LPSOCKADDR) socketAddrStorage, storageSize, NULL, 0, NULL, &sockstate->ov_read);
if (result != TRUE) {
result = WSAGetLastError();
result = FDAPI_WSAGetLastError();
if (result == ERROR_IO_PENDING) {
errno = WSA_IO_PENDING;
sockstate->masks |= CONNECT_PENDING;
+2 -4
View File
@@ -123,9 +123,9 @@ int anetKeepAlive(char *err, int fd, int interval)
val = interval/10;
if (val == 0) val = 1;
alive.keepaliveinterval = val*1000;
if(WSAIoctl(fd, SIO_KEEPALIVE_VALS, &alive, sizeof(alive),
if (FDAPI_WSAIoctl(fd, SIO_KEEPALIVE_VALS, &alive, sizeof(alive),
NULL, 0, &dwBytesRet, NULL, NULL) == SOCKET_ERROR) {
anetSetError(err, "WSAIotcl(SIO_KEEPALIVE_VALS) failed with error code %d\n", WSAGetLastError());
anetSetError(err, "WSAIotcl(SIO_KEEPALIVE_VALS) failed with error code %d\n", strerror(errno));
return ANET_ERR;
}
#else
@@ -264,7 +264,6 @@ static int anetSetReuseAddr(char *err, int fd) {
/* Make sure connection-intensive things like the redis benckmark
* will be able to close/open sockets a zillion of times */
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) {
WIN32_ONLY(errno = WSAGetLastError();)
anetSetError(err, "setsockopt SO_REUSEADDR: %s", strerror(errno));
return ANET_ERR;
}
@@ -274,7 +273,6 @@ static int anetSetReuseAddr(char *err, int fd) {
static int anetCreateSocket(char *err, int domain) {
int s;
if ((s = socket(domain, SOCK_STREAM, IF_WIN32(IPPROTO_TCP,0))) == -1) {
WIN32_ONLY(errno = WSAGetLastError();)
anetSetError(err, "create socket error: %s", strerror(errno));
return ANET_ERR;
}
-1
View File
@@ -221,7 +221,6 @@ static void readHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
#ifdef _WIN32
nread = read(c->context->fd,buf,sizeof(buf));
if (nread == -1) {
errno = WSAGetLastError();
if ((errno == ENOENT) || (errno == WSAEWOULDBLOCK)) {
errno = EAGAIN;
aeWinReceiveDone((int)c->context->fd);
-1
View File
@@ -1053,7 +1053,6 @@ void readSyncBulkPayload(aeEventLoop *el, int fd, void *privdata, int mask) {
if (nread <= 0) {
#ifdef _WIN32
if (server.repl_transfer_size) {
errno = WSAGetLastError();
redisLog(REDIS_WARNING,"I/O error %d (left %Iu) trying to sync with MASTER: %s",
errno, server.repl_transfer_size,
(nread == -1) ? wsa_strerror(errno) : "connection lost");