Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10a978f7b4 | ||
|
|
ef8807bdc9 | ||
|
|
2388de8062 | ||
|
|
4d3b8f4f76 |
@@ -58,4 +58,6 @@ To run the Redis test suite some manual work is required:
|
||||
following error message: "couldn't execute "cat": no such file or directory".
|
||||
- By default the test suite launches 16 parallel tests, but 2 is the suggested number.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
MSOpenTech Redis on Windows 3.0 Release Notes
|
||||
=============================================
|
||||
--[ Redis on Windows 3.0.504 ] Release date: Jul 01 2016
|
||||
|
||||
- [Fix] Use overlapped sockets for cluster failover communication.
|
||||
- [Portability] strtol and strtoul fixes.
|
||||
- [Docs] Added Microsoft Open Source Code of Conduct.
|
||||
|
||||
--[ Redis on Windows 3.0.503 ] Release date: Jun 21 2016
|
||||
|
||||
- [Fix] Possible AV during background save.
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
version: 3.0.503.{build}
|
||||
version: 3.0.504.{build}
|
||||
|
||||
branches:
|
||||
# whitelist
|
||||
|
||||
Vendored
+1
-1
@@ -648,7 +648,7 @@ static char *nextArgument(char *start, char **str, size_t *len) {
|
||||
if (p == NULL) return NULL;
|
||||
}
|
||||
|
||||
*len = (int)PORT_STRTOL(p+1,NULL,10);
|
||||
*len = (int)strtol(p+1,NULL,10);
|
||||
p = strchr(p,'\r');
|
||||
assert(p);
|
||||
*str = p+2;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<Product Id="*"
|
||||
Name="Redis on Windows"
|
||||
Language="1033"
|
||||
Version="3.0.503"
|
||||
Version="3.0.504"
|
||||
Manufacturer="MSOpenTech"
|
||||
UpgradeCode="{05410198-7212-4FC4-B7C8-AFEFC3DA0FBC}">
|
||||
<Package InstallerVersion="200"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<metadata>
|
||||
<id>redis-64</id>
|
||||
<title>Redis 64-bit</title>
|
||||
<version>3.0.503</version>
|
||||
<version>3.0.504</version>
|
||||
<authors>Alexis Campailla, Enrico Giordani, Jonathan Pickett</authors>
|
||||
<owners>Microsoft Open Technologies, Inc.</owners>
|
||||
<description>A porting of Redis on Windows 64-bit.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<metadata>
|
||||
<id>redis-64</id>
|
||||
<title>Redis 64-bit</title>
|
||||
<version>3.0.503</version>
|
||||
<version>3.0.504</version>
|
||||
<authors>Alexis Campailla, Enrico Giordani, Jonathan Pickett</authors>
|
||||
<owners>Microsoft Open Technologies, Inc.</owners>
|
||||
<description>A porting of Redis on Windows 64-bit.
|
||||
|
||||
@@ -34,6 +34,11 @@
|
||||
#define strcasecmp _stricmp
|
||||
#define strtoll _strtoi64
|
||||
|
||||
#ifdef _WIN64
|
||||
#define strtol _strtoi64
|
||||
#define strtoul _strtoui64
|
||||
#endif
|
||||
|
||||
#define sleep(x) Sleep((x)*1000)
|
||||
/* Redis calls usleep(1) to give thread some time.
|
||||
* Sleep(0) should do the same on Windows.
|
||||
|
||||
@@ -70,10 +70,4 @@ typedef int pid_t;
|
||||
typedef unsigned __int32 u_int32_t;
|
||||
#endif
|
||||
|
||||
#ifdef _WIN64
|
||||
#define PORT_STRTOL strtoll
|
||||
#else
|
||||
#define PORT_STRTOL strtol
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -674,7 +674,7 @@ int loadAppendOnlyFile(char *filename) {
|
||||
goto readerr;
|
||||
}
|
||||
if (buf[0] != '$') goto fmterr;
|
||||
len = PORT_STRTOL(buf+1,NULL,10);
|
||||
len = strtol(buf+1,NULL,10);
|
||||
argsds = sdsnewlen(NULL,len);
|
||||
if (len && fread(argsds,len,1,fp) == 0) {
|
||||
sdsfree(argsds);
|
||||
|
||||
+54
-7
@@ -42,6 +42,8 @@ POSIX_ONLY(#include <sys/socket.h>)
|
||||
POSIX_ONLY(#include <sys/file.h>)
|
||||
#include <math.h>
|
||||
|
||||
WIN32_ONLY(extern int WSIOCP_QueueAccept(int listenfd);)
|
||||
|
||||
/* A global reference to myself is handy to make code more clear.
|
||||
* Myself always points to server.cluster->myself, that is, the clusterNode
|
||||
* that represents this node. */
|
||||
@@ -598,7 +600,10 @@ void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||
|
||||
/* If the server is starting up, don't accept cluster connections:
|
||||
* UPDATE messages may interact with the database content. */
|
||||
if (server.masterhost == NULL && server.loading) return;
|
||||
if (server.masterhost == NULL && server.loading) {
|
||||
WIN32_ONLY(WSIOCP_QueueAccept(fd);)
|
||||
return;
|
||||
}
|
||||
|
||||
while(max--) {
|
||||
cfd = anetTcpAccept(server.neterr, fd, cip, sizeof(cip), &cport);
|
||||
@@ -606,6 +611,12 @@ void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||
if (errno != EWOULDBLOCK)
|
||||
redisLog(REDIS_VERBOSE,
|
||||
"Error accepting cluster node: %s", server.neterr);
|
||||
#ifdef _WIN32
|
||||
if (WSIOCP_QueueAccept(fd) == -1) {
|
||||
redisLog(REDIS_WARNING,
|
||||
"acceptTcpHandler: failed to queue another accept.");
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
anetNonBlock(NULL,cfd);
|
||||
@@ -1994,6 +2005,42 @@ void handleLinkIOError(clusterLink *link) {
|
||||
freeClusterLink(link);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void clusterWriteDone(aeEventLoop *el, int fd, void *privdata, int written) {
|
||||
WSIOCP_Request *req = (WSIOCP_Request *) privdata;
|
||||
clusterLink *link = (clusterLink *) req->client;
|
||||
REDIS_NOTUSED(el);
|
||||
REDIS_NOTUSED(fd);
|
||||
|
||||
if (sdslen(link->sndbuf) == written) {
|
||||
sdsrange(link->sndbuf, written, -1);
|
||||
aeDeleteFileEvent(server.el, link->fd, AE_WRITABLE);
|
||||
redisLog(REDIS_WARNING, "clusterWriteDone written %d fd %d", written, link->fd);
|
||||
}
|
||||
}
|
||||
|
||||
void clusterWriteHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||
clusterLink *link = (clusterLink*) privdata;
|
||||
REDIS_NOTUSED(el);
|
||||
REDIS_NOTUSED(mask);
|
||||
|
||||
int result = WSIOCP_SocketSend(fd,
|
||||
(char*) link->sndbuf,
|
||||
(int) (sdslen(link->sndbuf)),
|
||||
el,
|
||||
link,
|
||||
NULL,
|
||||
clusterWriteDone);
|
||||
if (errno == WSA_IO_PENDING)
|
||||
redisLog(REDIS_WARNING, "WSA_IO_PENDING writing to socket fd %d", link->fd);
|
||||
|
||||
if (result == SOCKET_ERROR && errno != WSA_IO_PENDING) {
|
||||
redisLog(REDIS_WARNING, "Error writing to socket fd", link->fd);
|
||||
handleLinkIOError(link);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Send data. This is handled using a trivial send buffer that gets
|
||||
* consumed by write(). We don't try to optimize this for speed too much
|
||||
* as this is a very low traffic channel. */
|
||||
@@ -2010,10 +2057,11 @@ void clusterWriteHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||
handleLinkIOError(link);
|
||||
return;
|
||||
}
|
||||
sdsrange(link->sndbuf,(int)nwritten,-1); WIN_PORT_FIX /* cast (int) */
|
||||
sdsrange(link->sndbuf,nwritten,-1);
|
||||
if (sdslen(link->sndbuf) == 0)
|
||||
aeDeleteFileEvent(server.el, link->fd, AE_WRITABLE);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Read data. Try to read the first field of the header first to check the
|
||||
* full length of the packet. When a whole packet is in memory this function
|
||||
@@ -2046,7 +2094,7 @@ void clusterReadHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||
"Bad message length or signature received "
|
||||
"from Cluster bus.");
|
||||
handleLinkIOError(link);
|
||||
IF_WIN32(goto done,return);
|
||||
return;
|
||||
}
|
||||
}
|
||||
readlen = ntohl(hdr->totlen) - rcvbuflen;
|
||||
@@ -2054,14 +2102,14 @@ void clusterReadHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||
}
|
||||
|
||||
nread = read(fd,buf,readlen);
|
||||
if (nread == -1 && errno == EAGAIN) IF_WIN32(goto done, return); /* No more data ready. */
|
||||
if (nread == -1 && errno == EAGAIN) { WIN32_ONLY(WSIOCP_QueueNextRead(fd);) return; } /* No more data ready. */
|
||||
|
||||
if (nread <= 0) {
|
||||
/* I/O error... */
|
||||
redisLog(REDIS_DEBUG,"I/O error reading from node link: %s",
|
||||
(nread == 0) ? "connection closed" : strerror(errno));
|
||||
handleLinkIOError(link);
|
||||
IF_WIN32(goto done, return);
|
||||
return;
|
||||
} else {
|
||||
/* Read data and recast the pointer to the new buffer. */
|
||||
link->rcvbuf = sdscatlen(link->rcvbuf,buf,nread);
|
||||
@@ -2075,11 +2123,10 @@ void clusterReadHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||
sdsfree(link->rcvbuf);
|
||||
link->rcvbuf = sdsempty();
|
||||
} else {
|
||||
IF_WIN32(goto done, return); /* Link no longer valid. */
|
||||
return; /* Link no longer valid. */
|
||||
}
|
||||
}
|
||||
}
|
||||
WIN32_ONLY(done:)
|
||||
WIN32_ONLY(WSIOCP_QueueNextRead(fd);)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -153,7 +153,7 @@ void loadServerConfigFromString(char *config) {
|
||||
server.unixsocket = zstrdup(argv[1]);
|
||||
} else if (!strcasecmp(argv[0],"unixsocketperm") && argc == 2) {
|
||||
errno = 0;
|
||||
server.unixsocketperm = (mode_t)PORT_STRTOL(argv[1], NULL, 8);
|
||||
server.unixsocketperm = (mode_t)strtol(argv[1], NULL, 8);
|
||||
if (errno || server.unixsocketperm > 0777) {
|
||||
err = "Invalid socket file permissions"; goto loaderr;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ int readLong(FILE *fp, char prefix, PORT_LONG *target) {
|
||||
ERROR("Expected prefix '%c', got: '%c'",buf[0],prefix);
|
||||
return 0;
|
||||
}
|
||||
*target = PORT_STRTOL(buf+1,&eptr,10);
|
||||
*target = strtol(buf+1,&eptr,10);
|
||||
return consumeNewline(eptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -225,7 +225,7 @@ int processHeader(void) {
|
||||
ERROR("Wrong signature in header\n");
|
||||
}
|
||||
|
||||
dump_version = (int)PORT_STRTOL(buf + 5, NULL, 10);
|
||||
dump_version = (int) strtol(buf + 5, NULL, 10);
|
||||
if (dump_version < 1 || dump_version > 6) {
|
||||
ERROR("Unknown RDB format version: %d\n", dump_version);
|
||||
}
|
||||
|
||||
+1
-1
@@ -1909,7 +1909,7 @@ static PORT_LONG getLongInfoField(char *info, char *field) {
|
||||
PORT_LONG l;
|
||||
|
||||
if (!value) return PORT_LONG_MIN;
|
||||
l = PORT_STRTOL(value, NULL, 10);
|
||||
l = strtol(value,NULL,10);
|
||||
free(value);
|
||||
return l;
|
||||
}
|
||||
|
||||
+3
-3
@@ -2720,7 +2720,7 @@ sds genRedisInfoString(char *section) {
|
||||
"config_file:%s\r\n",
|
||||
REDIS_VERSION,
|
||||
redisGitSHA1(),
|
||||
PORT_STRTOL(redisGitDirty(),NULL,10) > 0,
|
||||
strtol(redisGitDirty(),NULL,10) > 0,
|
||||
(PORT_ULONGLONG) redisBuildId(),
|
||||
mode,
|
||||
#ifdef _WIN32
|
||||
@@ -3521,7 +3521,7 @@ void redisAsciiArt(void) {
|
||||
"Redis %s (%s/%d) %s bit, %s mode, port %d, pid %ld ready to start.",
|
||||
REDIS_VERSION,
|
||||
redisGitSHA1(),
|
||||
PORT_STRTOL(redisGitDirty(),NULL,10) > 0,
|
||||
strtol(redisGitDirty(),NULL,10) > 0,
|
||||
(sizeof(PORT_LONG) == 8) ? "64" : "32",
|
||||
mode, server.port,
|
||||
(PORT_LONG) getpid()
|
||||
@@ -3530,7 +3530,7 @@ void redisAsciiArt(void) {
|
||||
snprintf(buf,1024*16,ascii_logo,
|
||||
REDIS_VERSION,
|
||||
redisGitSHA1(),
|
||||
PORT_STRTOL(redisGitDirty(),NULL,10) > 0,
|
||||
strtol(redisGitDirty(),NULL,10) > 0,
|
||||
(sizeof(PORT_LONG) == 8) ? "64" : "32",
|
||||
mode, server.port,
|
||||
(PORT_LONG) getpid()
|
||||
|
||||
+1
-1
@@ -1125,7 +1125,7 @@ void readSyncBulkPayload(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||
"MASTER <-> SLAVE sync: receiving streamed RDB from master");
|
||||
} else {
|
||||
usemark = 0;
|
||||
server.repl_transfer_size = PORT_STRTOL(buf+1,NULL,10);
|
||||
server.repl_transfer_size = strtol(buf+1,NULL,10);
|
||||
redisLog(REDIS_NOTICE,
|
||||
"MASTER <-> SLAVE sync: receiving %lld bytes from master",
|
||||
(PORT_LONGLONG) server.repl_transfer_size);
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
#define REDIS_VERSION "3.0.503"
|
||||
#define REDIS_VERSION "3.0.504"
|
||||
|
||||
+1
-1
@@ -378,7 +378,7 @@ size_t zmalloc_get_smap_bytes_by_field(char *field) {
|
||||
char *p = strchr(line,'k');
|
||||
if (p) {
|
||||
*p = '\0';
|
||||
bytes += PORT_STRTOL(line+flen,NULL,10) * 1024;
|
||||
bytes += strtol(line+flen,NULL,10) * 1024;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user