[Fix] Ported fixes from 2.8.

[Fix] Windows portability: explicit type casting.
[Cleanup] Code refactoring. Comments. Changed functions prefix to match
the functions type.
This commit is contained in:
Enrico Giordani
2015-09-02 14:56:36 +02:00
parent 328d747f4c
commit 4e54b241c6
40 changed files with 1043 additions and 1004 deletions
+76
View File
@@ -0,0 +1,76 @@
/*
* Copyright (c), Microsoft Open Technologies, Inc.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Win32_APIs.h"
#include <errno.h>
/* Replace MS C rtl rand which is 15bit with 32 bit */
int replace_random() {
unsigned int x = 0;
if (RtlGenRandom == NULL) {
// load proc if not loaded
HMODULE lib = LoadLibraryA("advapi32.dll");
RtlGenRandom = (RtlGenRandomFunc) GetProcAddress(lib, "SystemFunction036");
if (RtlGenRandom == NULL) return 1;
}
RtlGenRandom(&x, sizeof(unsigned int));
return (int) (x >> 1);
}
/* Rename which works on Windows when file exists */
int replace_rename(const char *src, const char *dst) {
/* anti-virus may lock file - error code 5. Retry until it works or get a different error */
int retries = 50;
while (1) {
if (MoveFileExA(src, dst, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH)) {
return 0;
} else {
errno = GetLastError();
if (errno != 5) break;
retries--;
if (retries == 0) {
retries = 50;
Sleep(10);
}
}
}
/* On error we will return generic error code without GetLastError() */
return -1;
}
int truncate(const char *path, PORT_LONGLONG length) {
LARGE_INTEGER newSize;
HANDLE toTruncate;
toTruncate = CreateFileA(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (toTruncate != INVALID_HANDLE_VALUE) {
newSize.QuadPart = length;
if (FALSE == (SetFilePointerEx(toTruncate, newSize, NULL, FILE_BEGIN) && SetEndOfFile(toTruncate))) {
errno = ENOENT;
return -1;
} else {
return 0;
}
} else {
errno = ENOENT;
return -1;
}
}
+69
View File
@@ -0,0 +1,69 @@
/*
* Copyright (c), Microsoft Open Technologies, Inc.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _WIN32_APIS_H
#define _WIN32_APIS_H
#include "Win32_types.h"
#include <Windows.h>
// API replacement for non-fd stdio functions
#define fseeko _fseeki64
#define ftello _ftelli64
#define snprintf _snprintf
#define strcasecmp _stricmp
#define strtoll _strtoi64
#define sleep(x) Sleep((x)*1000)
/* Redis calls usleep(1) to give thread some time.
* Sleep(0) should do the same on Windows.
* In other cases, usleep is called with millisec resolution
* which can be directly translated to WinAPI Sleep() */
#undef usleep
#define usleep(x) (x == 1) ? Sleep(0) : Sleep((int)((x)/1000))
/* following defined to choose little endian byte order */
#define __i386__ 1
#if !defined(va_copy)
#define va_copy(d,s) d = (s)
#endif
#ifndef __RTL_GENRANDOM
#define __RTL_GENRANDOM 1
typedef BOOLEAN(_stdcall* RtlGenRandomFunc)(void * RandomBuffer, ULONG RandomBufferLength);
#endif
RtlGenRandomFunc RtlGenRandom;
#define random() replace_random()
#define rand() replace_random()
#define srandom srand
int replace_random();
#define rename(a,b) replace_rename(a,b)
int replace_rename(const char *src, const char *dest);
int truncate(const char *path, PORT_LONGLONG length);
#define lseek lseek64
#endif
+3 -3
View File
@@ -27,10 +27,10 @@ namespace Globals
}
/* This function is used to force the VEH on the entire size of the buffer length,
in the event that the buffer crosses the memory page boundaries */
* in the event that the buffer crosses the memory page boundaries */
void EnsureMemoryIsMapped(const void *buffer, size_t size) {
/* Use 'volatile' to make sure the compiler doesn't remove "c = *((char*) (p + offset));" */
volatile char c;
// Use 'volatile' to make sure the compiler doesn't remove "c = *((char*) (p + offset));"
volatile char c;
char* p = (char*) buffer;
char* pStart = p - ((size_t) p % Globals::pageSize);
char* pEnd = p + size;
+300 -348
View File
@@ -31,7 +31,6 @@
#include "Win32_variadicFunctor.h"
#include "Win32_ANSI.h"
#include "win32_util.h"
#include <string>
#include "Win32_RedisLog.h"
#include "Win32_Common.h"
#include "Win32_Assert.h"
@@ -41,56 +40,86 @@ 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_WSASend WSASend = NULL;
redis_WSARecv WSARecv = NULL;
redis_WSAGetOverlappedResult WSAGetOverlappedResult = NULL;
redis_WSADuplicateSocket WSADuplicateSocket = NULL;
redis_WSASocket WSASocket = NULL;
// other API forwards
redis_fwrite fdapi_fwrite = NULL;
redis_fclose fdapi_fclose = NULL;
redis_fileno fdapi_fileno = NULL;
redis_setmode fdapi_setmode = NULL;
redis_select select = NULL;
redis_ntohl ntohl = NULL;
redis_isatty isatty = NULL;
redis_access access = NULL;
redis_lseek64 lseek64 = NULL;
redis_get_osfhandle fdapi_get_osfhandle = NULL;
redis_open_osfhandle fdapi_open_osfhandle = NULL;
// Unix compatible FD based routines
redis_pipe pipe = NULL;
redis_socket socket = NULL;
redis_close fdapi_close = NULL;
redis_open open = NULL;
redis_inet_addr inet_addr = NULL;
redis_inet_ntoa inet_ntoa = NULL;
redis_accept accept = NULL;
redis_setsockopt setsockopt = NULL;
redis_fcntl fcntl = NULL;
redis_poll poll = NULL;
redis_getsockopt getsockopt = NULL;
redis_connect connect = NULL;
redis_read read = NULL;
redis_write write = NULL;
redis_fsync fsync = NULL;
_redis_fstat fdapi_fstat64 = NULL;
redis_listen listen = NULL;
redis_ftruncate ftruncate = NULL;
redis_bind bind = NULL;
redis_gethostbyname gethostbyname = NULL;
redis_htons htons = NULL;
redis_htonl htonl = NULL;
redis_getpeername getpeername = NULL;
redis_getsockname getsockname = NULL;
redis_ntohs ntohs = NULL;
redis_freeaddrinfo freeaddrinfo = NULL;
redis_getaddrinfo getaddrinfo = NULL;
redis_inet_ntop inet_ntop = NULL;
redis_inet_pton inet_pton = NULL;
fdapi_accept accept = NULL;
fdapi_access access = NULL;
fdapi_bind bind = NULL;
fdapi_connect connect = NULL;
fdapi_fcntl fcntl = NULL;
fdapi_fstat fdapi_fstat64 = NULL;
fdapi_fsync fsync = NULL;
fdapi_ftruncate ftruncate = NULL;
fdapi_freeaddrinfo freeaddrinfo = NULL;
fdapi_getaddrinfo getaddrinfo = NULL;
fdapi_getpeername getpeername = NULL;
fdapi_getsockname getsockname = NULL;
fdapi_getsockopt getsockopt = NULL;
fdapi_htonl htonl = NULL;
fdapi_htons htons = NULL;
fdapi_isatty isatty = NULL;
fdapi_inet_ntop inet_ntop = NULL;
fdapi_inet_pton inet_pton = NULL;
fdapi_listen listen = NULL;
fdapi_lseek64 lseek64 = NULL;
fdapi_ntohl ntohl = NULL;
fdapi_ntohs ntohs = NULL;
fdapi_open open = NULL;
fdapi_pipe pipe = NULL;
fdapi_poll poll = NULL;
fdapi_read read = NULL;
fdapi_select select = NULL;
fdapi_setsockopt setsockopt = NULL;
fdapi_socket socket = NULL;
fdapi_write write = NULL;
}
auto f_WSACleanup = dllfunctor_stdcall<int>("ws2_32.dll", "WSACleanup");
auto f_WSAFDIsSet = dllfunctor_stdcall<int, SOCKET, fd_set*>("ws2_32.dll", "__WSAFDIsSet");
auto f_WSAGetLastError = dllfunctor_stdcall<int>("ws2_32.dll", "WSAGetLastError");
auto f_WSAGetOverlappedResult = dllfunctor_stdcall<BOOL, SOCKET, LPWSAOVERLAPPED, LPDWORD, BOOL, LPDWORD>("ws2_32.dll", "WSAGetOverlappedResult");
auto f_WSADuplicateSocket = dllfunctor_stdcall<int, SOCKET, DWORD, LPWSAPROTOCOL_INFO>("ws2_32.dll", "WSADuplicateSocketW");
auto f_WSAIoctl = dllfunctor_stdcall<int, SOCKET, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPVOID, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE>("ws2_32.dll", "WSAIoctl");
auto f_WSARecv = dllfunctor_stdcall<int, SOCKET, LPWSABUF, DWORD, LPDWORD, LPDWORD, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE>("ws2_32.dll", "WSARecv");
auto f_WSASocket = dllfunctor_stdcall<SOCKET, int, int, int, LPWSAPROTOCOL_INFO, GROUP, DWORD>("ws2_32.dll", "WSASocketW");
auto f_WSASend = dllfunctor_stdcall<int, SOCKET, LPWSABUF, DWORD, LPDWORD, DWORD, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE>("ws2_32.dll", "WSASend");
auto f_WSAStartup = dllfunctor_stdcall<int, WORD, LPWSADATA>("ws2_32.dll", "WSAStartup");
auto f_ioctlsocket = dllfunctor_stdcall<int, SOCKET, long, u_long*>("ws2_32.dll", "ioctlsocket");
auto f_accept = dllfunctor_stdcall<SOCKET, SOCKET, struct sockaddr*, int*>("ws2_32.dll", "accept");
auto f_bind = dllfunctor_stdcall<int, SOCKET, const struct sockaddr*, int>("ws2_32.dll", "bind");
auto f_closesocket = dllfunctor_stdcall<int, SOCKET>("ws2_32.dll", "closesocket");
auto f_connect = dllfunctor_stdcall<int, SOCKET, const struct sockaddr*, int>("ws2_32.dll", "connect");
auto f_freeaddrinfo = dllfunctor_stdcall<void, addrinfo*>("ws2_32.dll", "freeaddrinfo");
auto f_getaddrinfo = dllfunctor_stdcall<int, PCSTR, PCSTR, const ADDRINFOA*, ADDRINFOA**>("ws2_32.dll", "getaddrinfo");
auto f_gethostbyname = dllfunctor_stdcall<struct hostent*, const char*>("ws2_32.dll", "gethostbyname");
auto f_getpeername = dllfunctor_stdcall<int, SOCKET, struct sockaddr*, int*>("ws2_32.dll", "getpeername");
auto f_getsockname = dllfunctor_stdcall<int, SOCKET, struct sockaddr*, int*>("ws2_32.dll", "getsockname");
auto f_getsockopt = dllfunctor_stdcall<int, SOCKET, int, int, char*, int*>("ws2_32.dll", "getsockopt");
auto f_htonl = dllfunctor_stdcall<u_long, u_long>("ws2_32.dll", "htonl");
auto f_htons = dllfunctor_stdcall<u_short, u_short>("ws2_32.dll", "htons");
auto f_listen = dllfunctor_stdcall<int, SOCKET, int>("ws2_32.dll", "listen");
auto f_ntohs = dllfunctor_stdcall<u_short, u_short>("ws2_32.dll", "ntohs");
auto f_ntohl = dllfunctor_stdcall<u_long, u_long>("ws2_32.dll", "ntohl");
auto f_recv = dllfunctor_stdcall<int, SOCKET, char*, int, int>("ws2_32.dll", "recv");
auto f_select = dllfunctor_stdcall<int, int, fd_set*, fd_set*, fd_set*, const struct timeval*>("ws2_32.dll", "select");
auto f_send = dllfunctor_stdcall<int, SOCKET, const char*, int, int>("ws2_32.dll", "send");
auto f_setsockopt = dllfunctor_stdcall<int, SOCKET, int, int, const char*, int>("ws2_32.dll", "setsockopt");
auto f_socket = dllfunctor_stdcall<SOCKET, int, int, int>("ws2_32.dll", "socket");
#ifndef SIO_LOOPBACK_FAST_PATH
const DWORD SIO_LOOPBACK_FAST_PATH = 0x98000010; // from Win8 SDK
#endif
void EnableFastLoopback(SOCKET socket) {
// 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(f_WSAGetLastError(), system_category(), "WSAIoctl failed");
}
}
}
static fnWSIOCP_CloseSocketStateRFD* wsiocp_CloseSocketState;
@@ -98,11 +127,112 @@ void FDAPI_SetCloseSocketState(fnWSIOCP_CloseSocketStateRFD* func) {
wsiocp_CloseSocketState = func;
}
auto f_WSAGetLastError = dllfunctor_stdcall<int>("ws2_32.dll", "WSAGetLastError");
int FDAPI_WSAGetLastError(void) {
return f_WSAGetLastError();
}
BOOL FDAPI_WSAGetOverlappedResult(int rfd, LPWSAOVERLAPPED lpOverlapped, LPDWORD lpcbTransfer, BOOL fWait, LPDWORD lpdwFlags) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
return f_WSAGetOverlappedResult(socket, lpOverlapped, lpcbTransfer, fWait, lpdwFlags);
}
} CATCH_AND_REPORT();
errno = EBADF;
return SOCKET_ERROR;
}
int FDAPI_WSADuplicateSocket(int rfd, DWORD dwProcessId, LPWSAPROTOCOL_INFO lpProtocolInfo) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
return f_WSADuplicateSocket(socket, dwProcessId, lpProtocolInfo);
}
} CATCH_AND_REPORT();
errno = EBADF;
return SOCKET_ERROR;
}
int FDAPI_WSASocket(int af, int type, int protocol, LPWSAPROTOCOL_INFO lpProtocolInfo, GROUP g, DWORD dwFlags) {
try {
SOCKET socket = f_WSASocket(af,
type,
protocol,
lpProtocolInfo,
g,
dwFlags);
if (socket != INVALID_SOCKET) {
return RFDMap::getInstance().addSocket(socket);
}
} CATCH_AND_REPORT();
return -1;
}
int FDAPI_WSASend(int rfd, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
return f_WSASend(socket,
lpBuffers,
dwBufferCount,
lpNumberOfBytesSent,
dwFlags,
lpOverlapped,
lpCompletionRoutine);
}
} CATCH_AND_REPORT();
errno = EBADF;
return SOCKET_ERROR;
}
int FDAPI_WSARecv(int rfd, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
return f_WSARecv(socket,
lpBuffers,
dwBufferCount,
lpNumberOfBytesRecvd,
lpFlags,
lpOverlapped,
lpCompletionRoutine);
}
} CATCH_AND_REPORT();
errno = EBADF;
return SOCKET_ERROR;
}
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) {
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();
errno = EBADF;
return SOCKET_ERROR;
}
void FDAPI_SaveSocketAddrStorage(int rfd, SOCKADDR_STORAGE* socketAddrStorage) {
SocketInfo* socket_info = RFDMap::getInstance().lookupSocketInfo(rfd);
if (socket_info != NULL) {
@@ -110,8 +240,6 @@ void FDAPI_SaveSocketAddrStorage(int rfd, SOCKADDR_STORAGE* socketAddrStorage) {
}
}
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) {
@@ -137,32 +265,6 @@ BOOL FDAPI_SocketAttachIOCP(int rfd, HANDLE iocph) {
return FALSE;
}
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) {
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();
errno = EBADF;
return SOCKET_ERROR;
}
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);
@@ -190,22 +292,6 @@ BOOL FDAPI_AcceptEx(int listenFD, int acceptFD, PVOID lpOutputBuffer, DWORD dwRe
return FALSE;
}
#ifndef SIO_LOOPBACK_FAST_PATH
const DWORD SIO_LOOPBACK_FAST_PATH = 0x98000010; // from Win8 SDK
#endif
void EnableFastLoopback(SOCKET socket) {
// 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(f_WSAGetLastError(), system_category(), "WSAIoctl failed");
}
}
}
BOOL FDAPI_ConnectEx(int rfd, const struct sockaddr *name, int namelen, PVOID lpSendBuffer, DWORD dwSendDataLength, LPDWORD lpdwBytesSent, LPOVERLAPPED lpOverlapped) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
@@ -272,8 +358,6 @@ 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);
@@ -319,9 +403,9 @@ void FDAPI_ClearSocketInfo(int rfd) {
int FDAPI_PipeSetNonBlock(int rfd, int non_blocking) {
try {
int posixFD = RFDMap::getInstance().lookupPosixFD(rfd);
if (posixFD != -1) {
HANDLE h = (HANDLE) crt_get_osfhandle(posixFD);
int crt_fd = RFDMap::getInstance().lookupCrtFD(rfd);
if (crt_fd != INVALID_FD) {
HANDLE h = (HANDLE) crt_get_osfhandle(crt_fd);
if (h == INVALID_HANDLE_VALUE) {
errno = EBADF;
return -1;
@@ -367,22 +451,21 @@ int FDAPI_PipeSetNonBlock(int rfd, int non_blocking) {
return -1;
}
int redis_pipe_impl(int *pfds) {
int FDAPI_pipe(int *pfds) {
int result = -1;
try {
// Not passing _O_NOINHERIT, the underlying handles are inheritable by default
result = crt_pipe(pfds, 8192, _O_BINARY);
if (result == 0) {
pfds[0] = RFDMap::getInstance().addPosixFD(pfds[0]);
pfds[1] = RFDMap::getInstance().addPosixFD(pfds[1]);
pfds[0] = RFDMap::getInstance().addCrtFD(pfds[0]);
pfds[1] = RFDMap::getInstance().addCrtFD(pfds[1]);
}
} CATCH_AND_REPORT();
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) {
int FDAPI_socket(int af, int type, int protocol) {
try {
SOCKET socket = f_socket(af, type, protocol);
if (socket != INVALID_SOCKET) {
@@ -398,8 +481,7 @@ int redis_socket_impl(int af, int type, int protocol) {
}
// 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) {
int FDAPI_close(int rfd) {
try {
SocketInfo* socketInfo = RFDMap::getInstance().lookupSocketInfo(rfd);
if (socketInfo != NULL) {
@@ -423,10 +505,10 @@ int redis_close_impl(RFD rfd) {
return f_closesocket(socket);
}
} else {
int posixFD = RFDMap::getInstance().lookupPosixFD(rfd);
if (posixFD != -1) {
RFDMap::getInstance().removePosixFD(posixFD);
return crt_close(posixFD);
int crt_fd = RFDMap::getInstance().lookupCrtFD(rfd);
if (crt_fd != INVALID_FD) {
RFDMap::getInstance().removeCrtFD(crt_fd);
return crt_close(crt_fd);
}
}
} CATCH_AND_REPORT();
@@ -435,11 +517,11 @@ int redis_close_impl(RFD rfd) {
return -1;
}
int __cdecl redis_open_impl(const char * _Filename, int _OpenFlag, int flags = 0) {
int FDAPI_open(const char * _Filename, int _OpenFlag, int flags = 0) {
try {
int posixFD = crt_open(_Filename, _OpenFlag, flags);
if (posixFD != -1) {
return RFDMap::getInstance().addPosixFD(posixFD);
int crt_fd = crt_open(_Filename, _OpenFlag, flags);
if (crt_fd != INVALID_FD) {
return RFDMap::getInstance().addCrtFD(crt_fd);
}
} CATCH_AND_REPORT();
@@ -447,8 +529,7 @@ int __cdecl redis_open_impl(const char * _Filename, int _OpenFlag, int flags = 0
return -1;
}
auto f_accept = dllfunctor_stdcall<SOCKET, SOCKET, struct sockaddr*, int*>("ws2_32.dll", "accept");
int redis_accept_impl(int rfd, struct sockaddr *addr, socklen_t *addrlen) {
int FDAPI_accept(int rfd, struct sockaddr *addr, socklen_t *addrlen) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
@@ -469,7 +550,7 @@ int redis_accept_impl(int rfd, struct sockaddr *addr, socklen_t *addrlen) {
return -1;
}
int redis_setsockopt_impl(int rfd, int level, int optname, const void *optval, socklen_t optlen) {
int FDAPI_setsockopt(int rfd, int level, int optname, const void *optval, socklen_t optlen) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
@@ -486,7 +567,7 @@ int redis_setsockopt_impl(int rfd, int level, int optname, const void *optval, s
return -1;
}
int redis_fcntl_impl(int rfd, int cmd, int flags = 0 ) {
int FDAPI_fcntl(int rfd, int cmd, int flags = 0 ) {
try {
SocketInfo* socket_info = RFDMap::getInstance().lookupSocketInfo(rfd);
if (socket_info != NULL && socket_info->socket != INVALID_SOCKET) {
@@ -524,9 +605,7 @@ int redis_fcntl_impl(int rfd, int cmd, int flags = 0 ) {
return -1;
}
static auto f_WSAFDIsSet = dllfunctor_stdcall<int, SOCKET, fd_set*>("ws2_32.dll", "__WSAFDIsSet");
int redis_poll_impl(struct pollfd *fds, nfds_t nfds, int timeout) {
int FDAPI_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
try {
struct pollfd* pollCopy = new struct pollfd[nfds];
if (pollCopy == NULL) {
@@ -544,7 +623,8 @@ int redis_poll_impl(struct pollfd *fds, nfds_t nfds, int timeout) {
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
// WSAPoll implementation has a bug that cause the client
// to wait forever on a non-existant endpoint
// See https://github.com/MSOpenTech/redis/issues/214
int ret = f_WSAPoll(pollCopy, nfds, timeout);
@@ -619,8 +699,7 @@ int redis_poll_impl(struct pollfd *fds, nfds_t nfds, int timeout) {
return -1;
}
auto f_getsockopt = dllfunctor_stdcall<int, SOCKET, int, int, char*, int*>("ws2_32.dll", "getsockopt");
int redis_getsockopt_impl(int rfd, int level, int optname, void *optval, socklen_t *optlen) {
int FDAPI_getsockopt(int rfd, int level, int optname, void *optval, socklen_t *optlen) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
@@ -632,9 +711,7 @@ int redis_getsockopt_impl(int rfd, int level, int optname, void *optval, socklen
return -1;
}
auto f_connect = dllfunctor_stdcall<int, SOCKET, const struct sockaddr*, int>("ws2_32.dll", "connect");
int redis_connect_impl(int rfd, const struct sockaddr *addr, size_t addrlen) {
int FDAPI_connect(int rfd, const struct sockaddr *addr, size_t addrlen) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
@@ -652,8 +729,7 @@ int redis_connect_impl(int rfd, const struct sockaddr *addr, size_t addrlen) {
return -1;
}
auto f_recv = dllfunctor_stdcall<int, SOCKET, char*, int, int>("ws2_32.dll", "recv");
ssize_t redis_read_impl(int rfd, void *buf, size_t count) {
ssize_t FDAPI_read(int rfd, void *buf, size_t count) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
@@ -666,9 +742,9 @@ ssize_t redis_read_impl(int rfd, void *buf, size_t count) {
}
return retval;
} else {
int posixFD = RFDMap::getInstance().lookupPosixFD(rfd);
if (posixFD != -1) {
int retval = crt_read(posixFD, buf, (unsigned int) count);
int crt_fd = RFDMap::getInstance().lookupCrtFD(rfd);
if (crt_fd != INVALID_FD) {
int retval = crt_read(crt_fd, buf, (unsigned int) count);
if (retval == -1) {
errno = GetLastError();
}
@@ -684,8 +760,7 @@ ssize_t redis_read_impl(int rfd, void *buf, size_t count) {
return -1;
}
auto f_send = dllfunctor_stdcall<int, SOCKET, const char*, int, int>("ws2_32.dll", "send");
ssize_t redis_write_impl(int rfd, const void *buf, size_t count) {
ssize_t FDAPI_write(int rfd, const void *buf, size_t count) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
@@ -695,9 +770,9 @@ ssize_t redis_write_impl(int rfd, const void *buf, size_t count) {
}
return ret;
} else {
int posixFD = RFDMap::getInstance().lookupPosixFD(rfd);
if (posixFD != -1) {
if (posixFD == _fileno(stdout)) {
int crt_fd = RFDMap::getInstance().lookupCrtFD(rfd);
if (crt_fd != INVALID_FD) {
if (crt_fd == _fileno(stdout)) {
DWORD bytesWritten = 0;
if (FALSE != ParseAndPrintANSIString(GetStdHandle(STD_OUTPUT_HANDLE), buf, (DWORD) count, &bytesWritten)) {
return (int) bytesWritten;
@@ -705,7 +780,7 @@ ssize_t redis_write_impl(int rfd, const void *buf, size_t count) {
errno = GetLastError();
return 0;
}
} else if (posixFD == _fileno(stderr)) {
} else if (crt_fd == _fileno(stderr)) {
DWORD bytesWritten = 0;
if (FALSE != ParseAndPrintANSIString(GetStdHandle(STD_ERROR_HANDLE), buf, (DWORD) count, &bytesWritten)) {
return (int) bytesWritten;
@@ -714,7 +789,7 @@ ssize_t redis_write_impl(int rfd, const void *buf, size_t count) {
return 0;
}
} else {
int retval = crt_write(posixFD, buf, (unsigned int) count);
int retval = crt_write(crt_fd, buf, (unsigned int) count);
if (retval == -1) {
errno = GetLastError();
}
@@ -731,11 +806,11 @@ ssize_t redis_write_impl(int rfd, const void *buf, size_t count) {
return -1;
}
int redis_fsync_impl(int rfd) {
int FDAPI_fsync(int rfd) {
try {
int posixFD = RFDMap::getInstance().lookupPosixFD(rfd);
if (posixFD != -1) {
HANDLE h = (HANDLE) crt_get_osfhandle(posixFD);
int crt_fd = RFDMap::getInstance().lookupCrtFD(rfd);
if (crt_fd != INVALID_FD) {
HANDLE h = (HANDLE) crt_get_osfhandle(crt_fd);
if (h == INVALID_HANDLE_VALUE) {
errno = EBADF;
return -1;
@@ -761,11 +836,11 @@ int redis_fsync_impl(int rfd) {
return -1;
}
int redis_fstat_impl(int rfd, struct __stat64 *buffer) {
int FDAPI_fstat64(int rfd, struct __stat64 *buffer) {
try {
int posixFD = RFDMap::getInstance().lookupPosixFD(rfd);
if (posixFD != -1) {
return _fstat64(posixFD, buffer);
int crt_fd = RFDMap::getInstance().lookupCrtFD(rfd);
if (crt_fd != INVALID_FD) {
return _fstat64(crt_fd, buffer);
}
} CATCH_AND_REPORT();
@@ -773,8 +848,7 @@ int redis_fstat_impl(int rfd, struct __stat64 *buffer) {
return -1;
}
auto f_listen = dllfunctor_stdcall<int, SOCKET, int>("ws2_32.dll", "listen");
int redis_listen_impl(int rfd, int backlog) {
int FDAPI_listen(int rfd, int backlog) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
@@ -790,11 +864,11 @@ int redis_listen_impl(int rfd, int backlog) {
return -1;
}
int redis_ftruncate_impl(int rfd, PORT_LONGLONG length) {
int FDAPI_ftruncate(int rfd, PORT_LONGLONG length) {
try {
int posixFD = RFDMap::getInstance().lookupPosixFD(rfd);
if (posixFD != -1) {
HANDLE h = (HANDLE) crt_get_osfhandle(posixFD);
int crt_fd = RFDMap::getInstance().lookupCrtFD(rfd);
if (crt_fd != INVALID_FD) {
HANDLE h = (HANDLE) crt_get_osfhandle(crt_fd);
if (h == INVALID_HANDLE_VALUE) {
errno = EBADF;
@@ -815,8 +889,7 @@ int redis_ftruncate_impl(int rfd, PORT_LONGLONG length) {
return -1;
}
auto f_bind = dllfunctor_stdcall<int, SOCKET, const struct sockaddr*, int>("ws2_32.dll", "bind");
int redis_bind_impl(int rfd, const struct sockaddr *addr, socklen_t addrlen) {
int FDAPI_bind(int rfd, const struct sockaddr *addr, socklen_t addrlen) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
@@ -831,117 +904,19 @@ int redis_bind_impl(int rfd, const struct sockaddr *addr, socklen_t addrlen) {
return -1;
}
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 {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
return f_WSAGetOverlappedResult(socket, lpOverlapped, lpcbTransfer, fWait, lpdwFlags);
}
} CATCH_AND_REPORT();
errno = EBADF;
return SOCKET_ERROR;
}
auto f_WSADuplicateSocket = dllfunctor_stdcall<int, SOCKET, DWORD, LPWSAPROTOCOL_INFO>("ws2_32.dll", "WSADuplicateSocketW");
int redis_WSADuplicateSocket_impl(int rfd, DWORD dwProcessId, LPWSAPROTOCOL_INFO lpProtocolInfo) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
return f_WSADuplicateSocket(socket, dwProcessId, lpProtocolInfo);
}
} CATCH_AND_REPORT();
errno = EBADF;
return SOCKET_ERROR;
}
auto f_WSASocket = dllfunctor_stdcall<SOCKET, int, int, int, LPWSAPROTOCOL_INFO, GROUP, DWORD>("ws2_32.dll", "WSASocketW");
int redis_WSASocket_impl(int af, int type, int protocol, LPWSAPROTOCOL_INFO lpProtocolInfo, GROUP g, DWORD dwFlags) {
try {
SOCKET socket = f_WSASocket(af,
type,
protocol,
lpProtocolInfo,
g,
dwFlags);
if (socket != INVALID_SOCKET) {
return RFDMap::getInstance().addSocket(socket);
}
} CATCH_AND_REPORT();
return -1;
}
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 {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
return f_WSASend(socket,
lpBuffers,
dwBufferCount,
lpNumberOfBytesSent,
dwFlags,
lpOverlapped,
lpCompletionRoutine);
}
} CATCH_AND_REPORT();
errno = EBADF;
return SOCKET_ERROR;
}
auto f_WSARecv = dllfunctor_stdcall<int, SOCKET, LPWSABUF, DWORD, LPDWORD, LPDWORD, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE>("ws2_32.dll", "WSARecv");
int redis_WSARecv_impl(int rfd, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
return f_WSARecv(socket,
lpBuffers,
dwBufferCount,
lpNumberOfBytesRecvd,
lpFlags,
lpOverlapped,
lpCompletionRoutine);
}
} CATCH_AND_REPORT();
errno = EBADF;
return SOCKET_ERROR;
}
auto f_inet_addr = dllfunctor_stdcall<unsigned long, const char*>("ws2_32.dll", "inet_addr");
unsigned long redis_inet_addr_impl(const char *cp) {
return f_inet_addr(cp);
}
auto f_gethostbyname = dllfunctor_stdcall<struct hostent*, const char*>("ws2_32.dll", "gethostbyname");
struct hostent* redis_gethostbyname_impl(const char *name) {
struct hostent* FDAPI_gethostbyname(const char *name) {
return f_gethostbyname(name);
}
auto f_inet_ntoa = dllfunctor_stdcall<char *, struct in_addr>("ws2_32.dll", "inet_ntoa");
char* redis_inet_ntoa_impl(struct in_addr in) {
return f_inet_ntoa(in);
}
auto f_htons = dllfunctor_stdcall<u_short, u_short>("ws2_32.dll", "htons");
u_short redis_htons_impl(u_short hostshort) {
u_short FDAPI_htons(u_short hostshort) {
return f_htons(hostshort);
}
auto f_htonl = dllfunctor_stdcall<u_long, u_long>("ws2_32.dll", "htonl");
u_long redis_htonl_impl(u_long hostlong) {
u_long FDAPI_htonl(u_long hostlong) {
return f_htonl(hostlong);
}
auto f_getpeername = dllfunctor_stdcall<int, SOCKET, struct sockaddr*, int*>("ws2_32.dll", "getpeername");
int redis_getpeername_impl(int rfd, struct sockaddr *addr, socklen_t * addrlen) {
int FDAPI_getpeername(int rfd, struct sockaddr *addr, socklen_t * addrlen) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
@@ -963,8 +938,7 @@ int redis_getpeername_impl(int rfd, struct sockaddr *addr, socklen_t * addrlen)
return SOCKET_ERROR;
}
auto f_getsockname = dllfunctor_stdcall<int, SOCKET, struct sockaddr*, int*>("ws2_32.dll", "getsockname");
int redis_getsockname_impl(int rfd, struct sockaddr* addrsock, int* addrlen) {
int FDAPI_getsockname(int rfd, struct sockaddr* addrsock, int* addrlen) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
@@ -976,38 +950,36 @@ int redis_getsockname_impl(int rfd, struct sockaddr* addrsock, int* addrlen) {
return SOCKET_ERROR;
}
auto f_ntohs = dllfunctor_stdcall<u_short,u_short>("ws2_32.dll", "ntohs");
u_short redis_ntohs_impl(u_short netshort) {
u_short FDAPI_ntohs(u_short netshort) {
return f_ntohs( netshort );
}
int redis_setmode_impl(int fd,int mode) {
int FDAPI_setmode(int fd, int mode) {
return crt_setmode(fd, mode);
}
size_t redis_fwrite_impl(const void * _Str, size_t _Size, size_t _Count, FILE * _File) {
return crt_fwrite(_Str, _Size, _Count, _File);
size_t FDAPI_fwrite(const void *buffer, size_t size, size_t count, FILE *file) {
return crt_fwrite(buffer, size, count, file);
}
int redis_fclose_impl(FILE * file) {
int posixFD = crt_fileno(file);
if (posixFD != -1) {
RFDMap::getInstance().removePosixFD(posixFD);
int FDAPI_fclose(FILE *file) {
int crt_fd = crt_fileno(file);
if (crt_fd != INVALID_FD) {
RFDMap::getInstance().removeCrtFD(crt_fd);
}
return crt_fclose(file);
}
int redis_fileno_impl(FILE* file) {
int posixFD = crt_fileno(file);
if (posixFD != -1) {
// If posixFD is already mapped, addPosixFD() will return the existing rfd.
return RFDMap::getInstance().addPosixFD(posixFD);
int FDAPI_fileno(FILE *file) {
int crt_fd = crt_fileno(file);
if (crt_fd != INVALID_FD) {
// If crt_fd is already mapped, addCrtFD() will return the existing rfd.
return RFDMap::getInstance().addCrtFD(crt_fd);
}
return -1;
}
auto f_select = dllfunctor_stdcall<int, int, fd_set*, fd_set*, fd_set*, const struct timeval*>("ws2_32.dll", "select");
int redis_select_impl(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) {
int FDAPI_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) {
try {
if (readfds != NULL) {
for (u_int r = 0; r < readfds->fd_count; r++) {
@@ -1032,16 +1004,15 @@ int redis_select_impl(int nfds, fd_set *readfds, fd_set *writefds, fd_set *excep
return SOCKET_ERROR;
}
auto f_ntohl = dllfunctor_stdcall<u_long, u_long>("ws2_32.dll", "ntohl");
u_int redis_ntohl_impl(u_int netlong){
u_int FDAPI_ntohl(u_int netlong){
return f_ntohl(netlong);
}
int redis_isatty_impl(int rfd) {
int FDAPI_isatty(int rfd) {
try {
int posixFD = RFDMap::getInstance().lookupPosixFD(rfd);
if (posixFD != -1) {
return crt_isatty(posixFD);
int crt_fd = RFDMap::getInstance().lookupCrtFD(rfd);
if (crt_fd != INVALID_FD) {
return crt_isatty(crt_fd);
}
} CATCH_AND_REPORT();
@@ -1049,15 +1020,15 @@ int redis_isatty_impl(int rfd) {
return -1;
}
int redis_access_impl(const char *pathname, int mode) {
int FDAPI_access(const char *pathname, int mode) {
return crt_access(pathname, mode);
}
u_int64 redis_lseek64_impl(int rfd, u_int64 offset, int whence) {
u_int64 FDAPI_lseek64(int rfd, u_int64 offset, int whence) {
try {
int posixFD = RFDMap::getInstance().lookupPosixFD(rfd);
if (posixFD != -1) {
return crt_lseek64(posixFD, offset, whence);
int crt_fd = RFDMap::getInstance().lookupCrtFD(rfd);
if (crt_fd != INVALID_FD) {
return crt_lseek64(crt_fd, offset, whence);
}
} CATCH_AND_REPORT();
@@ -1065,11 +1036,11 @@ u_int64 redis_lseek64_impl(int rfd, u_int64 offset, int whence) {
return -1;
}
intptr_t redis_get_osfhandle_impl(RFD rfd) {
intptr_t FDAPI_get_osfhandle(RFD rfd) {
try {
int posixFD = RFDMap::getInstance().lookupPosixFD(rfd);
if (posixFD != -1) {
return crt_get_osfhandle(posixFD);
int crt_fd = RFDMap::getInstance().lookupCrtFD(rfd);
if (crt_fd != INVALID_FD) {
return crt_get_osfhandle(crt_fd);
}
} CATCH_AND_REPORT();
@@ -1077,11 +1048,11 @@ intptr_t redis_get_osfhandle_impl(RFD rfd) {
return -1;
}
int redis_open_osfhandle_impl(intptr_t osfhandle, int flags) {
int FDAPI_open_osfhandle(intptr_t osfhandle, int flags) {
try {
int posixFD = crt_open_osfhandle(osfhandle, flags);
if (posixFD != -1) {
return RFDMap::getInstance().addPosixFD(posixFD);
int crt_fd = crt_open_osfhandle(osfhandle, flags);
if (crt_fd != INVALID_FD) {
return RFDMap::getInstance().addCrtFD(crt_fd);
}
} CATCH_AND_REPORT();
@@ -1089,17 +1060,15 @@ int redis_open_osfhandle_impl(intptr_t osfhandle, int flags) {
return -1;
}
auto f_freeaddrinfo = dllfunctor_stdcall<void, addrinfo*>("ws2_32.dll", "freeaddrinfo");
void redis_freeaddrinfo_impl(struct addrinfo *ai) {
void FDAPI_freeaddrinfo(struct addrinfo *ai) {
f_freeaddrinfo(ai);
}
auto f_getaddrinfo = dllfunctor_stdcall<int, PCSTR, PCSTR, const ADDRINFOA*, ADDRINFOA**>("ws2_32.dll", "getaddrinfo");
int redis_getaddrinfo_impl(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) {
int FDAPI_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) {
return f_getaddrinfo(node, service,hints, res);
}
const char* redis_inet_ntop_impl(int af, const void *src, char *dst, size_t size) {
const char* FDAPI_inet_ntop(int af, const void *src, char *dst, size_t size) {
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);
@@ -1118,7 +1087,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) {
int FDAPI_inet_pton(int family, const char* src, void* dst) {
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);
@@ -1170,7 +1139,6 @@ BOOL ParseStorageAddress(const char *ip, int port, SOCKADDR_STORAGE* pStorageAdd
return TRUE;
}
auto f_WSAStartup = dllfunctor_stdcall<int, WORD, LPWSADATA>("ws2_32.dll", "WSAStartup");
int InitWinsock() {
WSADATA t_wsa;
WORD wVers;
@@ -1186,7 +1154,6 @@ int InitWinsock() {
}
}
auto f_WSACleanup = dllfunctor_stdcall<int>("ws2_32.dll", "WSACleanup");
int CleanupWinsock() {
return f_WSACleanup();
}
@@ -1202,51 +1169,36 @@ private:
Win32_FDSockMap() {
InitWinsock();
pipe = redis_pipe_impl;
socket = redis_socket_impl;
fdapi_close = redis_close_impl;
open = redis_open_impl;
setsockopt = redis_setsockopt_impl;
fcntl = redis_fcntl_impl;
poll = redis_poll_impl;
getsockopt = redis_getsockopt_impl;
connect = redis_connect_impl;
read = redis_read_impl;
write = redis_write_impl;
fsync = redis_fsync_impl;
fdapi_fstat64 = (_redis_fstat)redis_fstat_impl;
listen = redis_listen_impl;
ftruncate = redis_ftruncate_impl;
bind = redis_bind_impl;
htons = redis_htons_impl;
htonl = redis_htonl_impl;
getpeername = redis_getpeername_impl;
getsockname = redis_getsockname_impl;
ntohs = redis_ntohs_impl;
inet_addr = redis_inet_addr_impl;
gethostbyname = redis_gethostbyname_impl;
inet_ntoa = redis_inet_ntoa_impl;
inet_pton = redis_inet_pton_impl;
fdapi_fwrite = redis_fwrite_impl;
fdapi_fclose = redis_fclose_impl;
fdapi_fileno = redis_fileno_impl;
fdapi_setmode = redis_setmode_impl;
WSASend = redis_WSASend_impl;
WSARecv = redis_WSARecv_impl;
WSAGetOverlappedResult = redis_WSAGetOverlappedResult_impl;
WSADuplicateSocket = redis_WSADuplicateSocket_impl;
WSASocket = redis_WSASocket_impl;
select = redis_select_impl;
ntohl = redis_ntohl_impl;
isatty = redis_isatty_impl;
access = redis_access_impl;
lseek64 = redis_lseek64_impl;
fdapi_get_osfhandle = redis_get_osfhandle_impl;
fdapi_open_osfhandle = redis_open_osfhandle_impl;
freeaddrinfo = redis_freeaddrinfo_impl;
getaddrinfo = redis_getaddrinfo_impl;
inet_ntop = redis_inet_ntop_impl;
accept = redis_accept_impl;
accept = FDAPI_accept;
access = FDAPI_access;
bind = FDAPI_bind;
connect = FDAPI_connect;
fcntl = FDAPI_fcntl;
fdapi_fstat64 = (fdapi_fstat) FDAPI_fstat64;
freeaddrinfo = FDAPI_freeaddrinfo;
fsync = FDAPI_fsync;
ftruncate = FDAPI_ftruncate;
getaddrinfo = FDAPI_getaddrinfo;
getsockopt = FDAPI_getsockopt;
getpeername = FDAPI_getpeername;
getsockname = FDAPI_getsockname;
htonl = FDAPI_htonl;
htons = FDAPI_htons;
inet_ntop = FDAPI_inet_ntop;
inet_pton = FDAPI_inet_pton;
isatty = FDAPI_isatty;
listen = FDAPI_listen;
lseek64 = FDAPI_lseek64;
ntohl = FDAPI_ntohl;
ntohs = FDAPI_ntohs;
open = FDAPI_open;
pipe = FDAPI_pipe;
poll = FDAPI_poll;
read = FDAPI_read;
select = FDAPI_select;
setsockopt = FDAPI_setsockopt;
socket = FDAPI_socket;
write = FDAPI_write;
}
~Win32_FDSockMap() {
+105 -138
View File
@@ -33,31 +33,29 @@
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.
// Important! Do not include Winsock API definitions to avoid conflicts
// with API entry points defined below.
#define INCL_WINSOCK_API_PROTOTYPES 0
#include "win32_types.h"
#include <WinSock2.h>
#include <fcntl.h>
#include <stdio.h>
// the following are required to be defined before WS2tcpip is included.
// including a version of this file modified to eliminate prototype definitions not removed by INCL_WINSOCK_API_PROTOTYPES
// Including a version of this file modified to eliminate prototype
// definitions not removed by INCL_WINSOCK_API_PROTOTYPES
#include "WS2tcpip.h"
// reintroducing the inline APIs removed by INCL_WINSOCK_API_PROTOTYPES that Redis is using
// Reintroducing the inline APIs removed by INCL_WINSOCK_API_PROTOTYPES
// that Redis is using
#ifdef UNICODE
#define gai_strerror gai_strerrorW
#else
#define gai_strerror gai_strerrorA
#endif /* UNICODE */
#endif /* UNICODE */
#define GAI_STRERROR_BUFFER_SIZE 1024
WS2TCPIP_INLINE
char *
gai_strerrorA(
_In_ int ecode)
{
WS2TCPIP_INLINE char* gai_strerrorA(_In_ int ecode) {
DWORD dwMsgLen;
static char buff[GAI_STRERROR_BUFFER_SIZE + 1];
@@ -74,12 +72,7 @@ gai_strerrorA(
return buff;
}
WS2TCPIP_INLINE
WCHAR *
gai_strerrorW(
_In_ int ecode
)
{
WS2TCPIP_INLINE WCHAR* gai_strerrorW(_In_ int ecode) {
DWORD dwMsgLen;
static WCHAR buff[GAI_STRERROR_BUFFER_SIZE + 1];
@@ -111,7 +104,6 @@ gai_strerrorW(
#define POLLNVAL 0x0004
typedef struct pollfd {
SOCKET fd;
SHORT events;
SHORT revents;
@@ -119,59 +111,37 @@ typedef struct pollfd {
} WSAPOLLFD, *PWSAPOLLFD, FAR *LPWSAPOLLFD;
#endif
// WinSock APIs used in Win32_wsiocp.cpp
typedef int (*redis_WSASend)(int rfd, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
typedef int (*redis_WSARecv)(int rfd,LPWSABUF lpBuffers,DWORD dwBufferCount,LPDWORD lpNumberOfBytesRecvd,LPDWORD lpFlags,LPWSAOVERLAPPED lpOverlapped,LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
typedef unsigned long (*redis_inet_addr)(const char *cp);
typedef struct hostent* (*redis_gethostbyname)(const char *name);
typedef char* (*redis_inet_ntoa)(struct in_addr in);
typedef BOOL (*redis_WSAGetOverlappedResult)(int rfd,LPWSAOVERLAPPED lpOverlapped, LPDWORD lpcbTransfer, BOOL fWait, LPDWORD lpdwFlags);
typedef int (*redis_WSADuplicateSocket)(int rfd, DWORD dwProcessId, LPWSAPROTOCOL_INFO lpProtocolInfo);
typedef int (*redis_WSASocket)(int af, int type, int protocol, LPWSAPROTOCOL_INFO lpProtocolInfo, GROUP g, DWORD dwFlags);
// other API forwards
typedef int (*redis_setmode)(int fd,int mode);
typedef size_t (*redis_fwrite)(const void * _Str, size_t _Size, size_t _Count, FILE * _File);
typedef int (*redis_fclose)(FILE* file);
typedef int (*redis_fileno)(FILE* file);
// API prototypes must match the unix implementation
typedef int (*redis_pipe)(int pipefd[2]);
typedef int (*redis_socket)(int af,int type,int protocol);
typedef int (*redis_close)(int fd);
typedef int (*redis_open)(const char * _Filename, int _OpenFlag, int flags);
typedef int (*redis_accept)(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
typedef int (*redis_setsockopt)(int sockfd, int level, int optname,const void *optval, socklen_t optlen);
typedef int (*redis_fcntl)(int fd, int cmd, int flags);
typedef int (*redis_poll)(struct pollfd *fds, nfds_t nfds, int timeout);
typedef int (*redis_getsockopt)(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
typedef int (*redis_connect)(int sockfd, const struct sockaddr *addr, size_t addrlen);
typedef ssize_t (*redis_read)(int fd, void *buf, size_t count);
typedef ssize_t (*redis_write)(int fd, const void *buf, size_t count);
typedef int (*redis_fsync)(int fd);
typedef int (*_redis_fstat)(int fd, struct __stat64 *buffer);
typedef int (*redis_listen)(int sockfd, int backlog);
typedef int (*redis_ftruncate)(int fd, PORT_LONGLONG length);
typedef int (*redis_bind)(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
typedef int (*redis_shutdown)(int sockfd, int how);
typedef u_short (*redis_htons)(u_short hostshort);
typedef u_long (*redis_htonl)(u_long hostlong);
typedef int (*redis_getpeername)(int sockfd, struct sockaddr *addr, socklen_t * addrlen);
typedef int (*redis_getsockname)(int sockfd, struct sockaddr* addrsock, int* addrlen );
typedef u_short (*redis_ntohs)(u_short netshort);
typedef void (*redis_freeaddrinfo)(struct addrinfo *ai);
typedef int (*redis_getaddrinfo)(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
typedef const char* (*redis_inet_ntop)(int af, const void *src, char *dst, size_t size);
typedef int (*redis_inet_pton)(int af, const char * src, void *dst);
typedef int (*redis_select)(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);
typedef u_int (*redis_ntohl)(u_int netlong);
typedef int (*redis_isatty)(int fd);
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 (*fdapi_pipe)(int pipefd[2]);
typedef int (*fdapi_socket)(int af,int type,int protocol);
typedef int (*fdapi_open)(const char * _Filename, int _OpenFlag, int flags);
typedef int (*fdapi_accept)(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
typedef int (*fdapi_setsockopt)(int sockfd, int level, int optname,const void *optval, socklen_t optlen);
typedef int (*fdapi_fcntl)(int fd, int cmd, int flags);
typedef int (*fdapi_poll)(struct pollfd *fds, nfds_t nfds, int timeout);
typedef int (*fdapi_getsockopt)(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
typedef int (*fdapi_connect)(int sockfd, const struct sockaddr *addr, size_t addrlen);
typedef ssize_t (*fdapi_read)(int fd, void *buf, size_t count);
typedef ssize_t (*fdapi_write)(int fd, const void *buf, size_t count);
typedef int (*fdapi_fsync)(int fd);
typedef int (*fdapi_listen)(int sockfd, int backlog);
typedef int (*fdapi_ftruncate)(int fd, PORT_LONGLONG length);
typedef int (*fdapi_bind)(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
typedef u_short (*fdapi_htons)(u_short hostshort);
typedef u_long (*fdapi_htonl)(u_long hostlong);
typedef u_short (*fdapi_ntohs)(u_short netshort);
typedef int (*fdapi_getpeername)(int sockfd, struct sockaddr *addr, socklen_t * addrlen);
typedef int (*fdapi_getsockname)(int sockfd, struct sockaddr* addrsock, int* addrlen );
typedef void (*fdapi_freeaddrinfo)(struct addrinfo *ai);
typedef int (*fdapi_getaddrinfo)(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
typedef const char* (*fdapi_inet_ntop)(int af, const void *src, char *dst, size_t size);
typedef int (*fdapi_inet_pton)(int af, const char * src, void *dst);
typedef int (*fdapi_select)(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);
typedef u_int (*fdapi_ntohl)(u_int netlong);
typedef int (*fdapi_isatty)(int fd);
typedef int (*fdapi_access)(const char *pathname, int mode);
typedef u_int64 (*fdapi_lseek64)(int fd, u_int64 offset, int whence);
typedef int (*fdapi_fstat)(int fd, struct __stat64 *buffer);
typedef BOOL fnWSIOCP_CloseSocketStateRFD(int rfd);
@@ -186,84 +156,81 @@ extern "C"
#endif
// API replacements
extern redis_pipe pipe;
extern redis_socket socket;
extern redis_inet_addr inet_addr;
extern redis_inet_ntoa inet_ntoa;
extern fdapi_accept accept;
extern fdapi_access access;
extern fdapi_bind bind;
extern fdapi_connect connect;
extern fdapi_fcntl fcntl;
extern fdapi_fstat fdapi_fstat64;
extern fdapi_freeaddrinfo freeaddrinfo;
extern fdapi_fsync fsync;
extern fdapi_ftruncate ftruncate;
extern fdapi_getaddrinfo getaddrinfo;
extern fdapi_getsockopt getsockopt;
extern fdapi_getpeername getpeername;
extern fdapi_getsockname getsockname;
extern fdapi_htonl htonl;
extern fdapi_htons htons;
extern fdapi_isatty isatty;
extern fdapi_inet_ntop inet_ntop;
extern fdapi_inet_pton inet_pton;
extern fdapi_listen listen;
extern fdapi_lseek64 lseek64;
extern fdapi_ntohl ntohl;
extern fdapi_ntohs ntohs;
extern fdapi_open open;
extern fdapi_pipe pipe;
extern fdapi_poll poll;
extern fdapi_read read;
extern fdapi_select select;
extern fdapi_setsockopt setsockopt;
extern fdapi_socket socket;
extern fdapi_write write;
extern redis_WSASend WSASend;
extern redis_WSARecv WSARecv;
extern redis_WSAGetOverlappedResult WSAGetOverlappedResult;
extern redis_WSADuplicateSocket WSADuplicateSocket;
extern redis_WSASocket WSASocket;
// Other FD based APIs
void FDAPI_SaveSocketAddrStorage(int rfd, SOCKADDR_STORAGE* socketAddrStorage);
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);
int FDAPI_UpdateAcceptContext( int fd );
int FDAPI_PipeSetNonBlock(int rfd, int non_blocking);
void** FDAPI_GetSocketStatePtr(int rfd);
void FDAPI_ClearSocketInfo(int fd);
extern redis_close fdapi_close;
extern redis_open open;
extern redis_accept accept;
extern redis_setsockopt setsockopt;
extern redis_fcntl fcntl;
extern redis_poll poll;
extern redis_getsockopt getsockopt;
extern redis_connect connect;
extern redis_read read;
extern redis_write write;
extern redis_fsync fsync;
extern _redis_fstat fdapi_fstat64;
extern redis_listen listen;
extern redis_ftruncate ftruncate;
extern redis_bind bind;
extern redis_gethostbyname gethostbyname;
extern redis_htons htons;
extern redis_htonl htonl;
extern redis_getpeername getpeername;
extern redis_getsockname getsockname;
extern redis_ntohs ntohs;
extern redis_setmode fdapi_setmode;
extern redis_fwrite fdapi_fwrite;
extern redis_fclose fdapi_fclose;
extern redis_fileno fdapi_fileno;
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_WSASend(int rfd, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
int FDAPI_WSARecv(int rfd, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
BOOL FDAPI_WSAGetOverlappedResult(int rfd, LPWSAOVERLAPPED lpOverlapped, LPDWORD lpcbTransfer, BOOL fWait, LPDWORD lpdwFlags);
int FDAPI_WSADuplicateSocket(int rfd, DWORD dwProcessId, LPWSAPROTOCOL_INFO lpProtocolInfo);
int FDAPI_WSASocket(int af, int type, int protocol, LPWSAPROTOCOL_INFO lpProtocolInfo, GROUP g, DWORD dwFlags);
int FDAPI_WSAGetLastError(void);
extern redis_select select;
extern redis_ntohl ntohl;
extern redis_isatty isatty;
extern redis_access access;
extern redis_lseek64 lseek64;
extern redis_get_osfhandle fdapi_get_osfhandle;
extern redis_open_osfhandle fdapi_open_osfhandle;
extern redis_freeaddrinfo freeaddrinfo;
extern redis_getaddrinfo getaddrinfo;
extern redis_inet_ntop inet_ntop;
extern redis_inet_pton inet_pton;
intptr_t FDAPI_get_osfhandle(int fd);
int FDAPI_open_osfhandle(intptr_t osfhandle, int flags);
// other FD based APIs
void FDAPI_SaveSocketAddrStorage(int rfd, SOCKADDR_STORAGE* socketAddrStorage);
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);
int FDAPI_UpdateAcceptContext( int fd );
int FDAPI_PipeSetNonBlock(int rfd, int non_blocking);
void** FDAPI_GetSocketStatePtr(int rfd);
void FDAPI_ClearSocketInfo(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);
// FDAPI helper function
void FDAPI_SetCloseSocketState(fnWSIOCP_CloseSocketStateRFD* func);
void FDAPI_SetCloseSocketState(fnWSIOCP_CloseSocketStateRFD* func);
// other networking functions
// Other networking functions
BOOL ParseStorageAddress(const char *ip, int port, SOCKADDR_STORAGE* pSotrageAddr);
// macroize CRT definitions to point to our own
extern int FDAPI_close(int rfd);
extern int FDAPI_fclose(FILE *file);
extern int FDAPI_setmode(int fd, int mode);
extern size_t FDAPI_fwrite(const void *buffer, size_t size, size_t count, FILE *file);
extern int FDAPI_fileno(FILE *file);
// Macroize CRT definitions to point to our own
#ifndef FDAPI_NOCRTREDEFS
#define close(fd) fdapi_close(fd)
#define setmode(fd,mode) fdapi_setmode(fd,mode)
#define fwrite(Str, Size, Count, File) fdapi_fwrite(Str,Size,Count,File)
#define fclose(File) fdapi_fclose(File)
#define fileno(File) fdapi_fileno(File)
#define _get_osfhandle(fd) fdapi_get_osfhandle(fd)
#define close(fd) FDAPI_close(fd)
#define fclose(File) FDAPI_fclose(File)
#define setmode(fd,mode) FDAPI_setmode(fd,mode)
#define fwrite(Str,Size,Count,File) FDAPI_fwrite(Str,Size,Count,File)
#define fileno(File) FDAPI_fileno(File)
#define _INC_STAT_INL
#define fstat(_Desc, _Stat) fdapi_fstat64(_Desc,_Stat)
#define fstat(fd,buffer) fdapi_fstat64(fd,buffer)
#endif
#ifdef __cplusplus
+4
View File
@@ -21,6 +21,7 @@
<ItemGroup>
<ClCompile Include="win32fixes.c" />
<ClCompile Include="Win32_ANSI.c" />
<ClCompile Include="Win32_APIs.c" />
<ClCompile Include="Win32_CommandLine.cpp" />
<ClCompile Include="Win32_Common.cpp" />
<ClCompile Include="Win32_dlmalloc.c" />
@@ -35,6 +36,7 @@
<ClCompile Include="Win32_service.cpp" />
<ClCompile Include="Win32_StackTrace.cpp" />
<ClCompile Include="Win32_ThreadControl.c" />
<ClCompile Include="Win32_Time.c" />
<ClCompile Include="win32_util.c" />
<ClCompile Include="Win32_variadicFunctor.cpp" />
<ClCompile Include="win32_wsiocp.c" />
@@ -42,6 +44,7 @@
<ItemGroup>
<ClInclude Include="win32fixes.h" />
<ClInclude Include="Win32_ANSI.h" />
<ClInclude Include="Win32_APIs.h" />
<ClInclude Include="Win32_Assert.h" />
<ClInclude Include="Win32_CommandLine.h" />
<ClInclude Include="Win32_dlmalloc.h" />
@@ -58,6 +61,7 @@
<ClInclude Include="Win32_SmartHandle.h" />
<ClInclude Include="Win32_StackTrace.h" />
<ClInclude Include="Win32_ThreadControl.h" />
<ClInclude Include="Win32_Time.h" />
<ClInclude Include="win32_types.h" />
<ClInclude Include="win32_util.h" />
<ClInclude Include="Win32_variadicFunctor.h" />
+8 -10
View File
@@ -57,10 +57,10 @@ int pthread_create(pthread_t *thread, const void *unused, void *(*start_routine)
return 0;
}
/* Noop in windows */
/* Noop in Windows */
int pthread_detach(pthread_t thread) {
REDIS_NOTUSED(thread);
return 0; /* noop */
return 0;
}
pthread_t pthread_self(void) {
@@ -116,9 +116,9 @@ int pthread_cond_init(pthread_cond_t *cond, const void *unused) {
}
cond->continue_broadcast = CreateEvent(NULL, /* security */
FALSE, /* auto-reset */
FALSE, /* not signaled */
NULL); /* name */
FALSE, /* auto-reset */
FALSE, /* not signaled */
NULL); /* name */
if (!cond->continue_broadcast) {
errno = GetLastError();
return -1;
@@ -149,7 +149,7 @@ int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) {
*/
LeaveCriticalSection(mutex);
/* let's wait - ignore return value */
/* Let's wait - ignore return value */
WaitForSingleObject(cond->sema, INFINITE);
/*
@@ -180,7 +180,7 @@ int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) {
* the mutex. Auf in den Kampf!
*/
}
/* lock external mutex again */
/* Lock external mutex again */
EnterCriticalSection(mutex);
return 0;
@@ -198,9 +198,7 @@ int pthread_cond_signal(pthread_cond_t *cond) {
have_waiters = cond->waiters > 0;
LeaveCriticalSection(&cond->waiters_lock);
/*
* Signal only when there are waiters
*/
/* Signal only when there are waiters */
if (have_waiters)
return ReleaseSemaphore(cond->sema, 1, NULL) ?
0 : GetLastError();
+1 -1
View File
@@ -13,7 +13,7 @@ typedef size_t _sigset_t;
#define SIG_SETMASK (0)
#define SIG_BLOCK (1)
#define SIG_UNBLOCK (2)
#endif /*SIG_SETMASK*/
#endif /* SIG_SETMASK */
/* threads avoiding pthread.h */
#define pthread_mutex_t CRITICAL_SECTION
+15 -15
View File
@@ -320,9 +320,9 @@ BOOL QForkChildInit(HANDLE QForkConrolMemoryMapHandle, DWORD ParentProcessID) {
if (g_pQForkControl->typeOfOperation == OperationType::otRDB) {
g_ChildExitCode = do_rdbSave(g_pQForkControl->globalData.filename);
} else if (g_pQForkControl->typeOfOperation == OperationType::otAOF) {
int aof_pipe_read_ack = fdapi_open_osfhandle((intptr_t) g_pQForkControl->globalData.aof_pipe_read_ack_handle, _O_APPEND);
int aof_pipe_read_data = fdapi_open_osfhandle((intptr_t) g_pQForkControl->globalData.aof_pipe_read_data_handle, _O_APPEND);
int aof_pipe_write_ack = fdapi_open_osfhandle((intptr_t) g_pQForkControl->globalData.aof_pipe_write_ack_handle, _O_APPEND);
int aof_pipe_read_ack = FDAPI_open_osfhandle((intptr_t) g_pQForkControl->globalData.aof_pipe_read_ack_handle, _O_APPEND);
int aof_pipe_read_data = FDAPI_open_osfhandle((intptr_t) g_pQForkControl->globalData.aof_pipe_read_data_handle, _O_APPEND);
int aof_pipe_write_ack = FDAPI_open_osfhandle((intptr_t) g_pQForkControl->globalData.aof_pipe_write_ack_handle, _O_APPEND);
g_ChildExitCode = do_aofSave(g_pQForkControl->globalData.filename,
aof_pipe_read_ack,
aof_pipe_read_data,
@@ -330,14 +330,14 @@ BOOL QForkChildInit(HANDLE QForkConrolMemoryMapHandle, DWORD ParentProcessID) {
);
} else if (g_pQForkControl->typeOfOperation == OperationType::otSocket) {
LPWSAPROTOCOL_INFO lpProtocolInfo = (LPWSAPROTOCOL_INFO) g_pQForkControl->globalData.protocolInfo;
int pipe_write_fd = fdapi_open_osfhandle((intptr_t)g_pQForkControl->globalData.pipe_write_handle, _O_APPEND);
int pipe_write_fd = FDAPI_open_osfhandle((intptr_t) g_pQForkControl->globalData.pipe_write_handle, _O_APPEND);
for (int i = 0; i < g_pQForkControl->globalData.numfds; i++) {
g_pQForkControl->globalData.fds[i] = WSASocket(FROM_PROTOCOL_INFO,
FROM_PROTOCOL_INFO,
FROM_PROTOCOL_INFO,
&lpProtocolInfo[i],
0,
WSA_FLAG_OVERLAPPED);
g_pQForkControl->globalData.fds[i] = FDAPI_WSASocket(FROM_PROTOCOL_INFO,
FROM_PROTOCOL_INFO,
FROM_PROTOCOL_INFO,
&lpProtocolInfo[i],
0,
WSA_FLAG_OVERLAPPED);
}
g_ChildExitCode = do_socketSave(g_pQForkControl->globalData.fds,
@@ -979,9 +979,9 @@ pid_t BeginForkOperation_Aof(
unsigned __int32 dictHashSeed,
char* logfile)
{
HANDLE aof_pipe_write_ack_handle = (HANDLE) _get_osfhandle(aof_pipe_write_ack_to_parent);
HANDLE aof_pipe_read_ack_handle = (HANDLE) _get_osfhandle(aof_pipe_read_ack_from_parent);
HANDLE aof_pipe_read_data_handle = (HANDLE) _get_osfhandle(aof_pipe_read_data_from_parent);
HANDLE aof_pipe_write_ack_handle = (HANDLE) FDAPI_get_osfhandle(aof_pipe_write_ack_to_parent);
HANDLE aof_pipe_read_ack_handle = (HANDLE) FDAPI_get_osfhandle(aof_pipe_read_ack_from_parent);
HANDLE aof_pipe_read_data_handle = (HANDLE) FDAPI_get_osfhandle(aof_pipe_read_data_from_parent);
// The handle is already inheritable so there is no need to duplicate it
g_pQForkControl->globalData.aof_pipe_write_ack_handle = (aof_pipe_write_ack_handle);
@@ -996,7 +996,7 @@ void BeginForkOperation_Socket_PidHook(DWORD dwProcessId) {
WSAPROTOCOL_INFO* protocolInfo = (WSAPROTOCOL_INFO*)dlmalloc(sizeof(WSAPROTOCOL_INFO) * g_pQForkControl->globalData.numfds);
g_pQForkControl->globalData.protocolInfo = protocolInfo;
for(int i = 0; i < g_pQForkControl->globalData.numfds; i++) {
WSADuplicateSocket(g_pQForkControl->globalData.fds[i], dwProcessId, &protocolInfo[i]);
FDAPI_WSADuplicateSocket(g_pQForkControl->globalData.fds[i], dwProcessId, &protocolInfo[i]);
}
}
@@ -1014,7 +1014,7 @@ pid_t BeginForkOperation_Socket(
g_pQForkControl->globalData.numfds = numfds;
g_pQForkControl->globalData.clientids = clientids;
HANDLE pipe_write_handle = (HANDLE)_get_osfhandle(pipe_write_fd);
HANDLE pipe_write_handle = (HANDLE) FDAPI_get_osfhandle(pipe_write_fd);
// The handle is already inheritable so there is no need to duplicate it
g_pQForkControl->globalData.pipe_write_handle = (pipe_write_handle);
+7 -4
View File
@@ -30,7 +30,7 @@
#include "../redis.h"
#include "Win32Fixes.h"
#include "Win32_EventLog.h"
#include <time.h>
#include "Win32_Time.h"
#include <assert.h>
static const char ellipsis[] = "[...]";
@@ -136,11 +136,14 @@ void redisLogRaw(int level, const char *msg) {
secs = gettimeofdaysecs(&usecs);
now = localtime(&secs);
vlen = snprintf(buf + off, sizeof(buf) - off, "[%d] ", (int)_getpid());
assert(vlen >= 0); off += vlen;
assert(vlen >= 0);
off += vlen;
vlen = (int)strftime(buf + off, sizeof(buf) - off, "%d %b %H:%M:%S.", now);
assert(vlen >= 0); off += vlen;
assert(vlen >= 0);
off += vlen;
vlen = snprintf(buf + off, sizeof(buf) - off, "%03d %c ", usecs / 1000, c[level]);
assert(vlen >= 0); off += vlen;
assert(vlen >= 0);
off += vlen;
vlen = snprintf(buf + off, sizeof(buf) - off, "%s\n", msg);
if (vlen >= 0 && (off + vlen < sizeof(buf))) {
completeMessageLength = off + vlen;
+217
View File
@@ -0,0 +1,217 @@
/*
* Copyright (c), Microsoft Open Technologies, Inc.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* Credits Henry Rawas (henryr@schakra.com) */
#include "Win32_Time.h"
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include <assert.h>
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
struct timezone {
int tz_minuteswest; /* minutes W of Greenwich */
int tz_dsttime; /* type of dst correction */
};
/* fnGetSystemTimePreciseAsFileTime is NULL if and only if it hasn't been initialized. */
static VOID(WINAPI *fnGetSystemTimePreciseAsFileTime)(LPFILETIME) = NULL;
/* Interval (in seconds) of the high-resolution clock.
* Special values:
* 0 : it hasn't been initialized
* -1 : the system doesn't have high-resolution clock support
*/
static double highResTimeInterval = 0;
void InitHighResRelativeTime() {
LARGE_INTEGER perfFrequency;
if (highResTimeInterval != 0)
return;
/* Retrieve high-resolution timer frequency
* and precompute its reciprocal.
*/
if (QueryPerformanceFrequency(&perfFrequency)) {
highResTimeInterval = 1.0 / perfFrequency.QuadPart;
} else {
highResTimeInterval = -1;
}
assert(highResTimeInterval != 0);
}
void InitHighResAbsoluteTime() {
FARPROC fp;
HMODULE module;
if (fnGetSystemTimePreciseAsFileTime != NULL)
return;
/* Use GetSystemTimeAsFileTime as fallbcak where GetSystemTimePreciseAsFileTime is not available */
fnGetSystemTimePreciseAsFileTime = GetSystemTimeAsFileTime;
module = GetModuleHandleA("kernel32.dll");
if (module) {
fp = GetProcAddress(module, "GetSystemTimePreciseAsFileTime");
if (fp) {
fnGetSystemTimePreciseAsFileTime = (VOID(WINAPI*)(LPFILETIME)) fp;
}
}
assert(fnGetSystemTimePreciseAsFileTime != NULL);
}
void InitTimeFunctions() {
InitHighResRelativeTime();
InitHighResAbsoluteTime();
}
uint64_t GetHighResRelativeTime(double scale) {
LARGE_INTEGER counter;
if (highResTimeInterval <= 0) {
if (highResTimeInterval == 0) {
InitHighResRelativeTime();
}
/* If the performance interval is less than zero, there's no support. */
if (highResTimeInterval < 0) {
return 0;
}
}
if (!QueryPerformanceCounter(&counter)) {
return 0;
}
/* Because we have no guarantee about the order of magnitude of the
* performance counter interval, integer math could cause this computation
* to overflow. Therefore we resort to floating point math.
*/
return (uint64_t) ((double) counter.QuadPart * highResTimeInterval * scale);
}
time_t gettimeofdaysecs(unsigned int *usec) {
FILETIME ft;
time_t tmpres = 0;
GetSystemTimeAsFileTime(&ft);
tmpres |= ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
/*converting file time to unix epoch*/
tmpres /= 10; /*convert into microseconds*/
tmpres -= DELTA_EPOCH_IN_MICROSECS;
if (usec != NULL) {
*usec = (unsigned int) (tmpres % 1000000UL);
}
return (tmpres / 1000000UL);
}
int gettimeofday_fast(struct timeval *tv, struct timezone *tz) {
FILETIME ft;
unsigned __int64 tmpres = 0;
static int tzflag;
if (NULL != tv) {
GetSystemTimeAsFileTime(&ft);
tmpres |= ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
/*converting file time to unix epoch*/
tmpres /= 10; /*convert into microseconds*/
tmpres -= DELTA_EPOCH_IN_MICROSECS;
tv->tv_sec = (long) (tmpres / 1000000UL);
tv->tv_usec = (long) (tmpres % 1000000UL);
}
if (NULL != tz) {
if (!tzflag)
{
_tzset();
tzflag++;
}
tz->tz_minuteswest = _timezone / 60;
tz->tz_dsttime = _daylight;
}
return 0;
}
int gettimeofday_highres(struct timeval *tv, struct timezone *tz) {
FILETIME ft;
unsigned __int64 tmpres = 0;
static int tzflag;
if (NULL == fnGetSystemTimePreciseAsFileTime) {
InitHighResAbsoluteTime();
}
if (NULL != tv) {
fnGetSystemTimePreciseAsFileTime(&ft);
tmpres |= ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
/*converting file time to unix epoch*/
tmpres /= 10; /*convert into microseconds*/
tmpres -= DELTA_EPOCH_IN_MICROSECS;
tv->tv_sec = (long) (tmpres / 1000000UL);
tv->tv_usec = (long) (tmpres % 1000000UL);
}
if (NULL != tz) {
if (!tzflag) {
_tzset();
tzflag++;
}
tz->tz_minuteswest = _timezone / 60;
tz->tz_dsttime = _daylight;
}
return 0;
}
/* ctime_r is documented (http://www.mkssoftware.com/docs/man3/ctime_r.3.asp)
* to be reentrant.
* _ctime64 is not thread safe.
* Since this is used only in sentinel.c and Redis is single threaded this
* is not a problem */
char *ctime_r(const time_t *clock, char *buf) {
char* t = _ctime64(clock);
if (t != NULL) {
strcpy(buf, t);
} else {
buf[0] = 0;
}
return buf;
}
+38
View File
@@ -0,0 +1,38 @@
/*
* Copyright (c), Microsoft Open Technologies, Inc.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* Credits Henry Rawas (henryr@schakra.com) */
#ifndef WIN32TIME_H
#define WIN32TIME_H
#include <stdint.h>
#define gettimeofday gettimeofday_highres
void InitTimeFunctions();
uint64_t GetHighResRelativeTime(double scale);
time_t gettimeofdaysecs(unsigned int *usec);
int gettimeofday_highres(struct timeval *tv, struct timezone *tz);
char* ctime_r(const time_t *clock, char *buf);
#endif
+2 -2
View File
@@ -19,11 +19,12 @@
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <cstdint>
#include <stdio.h>
int crt_pipe(int *pfds, unsigned int psize, int textmode);
int crt_close(int fd);
int crt_read(int fd, void *buffer, unsigned int count);
@@ -35,7 +36,6 @@ int crt_setmode(int fd, int mode);
size_t crt_fwrite(const void *buffer, size_t size, size_t count, FILE *file);
int crt_fclose(FILE* file);
int crt_fileno(FILE* file);
int crt_isatty(int fd);
int crt_access(const char *pathname, int mode);
__int64 crt_lseek64(int fd, __int64 offset, int origin);
+46 -44
View File
@@ -1,28 +1,28 @@
/*
* Copyright (c), Microsoft Open Technologies, Inc.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
* Copyright (c), Microsoft Open Technologies, Inc.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "win32_types.h"
#include "win32_rfdmap.h"
#include "Win32_Assert.h"
RFDMap& RFDMap::getInstance() {
static RFDMap instance; // Instantiated on first use. Guaranteed to be destroyed.
@@ -32,11 +32,11 @@ RFDMap& RFDMap::getInstance() {
RFDMap::RFDMap() {
InitializeCriticalSection(&mutex);
// stdin, assigned rfd = 0
addPosixFD(0);
addCrtFD(0);
// stdout, assigned rfd = 1
addPosixFD(1);
addCrtFD(1);
// stderr, assigned rfd = 2
addPosixFD(2);
addCrtFD(2);
}
RFD RFDMap::getNextRFDAvailable() {
@@ -91,33 +91,34 @@ void RFDMap::removeRFDToSocketInfo(RFD rfd) {
LeaveCriticalSection(&mutex);
}
RFD RFDMap::addPosixFD(int posixFD) {
RFD RFDMap::addCrtFD(int crt_fd) {
RFD rfd;
EnterCriticalSection(&mutex);
if (PosixFDToRFDMap.find(posixFD) != PosixFDToRFDMap.end()) {
rfd = PosixFDToRFDMap[posixFD];
if (CrtFDToRFDMap.find(crt_fd) != CrtFDToRFDMap.end()) {
rfd = CrtFDToRFDMap[crt_fd];
} else {
rfd = getNextRFDAvailable();
if (rfd != INVALID_FD) {
PosixFDToRFDMap[posixFD] = rfd;
RFDToPosixFDMap[rfd] = posixFD;
CrtFDToRFDMap[crt_fd] = rfd;
RFDToCrtFDMap[rfd] = crt_fd;
}
}
LeaveCriticalSection(&mutex);
return rfd;
}
void RFDMap::removePosixFD(int posixFD) {
// posixFD between 0 and 2 should never be removed since they are assigned
// to stdin, stdout and stderr
if (posixFD > 2) {
void RFDMap::removeCrtFD(int crt_fd) {
// crt_fd between FIRST_RESERVED_RFD_INDEX and LAST_RESERVED_RFD_INDEX
// should never be removed.
ASSERT(FIRST_RESERVED_RFD_INDEX == 0);
if (crt_fd > RFDMap::LAST_RESERVED_RFD_INDEX) {
EnterCriticalSection(&mutex);
PosixFDToRFDMapType::iterator mit = PosixFDToRFDMap.find(posixFD);
if (mit != PosixFDToRFDMap.end()) {
map<int, RFD>::iterator mit = CrtFDToRFDMap.find(crt_fd);
if (mit != CrtFDToRFDMap.end()) {
RFD rfd = (*mit).second;
RFDRecyclePool.push(rfd);
RFDToPosixFDMap.erase(rfd);
PosixFDToRFDMap.erase(posixFD);
RFDToCrtFDMap.erase(rfd);
CrtFDToRFDMap.erase(crt_fd);
}
LeaveCriticalSection(&mutex);
}
@@ -143,14 +144,15 @@ SocketInfo* RFDMap::lookupSocketInfo(RFD rfd) {
return socket_info;
}
int RFDMap::lookupPosixFD(RFD rfd) {
int posixFD = -1;
int RFDMap::lookupCrtFD(RFD rfd) {
int crt_fd = INVALID_FD;
EnterCriticalSection(&mutex);
if (RFDToPosixFDMap.find(rfd) != RFDToPosixFDMap.end()) {
posixFD = RFDToPosixFDMap[rfd];
} else if (rfd >= 0 && rfd <= 2) {
posixFD = rfd;
if (RFDToCrtFDMap.find(rfd) != RFDToCrtFDMap.end()) {
crt_fd = RFDToCrtFDMap[rfd];
} else if (rfd >= RFDMap::FIRST_RESERVED_RFD_INDEX
&& rfd <= RFDMap::LAST_RESERVED_RFD_INDEX) {
crt_fd = rfd;
}
LeaveCriticalSection(&mutex);
return posixFD;
return crt_fd;
}
+59 -61
View File
@@ -1,24 +1,24 @@
/*
* Copyright (c), Microsoft Open Technologies, Inc.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
* Copyright (c), Microsoft Open Technologies, Inc.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
@@ -31,22 +31,6 @@
using namespace std;
typedef struct {
SOCKET socket;
void* state;
int flags;
SOCKADDR_STORAGE socketAddrStorage;
} SocketInfo;
typedef int RFD; // Redis File Descriptor
#define INVALID_FD -1
typedef map<SOCKET, RFD> SocketToRFDMapType;
typedef map<int, RFD> PosixFDToRFDMapType;
typedef map<RFD, SocketInfo> RFDToSocketInfoMapType;
typedef map<RFD, int> RFDToPosixFDMapType;
typedef queue<RFD> RFDRecyclePoolType;
/* In UNIX File Descriptors increment by one for each new one. Windows handles
* do not follow the same rule. Additionally UNIX uses a 32-bit int to
* represent a FD while Windows_x64 uses a 64-bit value to represent a handle.
@@ -57,7 +41,18 @@ typedef queue<RFD> RFDRecyclePoolType;
* indicate the number of handles that have been created (and other UNIXisms),
* this code maps SOCKET handles to a virtual FD number starting at 3 (0,1 and
* 2 are reserved for stdin, stdout and stderr).
*/
*/
#define INVALID_FD -1
typedef int RFD; // Redis File Descriptor
typedef struct {
SOCKET socket;
void* state;
int flags;
SOCKADDR_STORAGE socketAddrStorage;
} SocketInfo;
class RFDMap {
public:
static RFDMap& getInstance();
@@ -68,11 +63,11 @@ private:
void operator=(RFDMap const&); // Don't implement to guarantee singleton semantics
private:
SocketToRFDMapType SocketToRFDMap;
PosixFDToRFDMapType PosixFDToRFDMap;
RFDToSocketInfoMapType RFDToSocketInfoMap;
RFDToPosixFDMapType RFDToPosixFDMap;
RFDRecyclePoolType RFDRecyclePool;
map<SOCKET, RFD> SocketToRFDMap;
map<int, RFD> CrtFDToRFDMap;
map<RFD, SocketInfo> RFDToSocketInfoMap;
map<RFD, int> RFDToCrtFDMap;
queue<RFD> RFDRecyclePool;
private:
CRITICAL_SECTION mutex;
@@ -87,33 +82,36 @@ private:
RFD getNextRFDAvailable();
public:
/* Adds a socket to the socket map. Returns the redis file descriptor value
* for the socket. Returns invalidRFD if the socket is already added to the
* collection. */
RFD addSocket(SOCKET s);
/* Adds a socket to SocketToRFDMap and to RFDToSocketInfoMap.
* Returns the RFD value for the socket.
* Returns INVALID_RFD if the socket is already added to the collection. */
RFD addSocket(SOCKET socket);
/* Removes a socket from the list of sockets. Also removes the associated
* file descriptor. */
void removeSocketToRFD(SOCKET s);
/* Removes a socket from SocketToRFDMap. */
void removeSocketToRFD(SOCKET socket);
/* Removes a RFD from RFDToSocketInfoMap.
* It frees the associated RFD adding it to RFDRecyclePool. */
void removeRFDToSocketInfo(RFD rfd);
/* Adds a posixFD (used with low-level CRT posix file functions) to the
* posixFD map. Returns the redis file descriptor value for the posixFD.
* Returns invalidRFD if the posicFD is already added to the collection. */
RFD addPosixFD(int posixFD);
/* Adds a CRT fd (used with low-level CRT posix file functions) to RFDToCrtFDMap.
* Returns the RFD value for the crt_fd.
* Returns the existing RFD if the crt_fd is already present in the collection. */
RFD addCrtFD(int crt_fd);
/* Removes a socket from the list of sockets. Also removes the associated
* file descriptor. */
void removePosixFD(int posixFD);
/* Removes a socket from RFDToCrtFDMap.
* It frees the associated RFD adding it to RFDRecyclePool. */
void removeCrtFD(int crt_fd);
/* Returns the socket associated with a file descriptor. */
/* Returns the socket associated with a RFD.
* Returns INVALID_SOCKET if the socket is not found. */
SOCKET lookupSocket(RFD rfd);
/* Returns a pointer to the socket info structure associated with a file
* descriptor. */
/* Returns a pointer to the socket info structure associated with a RFD.
* Return NULL if the info socket info structure is not found. */
SocketInfo* lookupSocketInfo(RFD rfd);
/* Returns the socket associated with a file descriptor. */
int lookupPosixFD(RFD rfd);
/* Returns the crt_fd associated with a RFD.
* Returns INVALID_FD if the crt_fd is not found. */
int lookupCrtFD(RFD rfd);
};
+14 -17
View File
@@ -154,9 +154,6 @@ int WSIOCP_QueueAccept(int listenfd) {
/* Listen using extension function to get faster accepts */
int WSIOCP_Listen(int rfd, int backlog) {
aeSockState *sockstate;
const GUID wsaid_acceptex = WSAID_ACCEPTEX;
const GUID wsaid_acceptexaddrs = WSAID_GETACCEPTEXSOCKADDRS;
if ((sockstate = WSIOCP_GetSocketState(rfd)) == NULL) {
errno = WSAEINVAL;
return SOCKET_ERROR;
@@ -267,13 +264,13 @@ int WSIOCP_ReceiveDone(int fd) {
zreadbuf.buf = zreadchar;
zreadbuf.len = 0;
result = WSARecv(fd,
&zreadbuf,
1,
&bytesReceived,
&recvFlags,
&sockstate->ov_read,
NULL);
result = FDAPI_WSARecv(fd,
&zreadbuf,
1,
&bytesReceived,
&recvFlags,
&sockstate->ov_read,
NULL);
if (SUCCEEDED_WITH_IOCP(result == 0)){
sockstate->masks |= READ_QUEUED;
} else {
@@ -323,13 +320,13 @@ int WSIOCP_SocketSend(int fd, char *buf, int len, void *eventLoop,
areq->req.buf = buf;
areq->proc = (aeFileProc *) proc;
result = WSASend(fd,
&areq->wbuf,
1,
&bytesSent,
0,
&areq->ov,
NULL);
result = FDAPI_WSASend(fd,
&areq->wbuf,
1,
&bytesSent,
0,
&areq->ov,
NULL);
if (SUCCEEDED_WITH_IOCP(result == 0)) {
errno = WSA_IO_PENDING;
-242
View File
@@ -9,13 +9,7 @@
#include <stdlib.h>
#include <errno.h>
#include "win32fixes.h"
#include <signal.h>
#include <time.h>
#include <locale.h>
#include <math.h>
#include <string.h>
#include <assert.h>
#include "Win32_ThreadControl.h"
/* Redefined here to avoid redis.h so it can be used in other projects */
#define REDIS_NOTUSED(V) ((void) V)
@@ -51,41 +45,6 @@ int kill(pid_t pid, int sig) {
}
}
/* Replace MS C rtl rand which is 15bit with 32 bit */
int replace_random() {
unsigned int x=0;
if (RtlGenRandom == NULL) {
// load proc if not loaded
HMODULE lib = LoadLibraryA("advapi32.dll");
RtlGenRandom = (RtlGenRandomFunc)GetProcAddress(lib, "SystemFunction036");
if (RtlGenRandom == NULL) return 1;
}
RtlGenRandom(&x, sizeof(unsigned int));
return (int)(x >> 1);
}
/* Rename which works on Windows when file exists */
int replace_rename(const char *src, const char *dst) {
/* anti-virus may lock file - error code 5. Retry until it works or get a different error */
int retries = 50;
while (1) {
if (MoveFileExA(src, dst, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH)) {
return 0;
} else {
errno = GetLastError();
if (errno != 5) break;
retries--;
if (retries == 0) {
retries = 50;
Sleep(10);
}
}
}
/* On error we will return generic error code without GetLastError() */
return -1;
}
/* Redis CPU GetProcessTimes -> rusage */
int getrusage(int who, struct rusage * r) {
FILETIME starttime, exittime, kerneltime, usertime;
@@ -134,177 +93,6 @@ int getrusage(int who, struct rusage * r) {
return 0;
}
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
struct timezone {
int tz_minuteswest; /* minutes W of Greenwich */
int tz_dsttime; /* type of dst correction */
};
/* fnGetSystemTimePreciseAsFileTime is NULL if and only if it hasn't been initialized. */
static VOID (WINAPI *fnGetSystemTimePreciseAsFileTime)(LPFILETIME) = NULL;
/* Interval (in seconds) of the high-resolution clock.
* Special values:
* 0 : it hasn't been initialized
* -1 : the system doesn't have high-resolution clock support
*/
static double highResTimeInterval = 0;
void InitHighResRelativeTime() {
LARGE_INTEGER perfFrequency;
if (highResTimeInterval != 0)
return;
/* Retrieve high-resolution timer frequency
* and precompute its reciprocal.
*/
if (QueryPerformanceFrequency(&perfFrequency)) {
highResTimeInterval = 1.0 / perfFrequency.QuadPart;
} else {
highResTimeInterval = -1;
}
assert(highResTimeInterval != 0);
}
void InitHighResAbsoluteTime() {
FARPROC fp;
HMODULE module;
if (fnGetSystemTimePreciseAsFileTime != NULL)
return;
/* Use GetSystemTimeAsFileTime as fallbcak where GetSystemTimePreciseAsFileTime is not available */
fnGetSystemTimePreciseAsFileTime = GetSystemTimeAsFileTime;
module = GetModuleHandleA("kernel32.dll");
if (module) {
fp = GetProcAddress(module, "GetSystemTimePreciseAsFileTime");
if (fp) {
fnGetSystemTimePreciseAsFileTime = (VOID(WINAPI*)(LPFILETIME)) fp;
}
}
assert(fnGetSystemTimePreciseAsFileTime != NULL);
}
void InitTimeFunctions() {
InitHighResRelativeTime();
InitHighResAbsoluteTime();
}
uint64_t GetHighResRelativeTime(double scale) {
LARGE_INTEGER counter;
if (highResTimeInterval <= 0) {
if (highResTimeInterval == 0) {
InitHighResRelativeTime();
}
/* If the performance interval is less than zero, there's no support. */
if (highResTimeInterval < 0) {
return 0;
}
}
if (!QueryPerformanceCounter(&counter)) {
return 0;
}
/* Because we have no guarantee about the order of magnitude of the
* performance counter interval, integer math could cause this computation
* to overflow. Therefore we resort to floating point math.
*/
return (uint64_t) ((double)counter.QuadPart * highResTimeInterval * scale);
}
time_t gettimeofdaysecs(unsigned int *usec) {
FILETIME ft;
time_t tmpres = 0;
GetSystemTimeAsFileTime(&ft);
tmpres |= ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
/*converting file time to unix epoch*/
tmpres /= 10; /*convert into microseconds*/
tmpres -= DELTA_EPOCH_IN_MICROSECS;
if (usec != NULL) {
*usec = (unsigned int) (tmpres % 1000000UL);
}
return (tmpres / 1000000UL);
}
int gettimeofday_fast(struct timeval *tv, struct timezone *tz) {
FILETIME ft;
unsigned __int64 tmpres = 0;
static int tzflag;
if (NULL != tv) {
GetSystemTimeAsFileTime(&ft);
tmpres |= ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
/*converting file time to unix epoch*/
tmpres /= 10; /*convert into microseconds*/
tmpres -= DELTA_EPOCH_IN_MICROSECS;
tv->tv_sec = (long)(tmpres / 1000000UL);
tv->tv_usec = (long)(tmpres % 1000000UL);
}
if (NULL != tz) {
if (!tzflag)
{
_tzset();
tzflag++;
}
tz->tz_minuteswest = _timezone / 60;
tz->tz_dsttime = _daylight;
}
return 0;
}
int gettimeofday_highres(struct timeval *tv, struct timezone *tz) {
FILETIME ft;
unsigned __int64 tmpres = 0;
static int tzflag;
if (NULL == fnGetSystemTimePreciseAsFileTime) {
InitHighResAbsoluteTime();
}
if (NULL != tv) {
fnGetSystemTimePreciseAsFileTime(&ft);
tmpres |= ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
/*converting file time to unix epoch*/
tmpres /= 10; /*convert into microseconds*/
tmpres -= DELTA_EPOCH_IN_MICROSECS;
tv->tv_sec = (long) (tmpres / 1000000UL);
tv->tv_usec = (long) (tmpres % 1000000UL);
}
if (NULL != tz) {
if (!tzflag) {
_tzset();
tzflag++;
}
tz->tz_minuteswest = _timezone / 60;
tz->tz_dsttime = _daylight;
}
return 0;
}
static _locale_t clocale = NULL;
double wstrtod(const char *nptr, char **eptr) {
double d;
@@ -398,33 +186,3 @@ char *wsa_strerror(int err) {
return wsa_strerror_buf;
}
char *ctime_r(const time_t *clock, char *buf) {
// Note: ctime_r is documented (http://www.mkssoftware.com/docs/man3/ctime_r.3.asp) to be reentrant.
// _ctime64 is not thread safe. Since this is used only in sentinel.c, and Redis is single threaded,
// I am bypasing the critical section needed to guard against reentrancy.
char* t = _ctime64(clock);
if (t != NULL) {
strcpy(buf, t);
} else {
buf[0] = 0;
}
return buf;
}
int truncate(const char *path, PORT_LONGLONG length) {
LARGE_INTEGER newSize;
HANDLE toTruncate;
toTruncate = CreateFileA(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (toTruncate != INVALID_HANDLE_VALUE) {
newSize.QuadPart = length;
if (FALSE == (SetFilePointerEx(toTruncate, newSize, NULL, FILE_BEGIN) && SetEndOfFile(toTruncate))) {
errno = ENOENT;
return -1;
} else {
return 0;
}
} else {
errno = ENOENT;
return -1;
}
}
+4 -57
View File
@@ -29,24 +29,13 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <windows.h>
#include <float.h>
#include <fcntl.h> /* _O_BINARY */
#include <limits.h> /* INT_MAX */
#include <process.h>
#include <sys/types.h>
#include <stdint.h>
#include "Win32_APIs.h"
#include "Win32_FDAPI.h"
#define fseeko fseeko64
#define ftello ftello64
#define snprintf _snprintf
#define ftello64 _ftelli64
#define fseeko64 _fseeki64
#define strcasecmp _stricmp
#define strtoll _strtoi64
#if _MSC_VER < 1800
#define isnan _isnan
#define isfinite _finite
@@ -55,25 +44,6 @@
#include <math.h>
#endif
/* following defined to choose little endian byte order */
#define __i386__ 1
#if !defined(va_copy)
#define va_copy(d,s) d = (s)
#endif
#define sleep(x) Sleep((x)*1000)
#ifndef __RTL_GENRANDOM
#define __RTL_GENRANDOM 1
typedef BOOLEAN (_stdcall* RtlGenRandomFunc)(void * RandomBuffer, ULONG RandomBufferLength);
#endif
RtlGenRandomFunc RtlGenRandom;
#define random() (long)replace_random()
#define rand() replace_random()
#define srandom srand
int replace_random();
#if !defined(mode_t)
#define mode_t long
#endif
@@ -83,16 +53,6 @@ int replace_random();
typedef unsigned __int32 u_int32_t;
#endif
/* Redis calls usleep(1) to give thread some time
* Sleep(0) should do the same on windows
* In other cases, usleep is called with milisec resolution,
* which can be directly translated to winapi Sleep() */
#undef usleep
#define usleep(x) (x == 1) ? Sleep(0) : Sleep((int)((x)/1000))
/* Processes */
#define waitpid(pid,statusp,options) _cwait(statusp, pid, WAIT_CHILD)
#define WNOHANG 1
/* file mapping */
@@ -191,28 +151,20 @@ int sigaction(int sig, struct sigaction *in, struct sigaction *out);
#endif
#endif
#define rename(a,b) replace_rename(a,b)
int replace_rename(const char *src, const char *dest);
/* Misc Unix -> Win32 */
int kill(pid_t pid, int sig);
pid_t wait3(int *stat_loc, int options, void *rusage);
void InitTimeFunctions();
uint64_t GetHighResRelativeTime(double scale);
int gettimeofday_fast(struct timeval *tv, struct timezone *tz);
int gettimeofday_highres(struct timeval *tv, struct timezone *tz);
time_t gettimeofdaysecs(unsigned int *usec);
#define gettimeofday gettimeofday_highres
char *ctime_r(const time_t *clock, char *buf);
/* strtod does not handle Inf and Nan, we need to do the check before calling strtod */
#undef strtod
#define strtod(nptr, eptr) wstrtod((nptr), (eptr))
double wstrtod(const char *nptr, char **eptr);
int strerror_r(int err, char* buf, size_t buflen);
char *wsa_strerror(int err);
/* structs and functions for using IOCP with windows sockets */
/* need callback on write complete. aeWinSendReq is used to pass parameters */
@@ -230,9 +182,6 @@ int WSIOCP_Accept(int rfd, struct sockaddr *sa, socklen_t *len);
int WSIOCP_SocketConnect(int rfd, const SOCKADDR_STORAGE *ss);
int WSIOCP_SocketConnectBind(int rfd, const SOCKADDR_STORAGE *ss, const char* source_addr);
int strerror_r(int err, char* buf, size_t buflen);
char *wsa_strerror(int err);
// access check for executable uses X_OK. For Windows use READ access.
#ifndef X_OK
#define X_OK 4
@@ -242,8 +191,6 @@ char *wsa_strerror(int err);
#define STDOUT_FILENO 1
#endif
int truncate(const char *path, PORT_LONGLONG length);
#define lseek lseek64
#endif /* WIN32FIXES_H */
+3 -3
View File
@@ -401,12 +401,12 @@ int aeProcessEvents(aeEventLoop *eventLoop, int flags)
* timer to fire. */
aeGetTime(&now_sec, &now_ms);
tvp = &tv;
tvp->tv_sec = shortest->when_sec - now_sec;
tvp->tv_sec = (int)(shortest->when_sec - now_sec); WIN_PORT_FIX /* cast (int) */
if (shortest->when_ms < now_ms) {
tvp->tv_usec = ((shortest->when_ms+1000) - now_ms)*1000;
tvp->tv_usec = (int)((shortest->when_ms+1000) - now_ms)*1000; WIN_PORT_FIX /* cast (int) */
tvp->tv_sec --;
} else {
tvp->tv_usec = (shortest->when_ms - now_ms)*1000;
tvp->tv_usec = (int)(shortest->when_ms - now_ms)*1000; WIN_PORT_FIX /* cast (int) */
}
if (tvp->tv_sec < 0) tvp->tv_sec = 0;
if (tvp->tv_usec < 0) tvp->tv_usec = 0;
+1 -1
View File
@@ -264,7 +264,7 @@ static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
if (areq->proc != NULL) {
DWORD written = 0;
DWORD flags;
WSAGetOverlappedResult(rfd, &areq->ov, &written, FALSE, &flags);
FDAPI_WSAGetOverlappedResult(rfd, &areq->ov, &written, FALSE, &flags);
areq->proc(areq->eventLoop, rfd, &areq->req, (int) written);
}
sockstate->wreqs--;
+14 -9
View File
@@ -116,17 +116,21 @@ int anetKeepAlive(char *err, int fd, int interval)
DWORD dwBytesRet = 0;
alive.onoff = TRUE;
alive.keepalivetime = interval * 1000;
/* According to http://msdn.microsoft.com/en-us/library/windows/desktop/ee470551(v=vs.85).aspx
On Windows Vista and later, the number of keep-alive probes (data retransmissions) is set to 10 and cannot be changed.
So we set the keep alive interval as interval/10, as 10 probes will be send before detecting an error
*/
/* According to
* http://msdn.microsoft.com/en-us/library/windows/desktop/ee470551(v=vs.85).aspx
* On Windows Vista and later, the number of keep-alive probes (data
* retransmissions) is set to 10 and cannot be changed.
* So we set the keep alive interval as interval/10, as 10 probes will
* be send before detecting an error */
val = interval/10;
if (val == 0) val = 1;
alive.keepaliveinterval = val*1000;
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", strerror(errno));
return ANET_ERR;
NULL, 0, &dwBytesRet, NULL, NULL) == SOCKET_ERROR) {
anetSetError(err,
"WSAIotcl(SIO_KEEPALIVE_VALS) failed with error code %d\n",
strerror(errno));
return ANET_ERR;
}
#else
/* Default settings are more or less garbage, with the keepalive time
@@ -208,7 +212,7 @@ int anetTcpKeepAlive(char *err, int fd)
int anetSendTimeout(char *err, int fd, PORT_LONGLONG ms) {
struct timeval tv;
tv.tv_sec = ms/1000;
tv.tv_sec = (int) ms/1000; WIN_PORT_FIX /* cast (int) */
tv.tv_usec = (ms%1000)*1000;
if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1) {
anetSetError(err, "setsockopt SO_SNDTIMEO: %s", strerror(errno));
@@ -290,7 +294,8 @@ static int anetCreateSocket(char *err, int domain) {
#define ANET_CONNECT_NONBLOCK 1
#define ANET_CONNECT_BE_BINDING 2 /* Best effort binding. */
#ifdef _WIN32
static int anetTcpGenericConnect(char *err, char *addr, int port, char *source_addr, int flags) {
static int anetTcpGenericConnect(char *err, char *addr, int port,
char *source_addr, int flags) {
int fd;
SOCKADDR_STORAGE socketStorage;
+2 -2
View File
@@ -188,9 +188,9 @@ void *bioProcessBackgroundJobs(void *arg) {
/* Process the job accordingly to its type. */
if (type == REDIS_BIO_CLOSE_FILE) {
close((PORT_LONG) job->arg1);
close((int) job->arg1); WIN_PORT_FIX /* cast (long) -> (int) */
} else if (type == REDIS_BIO_AOF_FSYNC) {
aof_fsync((PORT_LONG) job->arg1);
aof_fsync((int) job->arg1); WIN_PORT_FIX /* cast (long) -> (int) */
} else {
redisPanic("Wrong job type in bioProcessBackgroundJobs().");
}
+1 -1
View File
@@ -581,7 +581,7 @@ void bitposCommand(redisClient *c) {
addReplyLongLong(c, -1);
} else {
PORT_LONG bytes = end-start+1;
PORT_LONG pos = redisBitpos(p+start,bytes,bit);
PORT_LONG pos = redisBitpos(p+start,(PORT_ULONG)bytes,(int)bit); WIN_PORT_FIX /* cast (PORT_ULONG), cast (int) */
/* If we are looking for clear bits, and the user specified an exact
* range with start-end, we can't consider the right of the range as
+4 -4
View File
@@ -378,7 +378,7 @@ int clusterLockConfig(char *filename) {
if (flock(fd,LOCK_EX|LOCK_NB) == -1) {
if (errno == EWOULDBLOCK) {
#else
HANDLE hFile = (HANDLE) _get_osfhandle(fd);
HANDLE hFile = (HANDLE) FDAPI_get_osfhandle(fd);
OVERLAPPED ovlp;
DWORD size_lower, size_upper;
// start offset is 0, and also zero the remaining members of the struct
@@ -2278,8 +2278,8 @@ void clusterSendPing(clusterLink *link, int type) {
freshnodes--;
gossip = &(hdr->data.ping.gossip[gossipcount]);
memcpy(gossip->nodename,this->name,REDIS_CLUSTER_NAMELEN);
gossip->ping_sent = htonl(this->ping_sent);
gossip->pong_received = htonl(this->pong_received);
gossip->ping_sent = htonl((u_long)this->ping_sent); WIN_PORT_FIX /* cast (u_long) */
gossip->pong_received = htonl((u_long)this->pong_received); WIN_PORT_FIX /* cast (u_long) */
memcpy(gossip->ip,this->ip,sizeof(this->ip));
gossip->port = htons(this->port);
gossip->flags = htons(this->flags);
@@ -4674,7 +4674,7 @@ try_again:
while ((towrite = sdslen(buf) - pos) > 0) {
towrite = (towrite > (64 * 1024) ? (64 * 1024) : towrite);
while (nwritten != (signed) towrite) {
nwritten = syncWrite(cs->fd, buf + pos, (ssize_t) towrite, timeout);
nwritten = (int) syncWrite(cs->fd, buf + pos, (ssize_t) towrite, timeout);
if (nwritten != (signed) towrite) {
DWORD err = GetLastError();
if (err == WSAEWOULDBLOCK) {
+7 -7
View File
@@ -556,7 +556,7 @@ void scanGenericCommand(redisClient *c, robj *o, PORT_ULONG cursor) {
/* Filter element if it does not match the pattern. */
if (!filter && use_pattern) {
if (sdsEncodedObject(kobj)) {
if (!stringmatchlen(pat, patlen, kobj->ptr, sdslen(kobj->ptr), 0))
if (!stringmatchlen(pat, patlen, kobj->ptr, (int)sdslen(kobj->ptr), 0)) WIN_PORT_FIX /* cast (int) */
filter = 1;
} else {
char buf[REDIS_LONGSTR_SIZE];
@@ -1141,14 +1141,14 @@ int *sortGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys)
* a fast way a key that belongs to a specified hash slot. This is useful
* while rehashing the cluster. */
void slotToKeyAdd(robj *key) {
unsigned int hashslot = keyHashSlot(key->ptr,sdslen(key->ptr));
unsigned int hashslot = keyHashSlot(key->ptr,(int)sdslen(key->ptr)); WIN_PORT_FIX /* cast (int) */
zslInsert(server.cluster->slots_to_keys,hashslot,key);
incrRefCount(key);
}
void slotToKeyDel(robj *key) {
unsigned int hashslot = keyHashSlot(key->ptr,sdslen(key->ptr));
unsigned int hashslot = keyHashSlot(key->ptr,(int)sdslen(key->ptr)); WIN_PORT_FIX /* cast (int) */
zslDelete(server.cluster->slots_to_keys,hashslot,key);
}
@@ -1210,16 +1210,16 @@ unsigned int countKeysInSlot(unsigned int hashslot) {
/* Use rank of first element, if any, to determine preliminary count */
if (zn != NULL) {
rank = zslGetRank(zsl, zn->score, zn->obj);
count = (zsl->length - (rank - 1));
rank = (int) zslGetRank(zsl, zn->score, zn->obj); WIN_PORT_FIX /* cast (int) */
count = (int) (zsl->length - (rank - 1)); WIN_PORT_FIX /* cast (int) */
/* Find last element in range */
zn = zslLastInRange(zsl, &range);
/* Use rank of last element, if any, to determine the actual count */
if (zn != NULL) {
rank = zslGetRank(zsl, zn->score, zn->obj);
count -= (zsl->length - rank);
rank = (int) zslGetRank(zsl, zn->score, zn->obj); WIN_PORT_FIX /* cast (int) */
count -= (int) (zsl->length - rank); WIN_PORT_FIX /* cast (int) */
}
}
return count;
+7 -6
View File
@@ -34,6 +34,7 @@
*/
#ifdef _WIN32
#include "win32_Interop/win32_util.h"
#include "win32_Interop/win32_time.h"
#include "win32_Interop/win32fixes.h"
#endif
@@ -642,9 +643,9 @@ dictEntry *dictGetRandomKey(dict *d)
do {
/* We are sure there are no elements in indexes from 0
* to rehashidx-1 */
h = d->rehashidx + (random() % (d->ht[0].size +
h = (unsigned int) (d->rehashidx + (random() % (d->ht[0].size + WIN_PORT_FIX /* cast (unsigned int) */
d->ht[1].size -
d->rehashidx));
d->rehashidx)));
he = (h >= d->ht[0].size) ? d->ht[1].table[h - d->ht[0].size] :
d->ht[0].table[h];
} while(he == NULL);
@@ -699,7 +700,7 @@ unsigned int dictGetSomeKeys(dict *d, dictEntry **des, unsigned int count) {
unsigned int stored = 0, maxsizemask;
unsigned int maxsteps;
if (dictSize(d) < count) count = dictSize(d);
if (dictSize(d) < count) count = (unsigned int)dictSize(d); WIN_PORT_FIX /* cast (unsigned int) */
maxsteps = count*10;
/* Try to do a rehashing work proportional to 'count'. */
@@ -711,9 +712,9 @@ unsigned int dictGetSomeKeys(dict *d, dictEntry **des, unsigned int count) {
}
tables = dictIsRehashing(d) ? 2 : 1;
maxsizemask = d->ht[0].sizemask;
maxsizemask = (unsigned int) d->ht[0].sizemask; WIN_PORT_FIX /* cast (unsigned int) */
if (tables > 1 && maxsizemask < d->ht[1].sizemask)
maxsizemask = d->ht[1].sizemask;
maxsizemask = (unsigned int) d->ht[1].sizemask; WIN_PORT_FIX /* cast (unsigned int) */
/* Pick a random point inside the larger table. */
unsigned int i = random() & maxsizemask;
@@ -728,7 +729,7 @@ unsigned int dictGetSomeKeys(dict *d, dictEntry **des, unsigned int count) {
* table, there will be no elements in both tables up to
* the current rehashing index, so we jump if possible.
* (this happens when going from big to small table). */
if (i >= d->ht[1].size) i = d->rehashidx;
if (i >= d->ht[1].size) i = (unsigned int) d->rehashidx; WIN_PORT_FIX /* cast (unsigned int) */
continue;
}
if (i >= d->ht[j].size) continue; /* Out of range for this table. */
+1
View File
@@ -30,6 +30,7 @@
#ifdef _WIN32
#include "Win32_Interop/win32_util.h"
#include "Win32_Interop/win32fixes.h"
#include "Win32_Interop/win32_time.h"
#endif
#include "fmacros.h"
+1 -1
View File
@@ -63,7 +63,7 @@ void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset
return MAP_FAILED;
};
h = CreateFileMapping((HANDLE) _get_osfhandle(fd), NULL, PAGE_READONLY, 0, 0, NULL);
h = CreateFileMapping((HANDLE) FDAPI_get_osfhandle(fd), NULL, PAGE_READONLY, 0, 0, NULL);
if (!h) {
return MAP_FAILED;
}
+1
View File
@@ -30,6 +30,7 @@
#ifdef _WIN32
#include "win32_Interop/win32_types.h"
#include "win32_Interop/win32_time.h"
#include "win32_Interop/win32_util.h"
#endif
+4 -4
View File
@@ -28,10 +28,10 @@
*/
#ifdef _WIN32
#include "win32_Interop\win32_util.h"
#include "Win32_Interop\Win32_FDAPI.h"
#include "Win32_Interop\Win32_ThreadControl.h"
#include "Win32_Interop\Win32_QFork.h"
#include "win32_Interop/Win32_util.h"
#include "Win32_Interop/Win32_FDAPI.h"
#include "Win32_Interop/Win32_ThreadControl.h"
#include "Win32_Interop/Win32_QFork.h"
#endif
#include "redis.h"
+1
View File
@@ -34,6 +34,7 @@
#include "Win32_Interop/win32_util.h"
#include "Win32_Interop/win32fixes.h"
#include "Win32_Interop/Win32_RedisLog.h"
#include "Win32_Interop/Win32_Time.h"
#endif
#include "fmacros.h"
+1
View File
@@ -31,6 +31,7 @@
#ifdef _WIN32
#include "win32_Interop/win32_util.h"
#include "win32_Interop/win32_types.h"
#include "win32_Interop/win32_time.h"
#endif
#include "redis.h"
+4 -2
View File
@@ -400,8 +400,10 @@ sds sdscatvprintf(sds s, const char *fmt, va_list ap) {
if (buf != staticbuf) zfree(buf);
buflen *= 2;
// WIN_PORT_FIX: from the vsnprintf documentation in MSDN: "To ensure that there is room for the terminating null, be sure that
// WIN_PORT_FIX: count is strictly less than the buffer length and initialize the buffer to null prior to calling the function."
// WIN_PORT_FIX: from the vsnprintf documentation in MSDN:
// "To ensure that there is room for the terminating null, be sure
// that count is strictly less than the buffer length and
// initialize the buffer to null prior to calling the function."
buf = IF_WIN32(zcalloc,zmalloc)(buflen);
if (buf == NULL) return NULL;
continue;
+1 -1
View File
@@ -2753,7 +2753,7 @@ int sentinelIsQuorumReachable(sentinelRedisInstance *master, int *usableptr) {
dictEntry *de;
int usable = 1; /* Number of usable Sentinels. Init to 1 to count myself. */
int result = SENTINEL_ISQR_OK;
int voters = dictSize(master->sentinels)+1; /* Known Sentinels + myself. */
int voters = (int)dictSize(master->sentinels)+1; /* Known Sentinels + myself. */ WIN_PORT_FIX /* cast (int) */
di = dictGetIterator(master->sentinels);
while((de = dictNext(di)) != NULL) {
+3 -3
View File
@@ -478,13 +478,13 @@ void sortCommand(redisClient *c) {
/* Send command output to the output buffer, performing the specified
* GET/DEL/INCR/DECR operations if any. */
outputlen = getop ? getop*(end-start+1) : end-start+1;
outputlen = getop ? (unsigned int)(getop*(end-start+1)) : (unsigned int)(end-start+1); WIN_PORT_FIX /* cast (unsigned int), cast (unsigned int) */
if (int_convertion_error) {
addReplyError(c,"One or more scores can't be converted into double");
} else if (storekey == NULL) {
/* STORE option not specified, sent the sorting result to client */
addReplyMultiBulkLen(c,outputlen);
for (j = start; j <= end; j++) {
for (j = (int)start; j <= end; j++) { WIN_PORT_FIX /* cast (int) */
listNode *ln;
listIter li;
@@ -512,7 +512,7 @@ void sortCommand(redisClient *c) {
robj *sobj = createZiplistObject();
/* STORE option specified, set the sorting result as a List object */
for (j = start; j <= end; j++) {
for (j = (int)start; j <= end; j++) { WIN_PORT_FIX /* cast (int) */
listNode *ln;
listIter li;
+1 -1
View File
@@ -721,7 +721,7 @@ void genericHgetallCommand(redisClient *c, int flags) {
if (flags & REDIS_HASH_KEY) multiplier++;
if (flags & REDIS_HASH_VALUE) multiplier++;
length = hashTypeLength(o) * multiplier;
length = (int)(hashTypeLength(o) * multiplier); WIN_PORT_FIX /* cast (int) */
addReplyMultiBulkLen(c, length);
hi = hashTypeInitIterator(o);
+3 -3
View File
@@ -126,7 +126,7 @@ listTypeIterator *listTypeInitIterator(robj *subject, PORT_LONG index, unsigned
li->encoding = subject->encoding;
li->direction = direction;
if (li->encoding == REDIS_ENCODING_ZIPLIST) {
li->zi = ziplistIndex(subject->ptr,index);
li->zi = ziplistIndex(subject->ptr,(int)index); WIN_PORT_FIX /* cast (int) */
} else if (li->encoding == REDIS_ENCODING_LINKEDLIST) {
li->ln = listIndex(subject->ptr,index);
} else {
@@ -613,8 +613,8 @@ void ltrimCommand(redisClient *c) {
/* Remove list elements to perform the trim */
if (o->encoding == REDIS_ENCODING_ZIPLIST) {
o->ptr = ziplistDeleteRange(o->ptr,0,ltrim);
o->ptr = ziplistDeleteRange(o->ptr,-rtrim,rtrim);
o->ptr = ziplistDeleteRange(o->ptr,0,(unsigned int)ltrim); WIN_PORT_FIX /* cast (unsigned int) */
o->ptr = ziplistDeleteRange(o->ptr,(unsigned int)-rtrim,(unsigned int)rtrim); WIN_PORT_FIX /* cast (unsigned int) */
} else if (o->encoding == REDIS_ENCODING_LINKEDLIST) {
list = o->ptr;
for (j = 0; j < ltrim; j++) {
+1 -1
View File
@@ -584,7 +584,7 @@ int qsortCompareSetsByCardinality(const void *s1, const void *s2) {
int qsortCompareSetsByRevCardinality(const void *s1, const void *s2) {
robj *o1 = *(robj**)s1, *o2 = *(robj**)s2;
return (o2 ? setTypeSize(o2) : 0) - (o1 ? setTypeSize(o1) : 0);
return (int)((o2 ? setTypeSize(o2) : 0) - (o1 ? setTypeSize(o1) : 0)); WIN_PORT_FIX /* cast (int) */
}
void sinterGenericCommand(redisClient *c, robj **setkeys, PORT_ULONG setnum, robj *dstkey) {
+13 -13
View File
@@ -139,7 +139,7 @@ zskiplistNode *zslInsert(zskiplist *zsl, double score, robj *obj) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
update[i]->level[i].span = (unsigned int) zsl->length; WIN_PORT_FIX /* cast (unsigned int) */
}
zsl->level = level;
}
@@ -1087,7 +1087,7 @@ unsigned int zsetLength(robj *zobj) {
if (zobj->encoding == REDIS_ENCODING_ZIPLIST) {
length = zzlLength(zobj->ptr);
} else if (zobj->encoding == REDIS_ENCODING_SKIPLIST) {
length = ((zset*)zobj->ptr)->zsl->length;
length = (int) ((zset*)zobj->ptr)->zsl->length; WIN_PORT_FIX /* cast (int) */
} else {
redisPanic("Unknown sorted set encoding");
}
@@ -1494,7 +1494,7 @@ void zremrangeGenericCommand(redisClient *c, int rangetype) {
if (zobj->encoding == REDIS_ENCODING_ZIPLIST) {
switch(rangetype) {
case ZRANGE_RANK:
zobj->ptr = zzlDeleteRangeByRank(zobj->ptr,start+1,end+1,&deleted);
zobj->ptr = zzlDeleteRangeByRank(zobj->ptr,(int)start+1,(int)end+1,&deleted); WIN_PORT_FIX /* cast (int), cast (int) */
break;
case ZRANGE_SCORE:
zobj->ptr = zzlDeleteRangeByScore(zobj->ptr,&range,&deleted);
@@ -1511,7 +1511,7 @@ void zremrangeGenericCommand(redisClient *c, int rangetype) {
zset *zs = zobj->ptr;
switch(rangetype) {
case ZRANGE_RANK:
deleted = zslDeleteRangeByRank(zs->zsl,start+1,end+1,zs->dict);
deleted = zslDeleteRangeByRank(zs->zsl,(int)start+1,(int)end+1,zs->dict); WIN_PORT_FIX /* cast (int), cast (int) */
break;
case ZRANGE_SCORE:
deleted = zslDeleteRangeByScore(zs->zsl,&range,zs->dict);
@@ -1687,7 +1687,7 @@ int zuiLength(zsetopsrc *op) {
return intsetLen(op->subject->ptr);
} else if (op->encoding == REDIS_ENCODING_HT) {
dict *ht = op->subject->ptr;
return (int)dictSize(ht); WIN_PORT_FIX /* int */
return (int)dictSize(ht); WIN_PORT_FIX /* cast (int) */
} else {
redisPanic("Unknown set encoding");
}
@@ -1696,7 +1696,7 @@ int zuiLength(zsetopsrc *op) {
return zzlLength(op->subject->ptr);
} else if (op->encoding == REDIS_ENCODING_SKIPLIST) {
zset *zs = op->subject->ptr;
return zs->zsl->length;
return (int)zs->zsl->length; WIN_PORT_FIX /* cast (int) */
} else {
redisPanic("Unknown sorted set encoding");
}
@@ -2190,7 +2190,7 @@ void zrangeGenericCommand(redisClient *c, int reverse) {
return;
}
if (end >= llen) end = llen-1;
rangelen = (end-start)+1;
rangelen = (int)(end-start)+1; WIN_PORT_FIX /* cast (int) */
/* Return the result in form of a multi-bulk reply */
addReplyMultiBulkLen(c, withscores ? (rangelen*2) : rangelen);
@@ -2203,9 +2203,9 @@ void zrangeGenericCommand(redisClient *c, int reverse) {
PORT_LONGLONG vlong;
if (reverse)
eptr = ziplistIndex(zl,-2-(2*start));
eptr = ziplistIndex(zl,(int)(-2-(2*start))); WIN_PORT_FIX /* cast (int) */
else
eptr = ziplistIndex(zl,2*start);
eptr = ziplistIndex(zl,(int)(2*start)); WIN_PORT_FIX /* cast (int) */
redisAssertWithInfo(c,zobj,eptr != NULL);
sptr = ziplistNext(zl,eptr);
@@ -2519,7 +2519,7 @@ void zcountCommand(redisClient *c) {
/* Use rank of first element, if any, to determine preliminary count */
if (zn != NULL) {
rank = zslGetRank(zsl, zn->score, zn->obj);
count = (zsl->length - (rank - 1));
count = (int)(zsl->length - (rank - 1)); WIN_PORT_FIX /* cast (int) */
/* Find last element in range */
zn = zslLastInRange(zsl, &range);
@@ -2527,7 +2527,7 @@ void zcountCommand(redisClient *c) {
/* Use rank of last element, if any, to determine the actual count */
if (zn != NULL) {
rank = zslGetRank(zsl, zn->score, zn->obj);
count -= (zsl->length - rank);
count -= (int)(zsl->length - rank); WIN_PORT_FIX /* cast (int) */
}
}
} else {
@@ -2597,7 +2597,7 @@ void zlexcountCommand(redisClient *c) {
/* Use rank of first element, if any, to determine preliminary count */
if (zn != NULL) {
rank = zslGetRank(zsl, zn->score, zn->obj);
count = (zsl->length - (rank - 1));
count = (int)(zsl->length - (rank - 1)); WIN_PORT_FIX /* cast (int) */
/* Find last element in range */
zn = zslLastInLexRange(zsl, &range);
@@ -2605,7 +2605,7 @@ void zlexcountCommand(redisClient *c) {
/* Use rank of last element, if any, to determine the actual count */
if (zn != NULL) {
rank = zslGetRank(zsl, zn->score, zn->obj);
count -= (zsl->length - rank);
count -= (int)(zsl->length - rank); WIN_PORT_FIX /* cast (int) */
}
}
} else {
+1
View File
@@ -30,6 +30,7 @@
#ifdef _WIN32
#include "win32_Interop/win32_util.h"
#include "win32_Interop/win32fixes.h"
#include "win32_Interop/win32_time.h"
#include <direct.h> // for getcwd
#include <shlwapi.h> // for PathIsRelative
#endif