[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:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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. */
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user