diff --git a/deps/hiredis/hiredis.c b/deps/hiredis/hiredis.c
index ae73a78e..49dd807d 100644
--- a/deps/hiredis/hiredis.c
+++ b/deps/hiredis/hiredis.c
@@ -44,6 +44,7 @@
#include "sds.h"
#ifdef _WIN32
#include "../../src/win32fixes.h"
+ #include "../../src/win32_socketmap.h"
#endif
static redisReply *createReplyObject(int type);
@@ -1025,6 +1026,7 @@ void redisFree(redisContext *c) {
if (c->fd > 0)
#ifdef _WIN32
closesocket(c->fd);
+ smRemoveSocket(c->fd);
#else
close(c->fd);
#endif
diff --git a/deps/hiredis/net.c b/deps/hiredis/net.c
index 028d9d13..81cdad98 100644
--- a/deps/hiredis/net.c
+++ b/deps/hiredis/net.c
@@ -60,6 +60,7 @@
#include "sds.h"
#ifdef _WIN32
#include "../../src/win32fixes.h"
+ #include "../../src/win32_socketmap.h"
#endif
/* Defined in hiredis.c */
@@ -104,6 +105,7 @@ static int redisCreateSocket(redisContext *c, int type) {
if (setsockopt((int)s, SOL_SOCKET, SO_REUSEADDR, (const char *) &on, sizeof(on)) == -1) {
__redisSetError(c,REDIS_ERR_IO,NULL);
closesocket(s);
+ smRemoveSocket(s);
return REDIS_ERR;
}
}
@@ -143,6 +145,7 @@ static int redisSetBlocking(redisContext *c, int fd, int blocking) {
__redisSetError(c,REDIS_ERR_IO,
sdscatprintf(sdsempty(), "ioctlsocket(FIONBIO): %d\n", errno));
closesocket(fd);
+ smRemoveSocket(fd);
return REDIS_ERR;
};
@@ -183,6 +186,7 @@ static int redisSetTcpNoDelay(redisContext *c, int fd) {
__redisSetError(c,REDIS_ERR_IO,
sdscatprintf(sdsempty(), "setsockopt(TCP_NODELAY): %d", (int)GetLastError()));
closesocket(fd);
+ smRemoveSocket(fd);
return REDIS_ERR;
}
return REDIS_OK;
@@ -218,6 +222,7 @@ static int redisContextWaitReady(redisContext *c, int fd, const struct timeval *
if (select(FD_SETSIZE, NULL, &wfd, NULL, toptr) == -1) {
__redisSetErrorFromErrno(c,REDIS_ERR_IO,"select(2)");
closesocket(fd);
+ smRemoveSocket(fd);
return REDIS_ERR;
}
@@ -225,6 +230,7 @@ static int redisContextWaitReady(redisContext *c, int fd, const struct timeval *
errno = WSAGetLastError();
__redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
closesocket(fd);
+ smRemoveSocket(fd);
return REDIS_ERR;
}
@@ -236,6 +242,7 @@ static int redisContextWaitReady(redisContext *c, int fd, const struct timeval *
__redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
closesocket(fd);
+ smRemoveSocket(fd);
return REDIS_ERR;
}
#else
@@ -298,6 +305,7 @@ int redisCheckSocketError(redisContext *c, int fd) {
errno = WSAGetLastError();
__redisSetErrorFromErrno(c,REDIS_ERR_IO,"getsockopt(SO_ERROR)");
closesocket(fd);
+ smRemoveSocket(fd);
return REDIS_ERR;
}
#else
@@ -374,6 +382,7 @@ int redisContextPreConnectTcp(redisContext *c, const char *addr, int port,
__redisSetError(c,REDIS_ERR_OTHER,
sdscatprintf(sdsempty(),"can't resolve: %s\n", addr));
closesocket(s);
+ smRemoveSocket(s);
return REDIS_ERR;
}
memcpy(&sa->sin_addr, he->h_addr, sizeof(struct in_addr));
@@ -415,6 +424,7 @@ int redisContextConnectTcp(redisContext *c, const char *addr, int port, struct t
__redisSetError(c,REDIS_ERR_OTHER,
sdscatprintf(sdsempty(),"can't resolve: %s\n", addr));
closesocket(s);
+ smRemoveSocket(s);
return REDIS_ERR;
}
memcpy(&sa.sin_addr, he->h_addr, sizeof(struct in_addr));
diff --git a/msvs/RedisBenchmark/RedisBenchmark.vcxproj b/msvs/RedisBenchmark/RedisBenchmark.vcxproj
index 263bc8a2..00e5e10c 100644
--- a/msvs/RedisBenchmark/RedisBenchmark.vcxproj
+++ b/msvs/RedisBenchmark/RedisBenchmark.vcxproj
@@ -167,8 +167,10 @@
+
+
diff --git a/msvs/RedisLog.h b/msvs/RedisLog.h
new file mode 100644
index 00000000..13ba4f7f
--- /dev/null
+++ b/msvs/RedisLog.h
@@ -0,0 +1,37 @@
+/*
+ * 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
+
+/* Log levels */
+#define REDIS_DEBUG 0
+#define REDIS_VERBOSE 1
+#define REDIS_NOTICE 2
+#define REDIS_WARNING 3
+#define REDIS_LOG_RAW (1<<10) /* Modifier to log without timestamp */
+
+#define REDIS_MAX_LOGMSG_LEN 1024 /* Default maximum length of syslog messages */
+
+void redisLog(int level, const char *fmt, ...);
+void redisLogRaw(int level, const char *msg);
+void redisLogFromHandler(int level, const char *msg);
+
+void SetVerbosity(int verbosity);
\ No newline at end of file
diff --git a/msvs/RedisServer.sln b/msvs/RedisServer.sln
index af1fa3f3..46742399 100644
--- a/msvs/RedisServer.sln
+++ b/msvs/RedisServer.sln
@@ -2,6 +2,9 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RedisServer", "RedisServer.vcxproj", "{46842776-68A5-EC98-6A09-1859BBFC73AA}"
+ ProjectSection(ProjectDependencies) = postProject
+ {170B0909-5F75-467F-9501-C99DEC16C6DC} = {170B0909-5F75-467F-9501-C99DEC16C6DC}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hiredis", "hiredis\hiredis.vcxproj", "{13E85053-54B3-487B-8DDB-3430B1C1B3BF}"
EndProject
diff --git a/msvs/RedisServer.vcxproj b/msvs/RedisServer.vcxproj
index 3750804d..8450400c 100644
--- a/msvs/RedisServer.vcxproj
+++ b/msvs/RedisServer.vcxproj
@@ -177,6 +177,7 @@
+
@@ -196,6 +197,7 @@
+
@@ -218,6 +220,7 @@
+
@@ -229,6 +232,7 @@
+
diff --git a/msvs/hiredis/hiredis.vcxproj b/msvs/hiredis/hiredis.vcxproj
index 00278ee5..88e7973b 100644
--- a/msvs/hiredis/hiredis.vcxproj
+++ b/msvs/hiredis/hiredis.vcxproj
@@ -151,6 +151,8 @@
+
+
diff --git a/src/RedisLog.c b/src/RedisLog.c
new file mode 100644
index 00000000..9109e940
--- /dev/null
+++ b/src/RedisLog.c
@@ -0,0 +1,116 @@
+/*
+ * 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 "redisLog.h"
+#include
+#include
+#include
+#include
+#include
+#include "win32Fixes.h"
+#include
+
+
+static int verbosity = REDIS_WARNING;
+static char* logFile = NULL;
+
+void setLogVerbosityLevel(int level)
+{
+ verbosity = level;
+}
+
+void setLogFile(const char* logFileName)
+{
+ if (logFile != NULL) {
+ free((void*)logFile);
+ logFile = NULL;
+ }
+ logFile = (char*)malloc(strlen(logFile));
+ if (logFile==NULL) {
+ redisLog(REDIS_WARNING, "memory allocation failure");
+ return;
+ }
+ strcpy (logFile,logFileName);
+}
+
+void redisLogRaw(int level, const char *msg) {
+#ifndef _WIN32
+ const int syslogLevelMap[] = { LOG_DEBUG, LOG_INFO, LOG_NOTICE, LOG_WARNING };
+#endif
+ const char *c = ".-*#";
+ FILE *fp;
+ char buf[64];
+ int rawmode = (level & REDIS_LOG_RAW);
+
+ level &= 0xff; /* clear flags */
+ if (level < verbosity) return;
+
+ fp = (logFile == NULL) ? stdout : fopen(logFile,"a");
+ if (!fp) return;
+
+ if (rawmode) {
+ fprintf(fp,"%s",msg);
+ } else {
+ int off;
+#ifdef _WIN32
+ time_t secs;
+ unsigned int usecs;
+ struct tm * now ;
+
+ secs = gettimeofdaysecs(&usecs);
+ now = localtime(&secs);
+ off = (int)strftime(buf,sizeof(buf),"%d %b %H:%M:%S.",now);
+ snprintf(buf+off,sizeof(buf)-off,"%03d",usecs/1000);
+#else
+ struct timeval tv;
+
+ gettimeofday(&tv,NULL);
+ off = strftime(buf,sizeof(buf),"%d %b %H:%M:%S.",localtime(&tv.tv_sec));
+ snprintf(buf+off,sizeof(buf)-off,"%03d",(int)tv.tv_usec/1000);
+#endif
+ fprintf(fp,"[%d] %s %c %s\n",(int)getpid(),buf,c[level],msg);
+ }
+ fflush(fp);
+
+ if (logFile) fclose(fp);
+#ifndef _WIN32
+ if (server.syslog_enabled) syslog(syslogLevelMap[level], "%s", msg);
+#endif
+}
+
+
+/* Like redisLogRaw() but with printf-alike support. This is the function that
+ * is used across the code. The raw version is only used in order to dump
+ * the INFO output on crash. */
+void redisLog(int level, const char *fmt, ...) {
+ va_list ap;
+ char msg[REDIS_MAX_LOGMSG_LEN];
+
+ if ((level&0xff) < verbosity) return;
+
+ va_start(ap, fmt);
+ vsnprintf(msg, sizeof(msg), fmt, ap);
+ va_end(ap);
+
+ redisLogRaw(level,msg);
+}
diff --git a/src/ae.c b/src/ae.c
index ca22b58f..d5a8c039 100644
--- a/src/ae.c
+++ b/src/ae.c
@@ -36,6 +36,8 @@
#include
#include
#include
+#else
+#include "win32_socketmap.h"
#endif
#include
#include
@@ -46,6 +48,8 @@
#include "zmalloc.h"
#include "config.h"
+
+
/* Include the best multiplexing layer supported by this system.
* The following should be ordered by performances, descending. */
#ifdef _WIN32
@@ -112,11 +116,26 @@ int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,
aeFileProc *proc, void *clientData)
{
aeFileEvent *fe;
+
+
+#ifdef _WIN32
+ if (smGetSocketCount() >= eventLoop->setsize) {
+ errno = ERANGE;
+ return AE_ERR;
+ }
+
+ if(smLookupFD(fd) == -1 ) {
+ errno = ERANGE;
+ return AE_ERR;
+ }
+ fe = &eventLoop->events[smLookupFD(fd)];
+#else
if (fd >= eventLoop->setsize) {
errno = ERANGE;
return AE_ERR;
}
fe = &eventLoop->events[fd];
+#endif
if (aeApiAddEvent(eventLoop, fd, mask) == -1)
return AE_ERR;
@@ -132,8 +151,17 @@ int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,
void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask)
{
aeFileEvent *fe;
+#ifdef _WIN32
+ if (smGetSocketCount() >= eventLoop->setsize) return;
+
+ if(smLookupFD(fd) == -1 ) return;
+
+ fe = &eventLoop->events[smLookupFD(fd)];
+#else
if (fd >= eventLoop->setsize) return;
+
fe = &eventLoop->events[fd];
+#endif
if (fe->mask == AE_NONE) return;
fe->mask = fe->mask & (~mask);
@@ -150,8 +178,17 @@ void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask)
int aeGetFileEvents(aeEventLoop *eventLoop, int fd) {
aeFileEvent *fe;
+#ifdef _WIN32
+ if(smLookupFD(fd) == -1 ) DebugBreak();
+
+ if (smGetSocketCount() >= eventLoop->setsize) return 0;
+
+ fe = &eventLoop->events[smLookupFD(fd)];
+#else
if (fd >= eventLoop->setsize) return 0;
+
fe = &eventLoop->events[fd];
+#endif
return fe->mask;
}
@@ -382,11 +419,24 @@ int aeProcessEvents(aeEventLoop *eventLoop, int flags)
numevents = aeApiPoll(eventLoop, tvp);
for (j = 0; j < numevents; j++) {
- aeFileEvent *fe = &eventLoop->events[eventLoop->fired[j].fd];
+ aeFileEvent *fe;
int mask = eventLoop->fired[j].mask;
int fd = eventLoop->fired[j].fd;
int rfired = 0;
+#ifdef _WIN32
+ if(smLookupFD(eventLoop->fired[j].fd) == -1 ) {
+ // We may have already processed a socket close request
+ // before a subscription notification gets sent out
+ processed++;
+ continue;
+ }
+
+ fe = &eventLoop->events[smLookupFD(eventLoop->fired[j].fd)];
+#else
+ fe = &eventLoop->events[eventLoop->fired[j].fd];
+#endif
+
/* note the fe->mask & mask & ... code: maybe an already processed
* event removed an element that fired and we still didn't
* processed, so we check if the event is still valid. */
diff --git a/src/anet.c b/src/anet.c
index 90bb9235..a3bb2e47 100644
--- a/src/anet.c
+++ b/src/anet.c
@@ -49,6 +49,7 @@
#ifdef _WIN32
#include "win32fixes.h"
#define ANET_NOTUSED(V) ((void) V)
+#include "win32_socketmap.h"
#endif
#include "anet.h"
@@ -245,9 +246,12 @@ static int anetTcpGenericConnect(char *err, char *addr, int port, int flags) {
struct sockaddr_in sa;
unsigned long inAddress;
- if ((s = anetCreateSocket(err,AF_INET)) == ANET_ERR)
+ if ((s = anetCreateSocket(err,AF_INET)) == ANET_ERR) {
return ANET_ERR;
-
+ }
+ else {
+ smAddSocket(s);
+ }
sa.sin_family = AF_INET;
sa.sin_port = htons((u_short)port);
inAddress = inet_addr(addr);
@@ -258,6 +262,7 @@ static int anetTcpGenericConnect(char *err, char *addr, int port, int flags) {
if (he == NULL) {
anetSetError(err, "can't resolve: %s\n", addr);
closesocket(s);
+ smRemoveSocket(s);
return ANET_ERR;
}
memcpy(&sa.sin_addr, he->h_addr, sizeof(struct in_addr));
@@ -274,6 +279,7 @@ static int anetTcpGenericConnect(char *err, char *addr, int port, int flags) {
anetSetError(err, "connect: %d\n", errno);
closesocket(s);
+ smRemoveSocket(s);
return ANET_ERR;
}
@@ -435,12 +441,14 @@ static int anetListen(char *err, int s, struct sockaddr *sa, socklen_t len) {
errno = WSAGetLastError();
anetSetError(err, "bind error: %d\n", errno);
closesocket((SOCKET)s);
+ smRemoveSocket(s);
return ANET_ERR;
}
if (aeWinListen((SOCKET)s, 511) == SOCKET_ERROR) { /* the magic 511 constant is from nginx */
errno = WSAGetLastError();
anetSetError(err, "listen error: %d\n", errno);
closesocket((SOCKET)s);
+ smRemoveSocket(s);
return ANET_ERR;
}
return ANET_OK;
@@ -457,6 +465,8 @@ int anetTcpServer(char *err, int port, char *bindaddr)
if ((s = anetCreateSocket(err,AF_INET)) == ANET_ERR)
return ANET_ERR;
+ smAddSocket(s);
+
/* Override for SO_REUSEADDR for windows server socks */
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == SOCKET_ERROR) {
errno = WSAGetLastError();
diff --git a/src/config.c b/src/config.c
index 97e6f6ae..14de1a1b 100644
--- a/src/config.c
+++ b/src/config.c
@@ -157,6 +157,9 @@ void loadServerConfigFromString(char *config) {
"Can't open the log file: %s", strerror(errno));
goto loaderr;
}
+ else {
+ setLogFile( server.logfile );
+ }
fclose(logfp);
}
} else if (!strcasecmp(argv[0],"syslog-enabled") && argc == 2) {
@@ -688,6 +691,7 @@ void configSetCommand(redisClient *c) {
} else {
goto badfmt;
}
+ setLogVerbosityLevel(server.verbosity);
} else if (!strcasecmp(c->argv[2]->ptr,"client-output-buffer-limit")) {
int vlen, j;
sds *v = sdssplitlen(o->ptr,(int)sdslen(o->ptr)," ",1,&vlen);
diff --git a/src/redis.c b/src/redis.c
index 2bbf6b65..ac8d9cb9 100644
--- a/src/redis.c
+++ b/src/redis.c
@@ -36,6 +36,7 @@
#ifdef _WIN32
#include
#define LOG_LOCAL0 0
+#include "win32_socketmap.h"
#else
#include
#include
@@ -259,67 +260,6 @@ struct redisCommand redisCommandTable[] = {
/*============================ Utility functions ============================ */
-/* Low level logging. To use only for very big messages, otherwise
- * redisLog() is to prefer. */
-void redisLogRaw(int level, const char *msg) {
-#ifndef _WIN32
- const int syslogLevelMap[] = { LOG_DEBUG, LOG_INFO, LOG_NOTICE, LOG_WARNING };
-#endif
- const char *c = ".-*#";
- FILE *fp;
- char buf[64];
- int rawmode = (level & REDIS_LOG_RAW);
-
- level &= 0xff; /* clear flags */
- if (level < server.verbosity) return;
-
- fp = (server.logfile == NULL) ? stdout : fopen(server.logfile,"a");
- if (!fp) return;
-
- if (rawmode) {
- fprintf(fp,"%s",msg);
- } else {
- int off;
-#ifdef _WIN32
- time_t secs;
- unsigned int usecs;
-
- secs = gettimeofdaysecs(&usecs);
- off = (int)strftime(buf,sizeof(buf),"%d %b %H:%M:%S.",localtime(&secs));
- snprintf(buf+off,sizeof(buf)-off,"%03d",usecs/1000);
-#else
- struct timeval tv;
-
- gettimeofday(&tv,NULL);
- off = strftime(buf,sizeof(buf),"%d %b %H:%M:%S.",localtime(&tv.tv_sec));
- snprintf(buf+off,sizeof(buf)-off,"%03d",(int)tv.tv_usec/1000);
-#endif
- fprintf(fp,"[%d] %s %c %s\n",(int)getpid(),buf,c[level],msg);
- }
- fflush(fp);
-
- if (server.logfile) fclose(fp);
-#ifndef _WIN32
- if (server.syslog_enabled) syslog(syslogLevelMap[level], "%s", msg);
-#endif
-}
-
-/* Like redisLogRaw() but with printf-alike support. This is the function that
- * is used across the code. The raw version is only used in order to dump
- * the INFO output on crash. */
-void redisLog(int level, const char *fmt, ...) {
- va_list ap;
- char msg[REDIS_MAX_LOGMSG_LEN];
-
- if ((level&0xff) < server.verbosity) return;
-
- va_start(ap, fmt);
- vsnprintf(msg, sizeof(msg), fmt, ap);
- va_end(ap);
-
- redisLogRaw(level,msg);
-}
-
#ifdef _WIN32
/* Misc Windows house keeping */
void win32Cleanup(void) {
@@ -1214,6 +1154,7 @@ void initServerConfig() {
server.sofd = -1;
server.dbnum = REDIS_DEFAULT_DBNUM;
server.verbosity = REDIS_NOTICE;
+ setLogVerbosityLevel(server.verbosity);
server.maxidletime = REDIS_MAXIDLETIME;
server.tcpkeepalive = 0;
server.active_expire_enabled = 1;
@@ -1918,8 +1859,14 @@ int prepareForShutdown(int flags) {
}
/* Close the listening sockets. Apparently this allows faster restarts. */
#ifdef _WIN32
- if (server.ipfd != -1) closesocket(server.ipfd);
- if (server.sofd != -1) closesocket(server.sofd);
+ if (server.ipfd != -1) {
+ closesocket(server.ipfd);
+ smRemoveSocket(server.ipfd);
+ }
+ if (server.sofd != -1) {
+ closesocket(server.sofd);
+ smRemoveSocket(server.sofd);
+ }
#else
if (server.ipfd != -1) close(server.ipfd);
if (server.sofd != -1) close(server.sofd);
diff --git a/src/redis.h b/src/redis.h
index baccf948..a03a885d 100644
--- a/src/redis.h
+++ b/src/redis.h
@@ -70,6 +70,7 @@
#include "util.h" /* Misc functions useful in many places */
#include "win32_cow.h" /* Windows copy on write */
+#include "redisLog.h" /* moved logging for hiredis and RedisCli usage /*
/* Error codes */
#define REDIS_OK 0
@@ -90,7 +91,6 @@
#define REDIS_SHARED_SELECT_CMDS 10
#define REDIS_SHARED_INTEGERS 10000
#define REDIS_SHARED_BULKHDR_LEN 32
-#define REDIS_MAX_LOGMSG_LEN 1024 /* Default maximum length of syslog messages */
#define REDIS_AOF_REWRITE_PERC 100
#define REDIS_AOF_REWRITE_MIN_SIZE (1024*1024)
#define REDIS_AOF_REWRITE_ITEMS_PER_CMD 64
@@ -244,13 +244,6 @@
#define REDIS_SORT_DESC 2
#define REDIS_SORTKEY_MAX 1024
-/* Log levels */
-#define REDIS_DEBUG 0
-#define REDIS_VERBOSE 1
-#define REDIS_NOTICE 2
-#define REDIS_WARNING 3
-#define REDIS_LOG_RAW (1<<10) /* Modifier to log without timestamp */
-
/* Anti-warning macro... */
#define REDIS_NOTUSED(V) ((void) V)
@@ -1008,9 +1001,6 @@ void call(redisClient *c, int flags);
void propagate(struct redisCommand *cmd, int dbid, robj **argv, int argc, int flags);
void alsoPropagate(struct redisCommand *cmd, int dbid, robj **argv, int argc, int target);
int prepareForShutdown();
-void redisLog(int level, const char *fmt, ...);
-void redisLogRaw(int level, const char *msg);
-void redisLogFromHandler(int level, const char *msg);
void usage();
void updateDictResizePolicy(void);
int htNeedsResize(dict *dict);
diff --git a/src/win32_socketmap.cpp b/src/win32_socketmap.cpp
new file mode 100644
index 00000000..78bd9cd7
--- /dev/null
+++ b/src/win32_socketmap.cpp
@@ -0,0 +1,158 @@
+/*
+ * 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 "win32fixes.h"
+#include "win32_socketmap.h"
+#include