diff --git a/src/Win32_Interop/Win32_APIs.c b/src/Win32_Interop/Win32_APIs.c new file mode 100644 index 00000000..2d78ea0f --- /dev/null +++ b/src/Win32_Interop/Win32_APIs.c @@ -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 + +/* 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; + } +} \ No newline at end of file diff --git a/src/Win32_Interop/Win32_APIs.h b/src/Win32_Interop/Win32_APIs.h new file mode 100644 index 00000000..e21e71e5 --- /dev/null +++ b/src/Win32_Interop/Win32_APIs.h @@ -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 + +// 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 \ No newline at end of file diff --git a/src/Win32_Interop/Win32_Common.cpp b/src/Win32_Interop/Win32_Common.cpp index c6d09db5..5e065317 100644 --- a/src/Win32_Interop/Win32_Common.cpp +++ b/src/Win32_Interop/Win32_Common.cpp @@ -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; diff --git a/src/Win32_Interop/Win32_FDAPI.cpp b/src/Win32_Interop/Win32_FDAPI.cpp index 3d888a6e..bb50598c 100644 --- a/src/Win32_Interop/Win32_FDAPI.cpp +++ b/src/Win32_Interop/Win32_FDAPI.cpp @@ -31,7 +31,6 @@ #include "Win32_variadicFunctor.h" #include "Win32_ANSI.h" #include "win32_util.h" -#include #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("ws2_32.dll", "WSACleanup"); +auto f_WSAFDIsSet = dllfunctor_stdcall("ws2_32.dll", "__WSAFDIsSet"); +auto f_WSAGetLastError = dllfunctor_stdcall("ws2_32.dll", "WSAGetLastError"); +auto f_WSAGetOverlappedResult = dllfunctor_stdcall("ws2_32.dll", "WSAGetOverlappedResult"); +auto f_WSADuplicateSocket = dllfunctor_stdcall("ws2_32.dll", "WSADuplicateSocketW"); +auto f_WSAIoctl = dllfunctor_stdcall("ws2_32.dll", "WSAIoctl"); +auto f_WSARecv = dllfunctor_stdcall("ws2_32.dll", "WSARecv"); +auto f_WSASocket = dllfunctor_stdcall("ws2_32.dll", "WSASocketW"); +auto f_WSASend = dllfunctor_stdcall("ws2_32.dll", "WSASend"); +auto f_WSAStartup = dllfunctor_stdcall("ws2_32.dll", "WSAStartup"); +auto f_ioctlsocket = dllfunctor_stdcall("ws2_32.dll", "ioctlsocket"); + +auto f_accept = dllfunctor_stdcall("ws2_32.dll", "accept"); +auto f_bind = dllfunctor_stdcall("ws2_32.dll", "bind"); +auto f_closesocket = dllfunctor_stdcall("ws2_32.dll", "closesocket"); +auto f_connect = dllfunctor_stdcall("ws2_32.dll", "connect"); +auto f_freeaddrinfo = dllfunctor_stdcall("ws2_32.dll", "freeaddrinfo"); +auto f_getaddrinfo = dllfunctor_stdcall("ws2_32.dll", "getaddrinfo"); +auto f_gethostbyname = dllfunctor_stdcall("ws2_32.dll", "gethostbyname"); +auto f_getpeername = dllfunctor_stdcall("ws2_32.dll", "getpeername"); +auto f_getsockname = dllfunctor_stdcall("ws2_32.dll", "getsockname"); +auto f_getsockopt = dllfunctor_stdcall("ws2_32.dll", "getsockopt"); +auto f_htonl = dllfunctor_stdcall("ws2_32.dll", "htonl"); +auto f_htons = dllfunctor_stdcall("ws2_32.dll", "htons"); +auto f_listen = dllfunctor_stdcall("ws2_32.dll", "listen"); +auto f_ntohs = dllfunctor_stdcall("ws2_32.dll", "ntohs"); +auto f_ntohl = dllfunctor_stdcall("ws2_32.dll", "ntohl"); +auto f_recv = dllfunctor_stdcall("ws2_32.dll", "recv"); +auto f_select = dllfunctor_stdcall("ws2_32.dll", "select"); +auto f_send = dllfunctor_stdcall("ws2_32.dll", "send"); +auto f_setsockopt = dllfunctor_stdcall("ws2_32.dll", "setsockopt"); +auto f_socket = dllfunctor_stdcall("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("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("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("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("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("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("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("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("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("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("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("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("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("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("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("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("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("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("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("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("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("ws2_32.dll", "inet_addr"); -unsigned long redis_inet_addr_impl(const char *cp) { - return f_inet_addr(cp); -} - - -auto f_gethostbyname = dllfunctor_stdcall("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("ws2_32.dll", "inet_ntoa"); -char* redis_inet_ntoa_impl(struct in_addr in) { - return f_inet_ntoa(in); -} - -auto f_htons = dllfunctor_stdcall("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("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("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("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("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("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("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("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("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("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("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("ws2_32.dll", "WSAStartup"); int InitWinsock() { WSADATA t_wsa; WORD wVers; @@ -1186,7 +1154,6 @@ int InitWinsock() { } } -auto f_WSACleanup = dllfunctor_stdcall("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() { diff --git a/src/Win32_Interop/Win32_FDAPI.h b/src/Win32_Interop/Win32_FDAPI.h index 34b37515..87017375 100644 --- a/src/Win32_Interop/Win32_FDAPI.h +++ b/src/Win32_Interop/Win32_FDAPI.h @@ -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 #include #include -// 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 diff --git a/src/Win32_Interop/Win32_Interop.vcxproj b/src/Win32_Interop/Win32_Interop.vcxproj index 77968e72..d1bc08b4 100644 --- a/src/Win32_Interop/Win32_Interop.vcxproj +++ b/src/Win32_Interop/Win32_Interop.vcxproj @@ -21,6 +21,7 @@ + @@ -35,6 +36,7 @@ + @@ -42,6 +44,7 @@ + @@ -58,6 +61,7 @@ + diff --git a/src/Win32_Interop/Win32_PThread.c b/src/Win32_Interop/Win32_PThread.c index 2a5005e1..36fa426e 100644 --- a/src/Win32_Interop/Win32_PThread.c +++ b/src/Win32_Interop/Win32_PThread.c @@ -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(); diff --git a/src/Win32_Interop/Win32_PThread.h b/src/Win32_Interop/Win32_PThread.h index 8bf557ab..e7c3669b 100644 --- a/src/Win32_Interop/Win32_PThread.h +++ b/src/Win32_Interop/Win32_PThread.h @@ -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 diff --git a/src/Win32_Interop/Win32_QFork.cpp b/src/Win32_Interop/Win32_QFork.cpp index cad4ea8a..5d3d20e1 100644 --- a/src/Win32_Interop/Win32_QFork.cpp +++ b/src/Win32_Interop/Win32_QFork.cpp @@ -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); diff --git a/src/Win32_Interop/Win32_RedisLog.c b/src/Win32_Interop/Win32_RedisLog.c index 9778cf6a..c698b3ce 100644 --- a/src/Win32_Interop/Win32_RedisLog.c +++ b/src/Win32_Interop/Win32_RedisLog.c @@ -30,7 +30,7 @@ #include "../redis.h" #include "Win32Fixes.h" #include "Win32_EventLog.h" -#include +#include "Win32_Time.h" #include 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; diff --git a/src/Win32_Interop/Win32_Time.c b/src/Win32_Interop/Win32_Time.c new file mode 100644 index 00000000..9256d50b --- /dev/null +++ b/src/Win32_Interop/Win32_Time.c @@ -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 +#include +#include +#include + +#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; +} \ No newline at end of file diff --git a/src/Win32_Interop/Win32_Time.h b/src/Win32_Interop/Win32_Time.h new file mode 100644 index 00000000..d7316f09 --- /dev/null +++ b/src/Win32_Interop/Win32_Time.h @@ -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 + +#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 diff --git a/src/Win32_Interop/Win32_fdapi_crt.h b/src/Win32_Interop/Win32_fdapi_crt.h index a750819e..0e941f93 100644 --- a/src/Win32_Interop/Win32_fdapi_crt.h +++ b/src/Win32_Interop/Win32_fdapi_crt.h @@ -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 #include - 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); diff --git a/src/Win32_Interop/win32_rfdmap.cpp b/src/Win32_Interop/win32_rfdmap.cpp index a97c9832..793096ae 100644 --- a/src/Win32_Interop/win32_rfdmap.cpp +++ b/src/Win32_Interop/win32_rfdmap.cpp @@ -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::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; } diff --git a/src/Win32_Interop/win32_rfdmap.h b/src/Win32_Interop/win32_rfdmap.h index 4aba4196..031e2b79 100644 --- a/src/Win32_Interop/win32_rfdmap.h +++ b/src/Win32_Interop/win32_rfdmap.h @@ -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 SocketToRFDMapType; -typedef map PosixFDToRFDMapType; -typedef map RFDToSocketInfoMapType; -typedef map RFDToPosixFDMapType; -typedef queue 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 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 SocketToRFDMap; + map CrtFDToRFDMap; + map RFDToSocketInfoMap; + map RFDToCrtFDMap; + queue 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); }; diff --git a/src/Win32_Interop/win32_wsiocp.c b/src/Win32_Interop/win32_wsiocp.c index 433dfb47..6f20406a 100644 --- a/src/Win32_Interop/win32_wsiocp.c +++ b/src/Win32_Interop/win32_wsiocp.c @@ -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; diff --git a/src/Win32_Interop/win32fixes.c b/src/Win32_Interop/win32fixes.c index 20344159..20de6675 100644 --- a/src/Win32_Interop/win32fixes.c +++ b/src/Win32_Interop/win32fixes.c @@ -9,13 +9,7 @@ #include #include #include "win32fixes.h" -#include -#include #include -#include -#include -#include -#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; - } -} diff --git a/src/Win32_Interop/win32fixes.h b/src/Win32_Interop/win32fixes.h index d1e1da7a..b8d10863 100644 --- a/src/Win32_Interop/win32fixes.h +++ b/src/Win32_Interop/win32fixes.h @@ -29,24 +29,13 @@ #include #include #include -#include #include /* _O_BINARY */ #include /* INT_MAX */ #include -#include -#include +#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 #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 */ diff --git a/src/ae.c b/src/ae.c index 4a9982fc..74f7505e 100644 --- a/src/ae.c +++ b/src/ae.c @@ -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; diff --git a/src/ae_wsiocp.c b/src/ae_wsiocp.c index 2daa20de..778c8a53 100644 --- a/src/ae_wsiocp.c +++ b/src/ae_wsiocp.c @@ -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--; diff --git a/src/anet.c b/src/anet.c index bb19621b..b5a9f972 100644 --- a/src/anet.c +++ b/src/anet.c @@ -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; diff --git a/src/bio.c b/src/bio.c index 156ee3de..87d45eb2 100644 --- a/src/bio.c +++ b/src/bio.c @@ -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()."); } diff --git a/src/bitops.c b/src/bitops.c index 69e4131d..4228a1e8 100644 --- a/src/bitops.c +++ b/src/bitops.c @@ -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 diff --git a/src/cluster.c b/src/cluster.c index 6587fafb..0d8eb072 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -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) { diff --git a/src/db.c b/src/db.c index a735ce9c..7148a628 100644 --- a/src/db.c +++ b/src/db.c @@ -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; diff --git a/src/dict.c b/src/dict.c index 242f9e44..98ce5eb2 100644 --- a/src/dict.c +++ b/src/dict.c @@ -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. */ diff --git a/src/redis-benchmark.c b/src/redis-benchmark.c index 6c84e92c..6ac5448e 100644 --- a/src/redis-benchmark.c +++ b/src/redis-benchmark.c @@ -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" diff --git a/src/redis-check-dump.c b/src/redis-check-dump.c index 591d5dcd..cb3cb423 100644 --- a/src/redis-check-dump.c +++ b/src/redis-check-dump.c @@ -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; } diff --git a/src/redis-cli.c b/src/redis-cli.c index cb662929..a0842ef8 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -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 diff --git a/src/redis.c b/src/redis.c index b23ad2da..7fb95520 100644 --- a/src/redis.c +++ b/src/redis.c @@ -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" diff --git a/src/redis.h b/src/redis.h index ad2d853b..4b97ce71 100644 --- a/src/redis.h +++ b/src/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" diff --git a/src/replication.c b/src/replication.c index 9ed30eed..6a65fb01 100644 --- a/src/replication.c +++ b/src/replication.c @@ -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" diff --git a/src/sds.c b/src/sds.c index 2db8b14b..6086688f 100644 --- a/src/sds.c +++ b/src/sds.c @@ -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; diff --git a/src/sentinel.c b/src/sentinel.c index 04894ede..37a5817c 100644 --- a/src/sentinel.c +++ b/src/sentinel.c @@ -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) { diff --git a/src/sort.c b/src/sort.c index c981bf1e..34dfcbbf 100644 --- a/src/sort.c +++ b/src/sort.c @@ -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; diff --git a/src/t_hash.c b/src/t_hash.c index 5487b226..36a235de 100644 --- a/src/t_hash.c +++ b/src/t_hash.c @@ -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); diff --git a/src/t_list.c b/src/t_list.c index ba7300cb..bb76b717 100644 --- a/src/t_list.c +++ b/src/t_list.c @@ -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++) { diff --git a/src/t_set.c b/src/t_set.c index c6a00fd8..109944dd 100644 --- a/src/t_set.c +++ b/src/t_set.c @@ -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) { diff --git a/src/t_zset.c b/src/t_zset.c index e83a2ce3..d98f0418 100644 --- a/src/t_zset.c +++ b/src/t_zset.c @@ -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 { diff --git a/src/util.c b/src/util.c index 8f16b926..fbbca0b2 100644 --- a/src/util.c +++ b/src/util.c @@ -30,6 +30,7 @@ #ifdef _WIN32 #include "win32_Interop/win32_util.h" #include "win32_Interop/win32fixes.h" +#include "win32_Interop/win32_time.h" #include // for getcwd #include // for PathIsRelative #endif