Squashed 2.8 fixes since the 3.0 initial merge.

Squashed commit of the following:

commit ba143668b964885ca1b2cf3af927a49bec0f14a4
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Tue Jul 7 11:53:46 2015 +0200

    [Fix] aeWinQueueAccept wrong return value.

    [Change] Variable name acceptsocket changed to acceptfd.

commit 75f6769fd52fe8215bd1a2149f1bd115078ea278
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Mon Jul 6 17:26:55 2015 +0200

    [Fix] Closing handled before returning.

    [Cleanup] Tabs->spaces.

commit 4f22c9be7dee2f34f2cbf5b8a4fd50b87b443937
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Mon Jul 6 17:15:20 2015 +0200

    [Change] Removed extra space allocated at the end of the mmap file.

    [Log] Improved error messages.

commit f306348c243493b192eaeee9aed404ec065bb60c
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Sat Jul 4 12:08:41 2015 +0200

    [Fix] RFDMap was not thread safe.

    [Cleanup] Removed unused/commented out code, tabs->spaces.

commit 8da060bf484898932f2ecd02c099266eb31d4d80
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Sat Jul 4 12:02:58 2015 +0200

    [Fix] UnhandledExceptiontHandler internal exception handling.

commit 99e5e26fba4b48531cd2a544d5a22d6caba0f681
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Thu Jul 2 08:15:11 2015 +0200

    [Cleanup] Removed unused include.

commit d812c4ed57cdc30cd817ad2e9181f5bf239dc07b
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Wed Jul 1 20:36:13 2015 +0200

    [Cleanup] Removed useless platform definition from RedisServer.sln

commit 0401c167120876ca5533beb0bc6054d6401e8b65
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Wed Jul 1 20:32:51 2015 +0200

    [Cleanup] Changed variable type to match function return value.

    checkForSentinelMode() returns an int, not a bool.

commit 6a9ccd3906d5c007d4683d9caea64da78e5ed668
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Wed Jul 1 20:27:21 2015 +0200

    [Cleanup] Minor change to method signature.

    The method input parameter has been changed to a const.

commit e60f617b543edff46ceebb9362f01619e2188594
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Wed Jul 1 20:16:00 2015 +0200

    [Cleanup] Removed non-existent file from hiredis project.

commit 8d17c3dd052083ec4e47176921337822299167b1
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Wed Jul 1 19:58:59 2015 +0200

    [WinPort] Explicit cast.

commit 426841dc8c454a2afbc44c8f005cb3bf31b20cd5
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Wed Jul 1 17:07:22 2015 +0200

    [Change] Move ReleasePackagingTool to its own solution.

    [Cleanup] Removed unused code in ReleasePackagingTool.
    [Changed] Chocolatey package now imports documents from the same folder where binaries are.

commit 6ed0696c7902d6dc268fd34f55bce95783bc4286
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Wed Jul 1 13:58:58 2015 +0200

    [Fix] Ignore SymInitialize() return value to make sure Stack Trace is logged

    	  when redis-server is running as a Windows service.

commit f5e18675c9046492e7dd5a2593c2f890627a093d
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Tue Jun 30 19:06:59 2015 +0200

    [Change] EventLog.dll excluded from NuGet package.

commit 1ae80857b6fe1b5f352d247376c8fbbd94e81dfc
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Mon Jun 29 16:02:25 2015 +0200

    Updated scripts to create and push the NuGet and Chocolatey packages.

     - [Change] the binaries are now downloaded from the github release.
     - [Change] Redis.nuspec: don't copy the files from the "documentation" folder since the documentation is already included with the binaries.
     - [Fix] PullBinaries.ps1: replaced hardcoded Redis version number with input parameter.
     - [Fix] improved error handling.

commit c8e70630693a4f505177623824dff998602e62b4
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Mon Jun 29 12:21:58 2015 +0200

    Fork code for background processing needed fixes and code refactoring.

     - [Fix] BeginForkOperation_Aof()/_Rdb()/_Socket() and BeginForkOperation() code
             refactoring.
     - [Fix] rewriteAppendOnlyFileBackground() code refactoring to minimize the code
             changes for WIN32.
     - [Fix] rewriteAppendOnlyFileBackground() must update the latency monitor, the
             fork stats and replicationScriptCacheFlush().
     - [Fix] rdbSaveBackground() code refactoring to minimize the code changes for
             WIN32.
     - [Fix] rdbSaveBackground() must update the latency monitor and the fork stats.
     - [Fix] memory leak in rdbSaveToSlavesSockets().
     - [Fix] properly releasing resources in rdbSaveToSlavesSockets().
     - [Fix] QForkChildInit() not setting the operationFailed event in case of
             exception.
     - [Fix] QForkChildInit() AV in catch() statement.

commit f1007fcaad5ceb17d27fcca081b8dbcf8906ee92
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Fri Jun 26 11:54:09 2015 +0200

    [Fix] deleting char** correctly (@zeliard)

commit b8009c220a
Author: Alexis Campailla <alexis@janeasystems.com>
Date:   Wed Jun 24 23:10:27 2015 +0200

    Fix 32-bit build

commit 4f384b9e58
Author: Alexis Campailla <alexis@janeasystems.com>
Date:   Wed Jun 24 21:36:57 2015 +0200

    Update appveyor version

commit b84d390111
Author: Alexis Campailla <alexis@janeasystems.com>
Date:   Wed Jun 24 20:53:17 2015 +0200

    Fix child process handle closing

commit fdbf5328c2
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Wed Jun 24 17:43:54 2015 +0200

    MapViewOfFileEx() error handling, UnhandledExceptiontHandler fixes.

    [log] Improved error message if MapViewOfFileEx() fails.
    [fix] Child process call exist(1) if MapViewOfFileEx() fails.
    [new] GetForkOperationStatus() now detects if the child process is not anymore running.
    [fix] Error reporting in UnhandledExceptiontHandler() for "UNKNOWN EXCEPTION".
    [new] UnhandledExceptiontHandler() now calls the default C++ unhandled exceptiont handler.
    [log] Changed the closing statement of the BUG REPORT.
    [comment] Removed commented out code in Win32_dlmalloc.c.

commit 05b20f0e4b
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Wed Jun 24 13:05:53 2015 +0200

    Change BUG REPORT closing message to point to a different git hub page.

commit 1cb3e84814
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Wed Jun 24 11:59:45 2015 +0200

    ReleasePackagingTool changes:
     [change] the release notes file is not anymore generated from a template
     [change] the .md files are not anymore generated from the .docx files
     [new] added redis-server.pdb symbols to the zip package file
     [fix] create the release package directory if it doesn't exist

commit 8ea708f9e1
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Wed Jun 24 01:21:27 2015 +0200

    New release notes format (similar to Redis on UNIX)

commit e2df601222
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Wed Jun 24 01:16:02 2015 +0200

    Fixed broken link in README.

commit 93d00065e4
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Wed Jun 24 01:12:49 2015 +0200

    Minor update to the README.

commit bd2ee4d2da
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Tue Jun 23 23:40:50 2015 +0200

    Warning message in config files for the maxmemory flag.

commit 2943ec7db6
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Tue Jun 23 21:56:31 2015 +0200

    Cleaned up the UnhandledExceptiontHandler() code.

    Minor changes.

commit b805f2be89
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Tue Jun 23 19:02:03 2015 +0200

    Calling abort() in redisOutOfMemoryHandler().

    Changed out-of-memory error report.

commit 18a653318d
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Tue Jun 23 18:55:53 2015 +0200

    Commented out printf calls in dlmalloc.

commit f01052fb5d
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Tue Jun 23 18:44:32 2015 +0200

    Changed #if defined(_WIN64) to #ifdef _WIN64

    It was causing an appveyor build failure.

commit a4865f06a9
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Tue Jun 23 18:15:20 2015 +0200

    'save' config flag added to the 'incompatibleNoPersistenceCommands' list.

    The fix prevents redis-server from crashing if the 'save' flag is set and
    'persistence-available' is set to 'no'.

commit 3de4f6cb47
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Tue Jun 23 16:54:23 2015 +0200

    Change misleading variables/functions names: master->parent, slave->child.

    Master and Slave labels were using for the Parent and Child processes.

commit 453b582eed
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Tue Jun 23 13:46:45 2015 +0200

    Updated authors and description for nuget and chocolatey.

commit e91c9eeef7
Merge: 5c05765 dc3285a
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Tue Jun 23 13:40:41 2015 +0200

    Merge branch '2.8-enrico' of https://github.com/janeasystems/redis-private into 2.8-enrico

commit dc3285af0b
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Tue Jun 23 11:42:51 2015 +0200

    Update Redis on Windows Release Notes.md

commit 5c05765d9a
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Mon Jun 22 21:23:08 2015 +0200

    Typos in warning message.

commit 510cc9bd3e
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Mon Jun 22 19:57:52 2015 +0200

    Replaced AddVectoredExceptionHandler with SetUnhandledExceptionFilter
    for unhandled exception handling.
    Added log warning if the maxmemory flag is not set.

commit 4993487b25
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Mon Jun 22 17:33:41 2015 +0200

    Fixed links in README.

commit 710d179f91
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Mon Jun 22 17:25:21 2015 +0200

    Added text to links.

commit 04c1ba4c56
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Mon Jun 22 17:15:48 2015 +0200

    Updated documentation.

commit 019d317a10
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Mon Jun 22 13:58:40 2015 +0200

    Use MEM_TOP_DOWN flag to allocate memory for memtest.

commit 3b4bd2f84e
Author: NickMRamirez <nramirez@hmbnet.com>
Date:   Wed Jun 10 15:12:07 2015 -0400

    Added logic to prevent firewall exception from being added if the Windows Firewall Windows service is stopped.

    (cherry picked from commit 12383540c65236b2657f74178d6c2e4ec0c4d15a)

    Conflicts:
    	msvs/msi/RedisMsi/RedisMsi.wixproj

commit 3935ffb302
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Mon Jun 22 12:35:10 2015 +0200

    RejoinCOWPages and background threads should be synchronized (part 2)

commit 87e43c5ce6
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Mon Jun 22 11:23:04 2015 +0200

    Changed error message.

commit af7ca8ca28
Author: Alexis Campailla <alexis@janeasystems.com>
Date:   Fri Jun 19 21:22:48 2015 +0200

    RejoinCOWPages and background threads should be synchronized

    RejoinCOWPages is copying dirty pages to a new view
    of the memory map.
    If another thread modifies the heap between when
    RejoincCOWPages copies the data and when the view is
    remapped, the modification will be lost, leading to a
    memory corruption.
    In short, when RejoincCOWPages is running, all other
    threads must be stopped.

    Fixes: https://github.com/MSOpenTech/redis/issues/244

commit 3cd7d92bf3
Author: Alexis Campailla <alexis@janeasystems.com>
Date:   Fri Jun 19 19:31:22 2015 +0200

    Build ReleasePackagingTool in Debug for Debug solution configuration

commit 4742811f48
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Fri Jun 19 12:05:32 2015 +0200

    Comment wording.

commit 2c8c937325
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Fri Jun 19 00:24:32 2015 +0200

    Cleaned up a few #ifdef _WIN32.

commit 2772b6388e
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Fri Jun 19 00:22:32 2015 +0200

    Indentation.

commit f8cc98586e
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Fri Jun 19 00:20:19 2015 +0200

    StackTrace and info report.

commit d6ede8b354
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Thu Jun 11 17:03:08 2015 +0200

    Moved RedisLog.* to Win32_Interop and renamed to Win32_RedisLog.*

    Deleted unused file msvs/RedisLog.h

commit 13f36c88e0
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Thu Jun 11 16:05:41 2015 +0200

    Added symbols to MSI.

    Also updated the release number to 2.8.21.

commit c68970e268
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Thu Jun 11 15:30:04 2015 +0200

    Enabled dlmalloc DEBUG mode in the debug build.

commit 1cf1db97ae
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Wed Jun 10 23:08:53 2015 +0200

    Final portability fixes for 'long' type.

commit 365c4c7559
Merge: fb63c21 fbb9d61
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Wed Jun 10 12:32:11 2015 +0200

    Merge version 2.8.21 from antirez into 2.8

     Changes to be committed:
    	modified:   00-RELEASENOTES
    	modified:   deps/lua/src/ldo.c
    	modified:   deps/lua/src/lua_cmsgpack.c
    	modified:   src/scripting.c
    	modified:   src/version.h

commit fb63c21f81
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Wed Jun 10 12:15:57 2015 +0200

    Comment.

    added a note in case 32bit support will be brought back.

commit bf260ec746
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Wed Jun 10 00:43:46 2015 +0200

    Test portability fix.

    the 'redis-sentinel' binary is not currently built on Windows, the quick
    workaround is to call 'redis-server --sentinel'

commit 2975545e6a
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Tue Jun 9 17:21:56 2015 +0200

    Restored support for the command argument --test-memory

    along with -h, --help, -v, --version

commit 64c14409d9
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Mon Jun 8 20:40:08 2015 +0200

    Added back the RealeasePackaingTool project in the RedisServer.sln build

    It was removed by mistake in a previous commit.

commit eaf29cc8aa
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Mon Jun 8 20:35:31 2015 +0200

    Truncate AOF in case of unexpected EOF.

    The Win32 port was not truncating the AOF file.

commit 91d01bf8fb
Author: Enrico Giordani <enrico.giordani@gmail.com>
Date:   Mon Jun 8 16:23:53 2015 +0200

    Win32 portability for tests: fix the syntax to invoke 'tail'.

    tail -nX file -> tail -X file

commit fbb9d619f7
Author: antirez <antirez@gmail.com>
Date:   Thu Jun 4 12:00:21 2015 +0200

    Fix 2.8.21 release notes to give full credits.

commit 7f8b865a65
Author: antirez <antirez@gmail.com>
Date:   Thu Jun 4 11:32:24 2015 +0200

    Redis 2.8.21

commit 700b863f13
Author: Ben Murphy <benmmurphy@gmail.com>
Date:   Mon May 11 23:24:37 2015 +0100

    hide access to debug table

commit 5a1b22ad7f
Author: Ben Murphy <benmmurphy@gmail.com>
Date:   Mon May 11 23:24:24 2015 +0100

    disable loading lua bytecode

commit 1eeb9bd714
Author: antirez <antirez@gmail.com>
Date:   Wed Jun 3 08:44:43 2015 +0200

    Scripting: Lua cmsgpack lib updated to include str8 support

Conflicts:
	00-RELEASENOTES
	src/version.h
	tests/instances.tcl
This commit is contained in:
Enrico Giordani
2015-07-07 13:04:19 +02:00
parent c2ccbdfb20
commit 91d9a0bcb0
72 changed files with 1324 additions and 1090 deletions
-173
View File
@@ -1,173 +0,0 @@
Where to find complete Redis documentation?
-------------------------------------------
This README is just a fast "quick start" document. You can find more detailed
documentation at http://redis.io
Building Redis
--------------
Redis can be compiled and used on Linux, OSX, OpenBSD, NetBSD, FreeBSD.
We support big endian and little endian architectures.
It may compile on Solaris derived systems (for instance SmartOS) but our
support for this platform is "best effort" and Redis is not guaranteed to
work as well as in Linux, OSX, and *BSD there.
It is as simple as:
% make
You can run a 32 bit Redis binary using:
% make 32bit
After building Redis is a good idea to test it, using:
% make test
Fixing build problems with dependencies or cached build options
—--------
Redis has some dependencies which are included into the "deps" directory.
"make" does not rebuild dependencies automatically, even if something in the
source code of dependencies is changes.
When you update the source code with `git pull` or when code inside the
dependencies tree is modified in any other way, make sure to use the following
command in order to really clean everything and rebuild from scratch:
make distclean
This will clean: jemalloc, lua, hiredis, linenoise.
Also if you force certain build options like 32bit target, no C compiler
optimizations (for debugging purposes), and other similar build time options,
those options are cached indefinitely until you issue a "make distclean"
command.
Fixing problems building 32 bit binaries
---------
If after building Redis with a 32 bit target you need to rebuild it
with a 64 bit target, or the other way around, you need to perform a
"make distclean" in the root directory of the Redis distribution.
In case of build errors when trying to build a 32 bit binary of Redis, try
the following steps:
* Install the packages libc6-dev-i386 (also try g++-multilib).
* Try using the following command line instead of "make 32bit":
make CFLAGS="-m32 -march=native" LDFLAGS="-m32"
Allocator
---------
Selecting a non-default memory allocator when building Redis is done by setting
the `MALLOC` environment variable. Redis is compiled and linked against libc
malloc by default, with the exception of jemalloc being the default on Linux
systems. This default was picked because jemalloc has proven to have fewer
fragmentation problems than libc malloc.
To force compiling against libc malloc, use:
% make MALLOC=libc
To compile against jemalloc on Mac OS X systems, use:
% make MALLOC=jemalloc
Verbose build
-------------
Redis will build with a user friendly colorized output by default.
If you want to see a more verbose output use the following:
% make V=1
Running Redis
-------------
To run Redis with the default configuration just type:
% cd src
% ./redis-server
If you want to provide your redis.conf, you have to run it using an additional
parameter (the path of the configuration file):
% cd src
% ./redis-server /path/to/redis.conf
It is possible to alter the Redis configuration passing parameters directly
as options using the command line. Examples:
% ./redis-server --port 9999 --slaveof 127.0.0.1 6379
% ./redis-server /etc/redis/6379.conf --loglevel debug
All the options in redis.conf are also supported as options using the command
line, with exactly the same name.
Playing with Redis
------------------
You can use redis-cli to play with Redis. Start a redis-server instance,
then in another terminal try the following:
% cd src
% ./redis-cli
redis> ping
PONG
redis> set foo bar
OK
redis> get foo
"bar"
redis> incr mycounter
(integer) 1
redis> incr mycounter
(integer) 2
redis>
You can find the list of all the available commands here:
http://redis.io/commands
Installing Redis
-----------------
In order to install Redis binaries into /usr/local/bin just use:
% make install
You can use "make PREFIX=/some/other/directory install" if you wish to use a
different destination.
Make install will just install binaries in your system, but will not configure
init scripts and configuration files in the appropriate place. This is not
needed if you want just to play a bit with Redis, but if you are installing
it the proper way for a production system, we have a script doing this
for Ubuntu and Debian systems:
% cd utils
% ./install_server.sh
The script will ask you a few questions and will setup everything you need
to run Redis properly as a background daemon that will start again on
system reboots.
You'll be able to stop and start Redis using the script named
/etc/init.d/redis_<portnumber>, for instance /etc/init.d/redis_6379.
Code contributions
---
Note: by contributing code to the Redis project in any form, including sending
a pull request via Github, a code fragment or patch via private email or
public discussion groups, you agree to release your code under the terms
of the BSD license that you can find in the COPYING file included in the Redis
source distribution.
Please see the CONTRIBUTING file in this source distribution for more
information.
Enjoy!
+9 -22
View File
@@ -17,22 +17,24 @@ Redis on Windows
- Signed binaries can be downloaded using Nuget and Chocolatey.
- There is a replacement for the UNIX fork() API that simulates the copy-on-write behavior using a memory mapped file.
- Because Redis makes some assumptions about the values of File Descriptors, we have built a virtual file descriptor mapping layer.
- We are moving towards moving all Windows-specific changes into the Win32_Interop library.
- Redis can be installed as a Windows Service.
## What's new since 2.8.12
## Redis 2.8 release notes
- See the Redis release notes: http://download.redis.io/redis-stable/00-RELEASENOTES
- Redis on UNIX [release notes](https://raw.githubusercontent.com/antirez/redis/2.8/00-RELEASENOTES)
- Redis on Windows [release notes](https://raw.githubusercontent.com/MSOpenTech/redis/2.8/Redis%20on%20Windows%20Release%20Notes.md)
## Important: More documentation is available
## How to configure and deploy Redis on Windows
Please read the documentation in msvs\setups\documentation. This is the documentation that is bundled with the binaries, and contains vital information about configuring and deploying Redis on Windows.
- [Memory Configuration](https://github.com/MSOpenTech/redis/wiki/Memory-Configuration "Memory Configuration")
- [Redis on Windows](https://raw.githubusercontent.com/MSOpenTech/redis/2.8/Redis%20on%20Windows.md "Redis on Windows")
- [Windows Service Documentation](https://raw.githubusercontent.com/MSOpenTech/redis/2.8/Windows%20Service%20Documentation.md "Windows Service Documentation")
## How to build Redis using Visual Studio
You can use the free Visual Studio Community edition available at http://www.visualstudio.com/products/visual-studio-community-vs.
- Open the solution file msvs\redisserver.sln in Visual Studio, select a build configuration (Debug or Release) and target (Win32 or x64) then build.
- Open the solution file msvs\redisserver.sln in Visual Studio, select a build configuration (Debug or Release) and target (x64) then build.
This should create the following executables in the msvs\$(Target)\$(Configuration) folder:
@@ -52,21 +54,6 @@ To run the Redis test suite requires some manual work:
- To run the tests you need to have a Unix shell on your machine, or MinGW tools in your path. To execute the tests, run the following command:
"tclsh8.5.exe tests/test_helper.tcl --clients N", where N is the number of parallel clients . If a Unix shell is not installed you may see the
following error message: "couldn't execute "cat": no such file or directory".
- By default the test suite launches 16 parallel tests. I will get time out errors on an iCore 7-2620m@2.7Ghz with some of the tests when the number of clients
is greater than 6.
- By default the test suite launches 16 parallel tests, but some of the tests may fail when the number of clients is greater than 2.
## Known issues
Problem:
On versions of Windows prior to Windows 8/Server 2012, when an AOF or RDB operation is complete and the child process is being rejoined with the parent, it is
possible for Redis to unexpectedly terminate.
Cause:
The PAGE_REVERT_TO_FILE_MAP flag is not usable in VirtualProtect() in earlier versions of the OS. This flag allows for removing copy on write(COW) pages from
a memory mapped view without unmapping the view. In prior versions of the OS, the only way to purge COW pages is to unmap and then remap the memory mapped view.
Between the unmapping and remapping operations a third party process(e.g., an anti-virus program) could allocate virtual memory occupied by the memory mapped view.
As this view is used for the Redis heap, failure to remap is a fatal error. (See RejoinCOWPages() in src\Win32_Interop\Win32_QFork.cpp)
Solution:
If you encounter this problem, host Redis on Windows 8/Server 2012 or newer.
+47 -20
View File
@@ -1,34 +1,61 @@
MSOpenTech Redis 2.8.20 Release Notes
=====================================
MSOpenTech Redis on Windows 2.8 Release Notes
=============================================
Welcome to the binary release of Redis from Microsoft Open Technologies, Inc.
--[ Redis on Windows 2.8.21 ] Release date: Jun 24 2015
What is Redis?
--------------
- Merged Redis 2.8.21 [https://raw.githubusercontent.com/antirez/redis/2.8/00-RELEASENOTES]
- Fixes for 64-bit portability.
- Fixed rejoin pages on COW race condition.
- Fixed AOF truncation.
- Fixed crash when the 'save' flag is set and the 'persistence-available' flag is set to 'no'.
- Logging a BUG REPORT (stack trace and server info) when Redis crashes.
- Restored native Redis command arguments: -h, --help, -version, --version, --test-memory.
- Install symbols for redis binaries.
- Prevent firewall exception from being added if the Windows Firewall Windows service is stopped. (NickMRamirez)
- Fix wrong pointer castings for x64 support. (zeliard)
- Fix pointer casting for supporting a 64bit case. (zeliard)
- Fix wrong memset argument. (zeliard)
Redis is an open source, high performance, key-value store. Values may contain strings, hashes, lists, sets and sorted sets. Redis has been developed primarily for UNIX-like operating systems.
--[ Redis on Windows 2.8.19.1 ] Release date: May 04 2015
Porting Goals
-------------
- Added an MSI installer, in addition to the .zip distribution
- Various bug fixes, including:
#167
#228
Our goal is to provide a version of Redis that runs on Windows with a performance essentially equal to the performance of Redis on an equivalent UNIX machine.
--[ Redis on Windows 2.8.19 ] Release date: Feb 25 2015
What is new with the 2.8.20 release
-----------------------------------
- Workaround for getpeername() issue, which affected sentinel failover over ipv6.
- Miscellaneous bug fixes.
Our last official release was 2.8.12. We have merged in the changes up to 2.8.20. Please see the [release notes for the UNIX 2.8 branch](http://download.redis.io/redis-stable/00-RELEASENOTES) to understand how this impacts Redis functionality.
--[ Redis on Windows 2.8.17.4 ] Release date: Feb 02 2015
### Network layer changes
- Fix AV in AllocHeapBlock.
There have been significant changes to the networking layer for this version. Likely there will be a few weeks before there is another official (Chocolatey and Nuget) release. Most of these changes target IPv6.
--[ Redis on Windows 2.8.17.3 ] Release date: Dec 26 2014
### persistence-available flag
- Fix redis-cli pipe mode.
If Redis is to be used as an in-memory-only cache without any kind of persistence, then the fork() mechanism used by the background AOF/RDB persistence is unnecessary. As an optimization, all persistence can be turned off in the Windows version of Redis in this scenario. This will disable the creation of the memory mapped heap file, redirect heap allocations to the system heap allocator, and disable commands that would otherwise cause fork() operations: BGSAVE and BGREWRITEAOF. This flag may not be combined with any of the other flags that configure AOF and RDB operations.
--[ Redis on Windows 2.8.17.2 ] Release date: Dec 23 2014
persistence-available [(yes)|no]
- Moved binaries out of the repository, to the Releases page.
- Miscellaneous bug fixes.
How to develop for Redis
------------------------
--[ Redis on Windows 2.8.17.1 ] Release date: Dec 16 2014
You will need a client library for accessing Redis. There are a wide variety of client libraries available as listed at <http://redis.io/clients>.
- Move release binaries to release page.
- Adopting the suggestions at #172.
- We no longer commit the binaries into the repo.
- Instead, we create periodic releases on the release page.
--[ Redis on Windows 2.8.12 ] Release date: Sep 4 2014
--[ Redis on Windows 2.8.9 ] Release date: Jun 26 2014
--[ Redis on Windows 2.6.14 ] Release date: May 20 2014
--[ Redis on Windows 2.8.4 ] Release date: May 20 2014
--[ Redis on Windows 2.6.8 ] Release date: May 6 2013
--[ Redis on Windows 2.4.6 ] Release date: Feb 10 2012
+7
View File
@@ -1,6 +1,8 @@
MSOpenTech’s Redis on Windows
=============================
Redis is an open source, high performance, key-value store. Values may contain strings, hashes, lists, sets and sorted sets. Redis has been developed primarily for UNIX-like operating systems.
Our goal is to provide a version of Redis that runs on Windows with a performance essentially equal to the performance of Redis on an equivalent UNIX machine.
We strive to have a stable, functionally equivalent and comparably performing version of Redis on Windows. We have achieved performance nearly identical to the POSIX version running head-to-head on identical hardware across the network. Aside from feature differences that help Redis take advantage of the Windows infrastructure, our version of Redis should work in most situations with the identical setup and configuration that one would use on a POSIX operating system.
How is Redis on Windows implemented?
@@ -105,3 +107,8 @@ Service Account
---------------
When using Redis as a Windows service, the default installation configures Redis to run under the system’s NETWORK SERVICE account. There are some environments where another account must be used (perhaps a domain service account). Configuration of this account needs to be done manually at this point with the service control manager. If this is done, it is also important to give read/write/create permission to the folder that the Redis executable is in to this user identity.
How to develop for Redis
========================
You will need a client library for accessing Redis. There are a wide variety of client libraries available as listed at <http://redis.io/clients>.
+1 -1
View File
@@ -1,4 +1,4 @@
version: 2.8.13.{build}
version: 2.8.21.{build}
branches:
# whitelist
-1
View File
@@ -34,7 +34,6 @@
*/
#ifdef _WIN32
#include "../../src/win32_Interop/win32_types.h"
#include "../../src/win32_Interop/win32_util.h"
#endif
#include "fmacros.h"
+3 -2
View File
@@ -58,8 +58,9 @@
#include "net.h"
#include "sds.h"
#ifdef _WIN32
#include "../../src/win32_Interop/win32_util.h"
#include "../../src/win32_Interop/win32fixes.h"
#include "mstcpip.h"
#include "mstcpip.h"
#endif
/* Defined in hiredis.c */
@@ -234,7 +235,7 @@ static int redisContextWaitReady(redisContext *c, const struct timeval *timeout)
if (errno == EINPROGRESS) {
int res;
if ((res = poll(wfd, 1, msec)) == -1) {
if ((res = poll(wfd, 1, (int) msec)) == -1) { WIN_PORT_FIX /* cast (int) */
__redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
redisContextCloseFd(c);
return REDIS_ERR;
+1 -1
View File
@@ -495,7 +495,7 @@ static void f_parser (lua_State *L, void *ud) {
struct SParser *p = cast(struct SParser *, ud);
int c = luaZ_lookahead(p->z);
luaC_checkGC(L);
tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z,
tf = (luaY_parser)(L, p->z,
&p->buff, p->name);
cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L)));
cl->l.p = tf;
+42 -29
View File
@@ -66,7 +66,7 @@
/* Reverse memory bytes if arch is little endian. Given the conceptual
* simplicity of the Lua build system we prefer check for endianess at runtime.
* The performance difference should be acceptable. */
static void memrevifle(void *ptr, size_t len) {
void memrevifle(void *ptr, size_t len) {
unsigned char *p = (unsigned char *)ptr,
*e = (unsigned char *)p+len-1,
aux;
@@ -96,7 +96,7 @@ typedef struct mp_buf {
size_t len, free;
} mp_buf;
static void *mp_realloc(lua_State *L, void *target, size_t osize,size_t nsize) {
void *mp_realloc(lua_State *L, void *target, size_t osize,size_t nsize) {
void *(*local_realloc) (void *, void *, size_t osize, size_t nsize) = NULL;
void *ud;
@@ -105,7 +105,7 @@ static void *mp_realloc(lua_State *L, void *target, size_t osize,size_t nsize) {
return local_realloc(ud, target, osize, nsize);
}
static mp_buf *mp_buf_new(lua_State *L) {
mp_buf *mp_buf_new(lua_State *L) {
mp_buf *buf = NULL;
/* Old size = 0; new size = sizeof(*buf) */
@@ -117,7 +117,7 @@ static mp_buf *mp_buf_new(lua_State *L) {
return buf;
}
static void mp_buf_append(mp_buf *buf, const unsigned char *s, size_t len) {
void mp_buf_append(mp_buf *buf, const unsigned char *s, size_t len) {
if (buf->free < len) {
size_t newlen = buf->len+len;
@@ -153,7 +153,7 @@ typedef struct mp_cur {
int err;
} mp_cur;
static void mp_cur_init(mp_cur *cursor, const unsigned char *s, size_t len) {
void mp_cur_init(mp_cur *cursor, const unsigned char *s, size_t len) {
cursor->p = s;
cursor->left = len;
cursor->err = MP_CUR_ERROR_NONE;
@@ -173,13 +173,17 @@ static void mp_cur_init(mp_cur *cursor, const unsigned char *s, size_t len) {
/* ------------------------- Low level MP encoding -------------------------- */
static void mp_encode_bytes(mp_buf *buf, const unsigned char *s, size_t len) {
void mp_encode_bytes(mp_buf *buf, const unsigned char *s, size_t len) {
unsigned char hdr[5];
int hdrlen;
if (len < 32) {
hdr[0] = 0xa0 | (len&0xff); /* fix raw */
hdrlen = 1;
} else if (len <= 0xff) {
hdr[0] = 0xd9;
hdr[1] = len;
hdrlen = 2;
} else if (len <= 0xffff) {
hdr[0] = 0xda;
hdr[1] = (len&0xff00)>>8;
@@ -198,7 +202,7 @@ static void mp_encode_bytes(mp_buf *buf, const unsigned char *s, size_t len) {
}
/* we assume IEEE 754 internal format for single and double precision floats. */
static void mp_encode_double(mp_buf *buf, double d) {
void mp_encode_double(mp_buf *buf, double d) {
unsigned char b[9];
float f = d;
@@ -216,7 +220,7 @@ static void mp_encode_double(mp_buf *buf, double d) {
}
}
static void mp_encode_int(mp_buf *buf, int64_t n) {
void mp_encode_int(mp_buf *buf, int64_t n) {
unsigned char b[9];
int enclen;
@@ -288,7 +292,7 @@ static void mp_encode_int(mp_buf *buf, int64_t n) {
mp_buf_append(buf,b,enclen);
}
static void mp_encode_array(mp_buf *buf, int64_t n) {
void mp_encode_array(mp_buf *buf, int64_t n) {
unsigned char b[5];
int enclen;
@@ -311,7 +315,7 @@ static void mp_encode_array(mp_buf *buf, int64_t n) {
mp_buf_append(buf,b,enclen);
}
static void mp_encode_map(mp_buf *buf, int64_t n) {
void mp_encode_map(mp_buf *buf, int64_t n) {
unsigned char b[5];
int enclen;
@@ -336,7 +340,7 @@ static void mp_encode_map(mp_buf *buf, int64_t n) {
/* --------------------------- Lua types encoding --------------------------- */
static void mp_encode_lua_string(lua_State *L, mp_buf *buf) {
void mp_encode_lua_string(lua_State *L, mp_buf *buf) {
size_t len;
const char *s;
@@ -344,13 +348,13 @@ static void mp_encode_lua_string(lua_State *L, mp_buf *buf) {
mp_encode_bytes(buf,(const unsigned char*)s,len);
}
static void mp_encode_lua_bool(lua_State *L, mp_buf *buf) {
void mp_encode_lua_bool(lua_State *L, mp_buf *buf) {
unsigned char b = lua_toboolean(L,-1) ? 0xc3 : 0xc2;
mp_buf_append(buf,&b,1);
}
/* Lua 5.3 has a built in 64-bit integer type */
static void mp_encode_lua_integer(lua_State *L, mp_buf *buf) {
void mp_encode_lua_integer(lua_State *L, mp_buf *buf) {
#if (LUA_VERSION_NUM < 503) && BITS_32
lua_Number i = lua_tonumber(L,-1);
#else
@@ -362,7 +366,7 @@ static void mp_encode_lua_integer(lua_State *L, mp_buf *buf) {
/* Lua 5.2 and lower only has 64-bit doubles, so we need to
* detect if the double may be representable as an int
* for Lua < 5.3 */
static void mp_encode_lua_number(lua_State *L, mp_buf *buf) {
void mp_encode_lua_number(lua_State *L, mp_buf *buf) {
lua_Number n = lua_tonumber(L,-1);
if (IS_INT64_EQUIVALENT(n)) {
@@ -372,10 +376,10 @@ static void mp_encode_lua_number(lua_State *L, mp_buf *buf) {
}
}
static void mp_encode_lua_type(lua_State *L, mp_buf *buf, int level);
void mp_encode_lua_type(lua_State *L, mp_buf *buf, int level);
/* Convert a lua table into a message pack list. */
static void mp_encode_lua_table_as_array(lua_State *L, mp_buf *buf, int level) {
void mp_encode_lua_table_as_array(lua_State *L, mp_buf *buf, int level) {
#if LUA_VERSION_NUM < 502
size_t len = lua_objlen(L,-1), j;
#else
@@ -391,7 +395,7 @@ static void mp_encode_lua_table_as_array(lua_State *L, mp_buf *buf, int level) {
}
/* Convert a lua table into a message pack key-value map. */
static void mp_encode_lua_table_as_map(lua_State *L, mp_buf *buf, int level) {
void mp_encode_lua_table_as_map(lua_State *L, mp_buf *buf, int level) {
size_t len = 0;
/* First step: count keys into table. No other way to do it with the
@@ -418,7 +422,7 @@ static void mp_encode_lua_table_as_map(lua_State *L, mp_buf *buf, int level) {
/* Returns true if the Lua table on top of the stack is exclusively composed
* of keys from numerical keys from 1 up to N, with N being the total number
* of elements, without any hole in the middle. */
static int table_is_an_array(lua_State *L) {
int table_is_an_array(lua_State *L) {
int count = 0, max = 0;
#if LUA_VERSION_NUM < 503
lua_Number n;
@@ -461,14 +465,14 @@ static int table_is_an_array(lua_State *L) {
/* If the length operator returns non-zero, that is, there is at least
* an object at key '1', we serialize to message pack list. Otherwise
* we use a map. */
static void mp_encode_lua_table(lua_State *L, mp_buf *buf, int level) {
void mp_encode_lua_table(lua_State *L, mp_buf *buf, int level) {
if (table_is_an_array(L))
mp_encode_lua_table_as_array(L,buf,level);
else
mp_encode_lua_table_as_map(L,buf,level);
}
static void mp_encode_lua_null(lua_State *L, mp_buf *buf) {
void mp_encode_lua_null(lua_State *L, mp_buf *buf) {
unsigned char b[1];
(void)L;
@@ -476,7 +480,7 @@ static void mp_encode_lua_null(lua_State *L, mp_buf *buf) {
mp_buf_append(buf,b,1);
}
static void mp_encode_lua_type(lua_State *L, mp_buf *buf, int level) {
void mp_encode_lua_type(lua_State *L, mp_buf *buf, int level) {
int t = lua_type(L,-1);
/* Limit the encoding of nested tables to a specified maximum depth, so that
@@ -506,7 +510,7 @@ static void mp_encode_lua_type(lua_State *L, mp_buf *buf, int level) {
* Packs all arguments as a stream for multiple upacking later.
* Returns error if no arguments provided.
*/
static int mp_pack(lua_State *L) {
int mp_pack(lua_State *L) {
int nargs = lua_gettop(L);
int i;
mp_buf *buf;
@@ -687,6 +691,15 @@ void mp_decode_to_lua_type(lua_State *L, mp_cur *c) {
mp_cur_consume(c,9);
}
break;
case 0xd9: /* raw 8 */
mp_cur_need(c,2);
{
size_t l = c->p[1];
mp_cur_need(c,2+l);
lua_pushlstring(L,(char*)c->p+2,l);
mp_cur_consume(c,2+l);
}
break;
case 0xda: /* raw 16 */
mp_cur_need(c,3);
{
@@ -773,7 +786,7 @@ void mp_decode_to_lua_type(lua_State *L, mp_cur *c) {
}
}
static int mp_unpack_full(lua_State *L, int limit, int offset) {
int mp_unpack_full(lua_State *L, int limit, int offset) {
size_t len;
const char *s;
mp_cur c;
@@ -826,18 +839,18 @@ static int mp_unpack_full(lua_State *L, int limit, int offset) {
return cnt;
}
static int mp_unpack(lua_State *L) {
int mp_unpack(lua_State *L) {
return mp_unpack_full(L, 0, 0);
}
static int mp_unpack_one(lua_State *L) {
int mp_unpack_one(lua_State *L) {
int offset = luaL_optinteger(L, 2, 0);
/* Variable pop because offset may not exist */
lua_pop(L, lua_gettop(L)-1);
return mp_unpack_full(L, 1, offset);
}
static int mp_unpack_limit(lua_State *L) {
int mp_unpack_limit(lua_State *L) {
int limit = luaL_checkinteger(L, 2);
int offset = luaL_optinteger(L, 3, 0);
/* Variable pop because offset may not exist */
@@ -846,7 +859,7 @@ static int mp_unpack_limit(lua_State *L) {
return mp_unpack_full(L, limit, offset);
}
static int mp_safe(lua_State *L) {
int mp_safe(lua_State *L) {
int argc, err, total_results;
argc = lua_gettop(L);
@@ -869,7 +882,7 @@ static int mp_safe(lua_State *L) {
}
/* -------------------------------------------------------------------------- */
static const struct luaL_Reg cmds[] = {
const struct luaL_Reg cmds[] = {
{"pack", mp_pack},
{"unpack", mp_unpack},
{"unpack_one", mp_unpack_one},
@@ -877,7 +890,7 @@ static const struct luaL_Reg cmds[] = {
{0}
};
static int luaopen_create(lua_State *L) {
int luaopen_create(lua_State *L) {
int i;
/* Manually construct our module table instead of
* relying on _register or _newlib */
-86
View File
@@ -33,164 +33,78 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lua", "lua\lua\lua.vcxproj"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Win32_Interop", "..\src\Win32_Interop\Win32_Interop.vcxproj", "{8C07F811-C81C-432C-B334-1AE6FAECF951}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReleasePackagingTool", "ReleasePackagingTool\ReleasePackagingTool.csproj", "{74A69E5D-6540-43CC-9975-20989BF19EB0}"
ProjectSection(ProjectDependencies) = postProject
{46842776-68A5-EC98-6A09-1859BBFC73AA} = {46842776-68A5-EC98-6A09-1859BBFC73AA}
{392BBB91-3934-4A56-AF42-65C5728311E8} = {392BBB91-3934-4A56-AF42-65C5728311E8}
{52193A97-D010-41D6-BF2B-33E8E764E308} = {52193A97-D010-41D6-BF2B-33E8E764E308}
{B00D4BB5-44DE-405E-839C-D16F547006CF} = {B00D4BB5-44DE-405E-839C-D16F547006CF}
{A65C2CD6-72A3-441A-AEA3-D754BEA9A86A} = {A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Mixed Platforms = Release|Mixed Platforms
Release|Win32 = Release|Win32
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{46842776-68A5-EC98-6A09-1859BBFC73AA}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{46842776-68A5-EC98-6A09-1859BBFC73AA}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{46842776-68A5-EC98-6A09-1859BBFC73AA}.Debug|Win32.ActiveCfg = Debug|Win32
{46842776-68A5-EC98-6A09-1859BBFC73AA}.Debug|Win32.Build.0 = Debug|Win32
{46842776-68A5-EC98-6A09-1859BBFC73AA}.Debug|x64.ActiveCfg = Debug|x64
{46842776-68A5-EC98-6A09-1859BBFC73AA}.Debug|x64.Build.0 = Debug|x64
{46842776-68A5-EC98-6A09-1859BBFC73AA}.Debug|x86.ActiveCfg = Debug|Win32
{46842776-68A5-EC98-6A09-1859BBFC73AA}.Debug|x86.Build.0 = Debug|Win32
{46842776-68A5-EC98-6A09-1859BBFC73AA}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{46842776-68A5-EC98-6A09-1859BBFC73AA}.Release|Mixed Platforms.Build.0 = Release|Win32
{46842776-68A5-EC98-6A09-1859BBFC73AA}.Release|Win32.ActiveCfg = Release|Win32
{46842776-68A5-EC98-6A09-1859BBFC73AA}.Release|Win32.Build.0 = Release|Win32
{46842776-68A5-EC98-6A09-1859BBFC73AA}.Release|x64.ActiveCfg = Release|x64
{46842776-68A5-EC98-6A09-1859BBFC73AA}.Release|x64.Build.0 = Release|x64
{46842776-68A5-EC98-6A09-1859BBFC73AA}.Release|x86.ActiveCfg = Release|Win32
{46842776-68A5-EC98-6A09-1859BBFC73AA}.Release|x86.Build.0 = Release|Win32
{13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Debug|Win32.ActiveCfg = Debug|Win32
{13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Debug|Win32.Build.0 = Debug|Win32
{13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Debug|x64.ActiveCfg = Debug|x64
{13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Debug|x64.Build.0 = Debug|x64
{13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Debug|x86.ActiveCfg = Debug|Win32
{13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Debug|x86.Build.0 = Debug|Win32
{13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Release|Mixed Platforms.Build.0 = Release|Win32
{13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Release|Win32.ActiveCfg = Release|Win32
{13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Release|Win32.Build.0 = Release|Win32
{13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Release|x64.ActiveCfg = Release|x64
{13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Release|x64.Build.0 = Release|x64
{13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Release|x86.ActiveCfg = Release|Win32
{13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Release|x86.Build.0 = Release|Win32
{B00D4BB5-44DE-405E-839C-D16F547006CF}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{B00D4BB5-44DE-405E-839C-D16F547006CF}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{B00D4BB5-44DE-405E-839C-D16F547006CF}.Debug|Win32.ActiveCfg = Debug|Win32
{B00D4BB5-44DE-405E-839C-D16F547006CF}.Debug|Win32.Build.0 = Debug|Win32
{B00D4BB5-44DE-405E-839C-D16F547006CF}.Debug|x64.ActiveCfg = Debug|x64
{B00D4BB5-44DE-405E-839C-D16F547006CF}.Debug|x64.Build.0 = Debug|x64
{B00D4BB5-44DE-405E-839C-D16F547006CF}.Debug|x86.ActiveCfg = Debug|Win32
{B00D4BB5-44DE-405E-839C-D16F547006CF}.Debug|x86.Build.0 = Debug|Win32
{B00D4BB5-44DE-405E-839C-D16F547006CF}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{B00D4BB5-44DE-405E-839C-D16F547006CF}.Release|Mixed Platforms.Build.0 = Release|Win32
{B00D4BB5-44DE-405E-839C-D16F547006CF}.Release|Win32.ActiveCfg = Release|Win32
{B00D4BB5-44DE-405E-839C-D16F547006CF}.Release|Win32.Build.0 = Release|Win32
{B00D4BB5-44DE-405E-839C-D16F547006CF}.Release|x64.ActiveCfg = Release|x64
{B00D4BB5-44DE-405E-839C-D16F547006CF}.Release|x64.Build.0 = Release|x64
{B00D4BB5-44DE-405E-839C-D16F547006CF}.Release|x86.ActiveCfg = Release|Win32
{B00D4BB5-44DE-405E-839C-D16F547006CF}.Release|x86.Build.0 = Release|Win32
{A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Debug|Win32.ActiveCfg = Debug|Win32
{A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Debug|Win32.Build.0 = Debug|Win32
{A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Debug|x64.ActiveCfg = Debug|x64
{A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Debug|x64.Build.0 = Debug|x64
{A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Debug|x86.ActiveCfg = Debug|Win32
{A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Debug|x86.Build.0 = Debug|Win32
{A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Release|Mixed Platforms.Build.0 = Release|Win32
{A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Release|Win32.ActiveCfg = Release|Win32
{A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Release|Win32.Build.0 = Release|Win32
{A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Release|x64.ActiveCfg = Release|x64
{A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Release|x64.Build.0 = Release|x64
{A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Release|x86.ActiveCfg = Release|Win32
{A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Release|x86.Build.0 = Release|Win32
{52193A97-D010-41D6-BF2B-33E8E764E308}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{52193A97-D010-41D6-BF2B-33E8E764E308}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{52193A97-D010-41D6-BF2B-33E8E764E308}.Debug|Win32.ActiveCfg = Debug|Win32
{52193A97-D010-41D6-BF2B-33E8E764E308}.Debug|Win32.Build.0 = Debug|Win32
{52193A97-D010-41D6-BF2B-33E8E764E308}.Debug|x64.ActiveCfg = Debug|x64
{52193A97-D010-41D6-BF2B-33E8E764E308}.Debug|x64.Build.0 = Debug|x64
{52193A97-D010-41D6-BF2B-33E8E764E308}.Debug|x86.ActiveCfg = Debug|Win32
{52193A97-D010-41D6-BF2B-33E8E764E308}.Debug|x86.Build.0 = Debug|Win32
{52193A97-D010-41D6-BF2B-33E8E764E308}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{52193A97-D010-41D6-BF2B-33E8E764E308}.Release|Mixed Platforms.Build.0 = Release|Win32
{52193A97-D010-41D6-BF2B-33E8E764E308}.Release|Win32.ActiveCfg = Release|Win32
{52193A97-D010-41D6-BF2B-33E8E764E308}.Release|Win32.Build.0 = Release|Win32
{52193A97-D010-41D6-BF2B-33E8E764E308}.Release|x64.ActiveCfg = Release|x64
{52193A97-D010-41D6-BF2B-33E8E764E308}.Release|x64.Build.0 = Release|x64
{52193A97-D010-41D6-BF2B-33E8E764E308}.Release|x86.ActiveCfg = Release|Win32
{52193A97-D010-41D6-BF2B-33E8E764E308}.Release|x86.Build.0 = Release|Win32
{392BBB91-3934-4A56-AF42-65C5728311E8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{392BBB91-3934-4A56-AF42-65C5728311E8}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{392BBB91-3934-4A56-AF42-65C5728311E8}.Debug|Win32.ActiveCfg = Debug|Win32
{392BBB91-3934-4A56-AF42-65C5728311E8}.Debug|Win32.Build.0 = Debug|Win32
{392BBB91-3934-4A56-AF42-65C5728311E8}.Debug|x64.ActiveCfg = Debug|x64
{392BBB91-3934-4A56-AF42-65C5728311E8}.Debug|x64.Build.0 = Debug|x64
{392BBB91-3934-4A56-AF42-65C5728311E8}.Debug|x86.ActiveCfg = Debug|Win32
{392BBB91-3934-4A56-AF42-65C5728311E8}.Debug|x86.Build.0 = Debug|Win32
{392BBB91-3934-4A56-AF42-65C5728311E8}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{392BBB91-3934-4A56-AF42-65C5728311E8}.Release|Mixed Platforms.Build.0 = Release|Win32
{392BBB91-3934-4A56-AF42-65C5728311E8}.Release|Win32.ActiveCfg = Release|Win32
{392BBB91-3934-4A56-AF42-65C5728311E8}.Release|Win32.Build.0 = Release|Win32
{392BBB91-3934-4A56-AF42-65C5728311E8}.Release|x64.ActiveCfg = Release|x64
{392BBB91-3934-4A56-AF42-65C5728311E8}.Release|x64.Build.0 = Release|x64
{392BBB91-3934-4A56-AF42-65C5728311E8}.Release|x86.ActiveCfg = Release|Win32
{392BBB91-3934-4A56-AF42-65C5728311E8}.Release|x86.Build.0 = Release|Win32
{170B0909-5F75-467F-9501-C99DEC16C6DC}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{170B0909-5F75-467F-9501-C99DEC16C6DC}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{170B0909-5F75-467F-9501-C99DEC16C6DC}.Debug|Win32.ActiveCfg = Debug|Win32
{170B0909-5F75-467F-9501-C99DEC16C6DC}.Debug|Win32.Build.0 = Debug|Win32
{170B0909-5F75-467F-9501-C99DEC16C6DC}.Debug|x64.ActiveCfg = Debug|x64
{170B0909-5F75-467F-9501-C99DEC16C6DC}.Debug|x64.Build.0 = Debug|x64
{170B0909-5F75-467F-9501-C99DEC16C6DC}.Debug|x86.ActiveCfg = Debug|Win32
{170B0909-5F75-467F-9501-C99DEC16C6DC}.Debug|x86.Build.0 = Debug|Win32
{170B0909-5F75-467F-9501-C99DEC16C6DC}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{170B0909-5F75-467F-9501-C99DEC16C6DC}.Release|Mixed Platforms.Build.0 = Release|Win32
{170B0909-5F75-467F-9501-C99DEC16C6DC}.Release|Win32.ActiveCfg = Release|Win32
{170B0909-5F75-467F-9501-C99DEC16C6DC}.Release|Win32.Build.0 = Release|Win32
{170B0909-5F75-467F-9501-C99DEC16C6DC}.Release|x64.ActiveCfg = Release|x64
{170B0909-5F75-467F-9501-C99DEC16C6DC}.Release|x64.Build.0 = Release|x64
{170B0909-5F75-467F-9501-C99DEC16C6DC}.Release|x86.ActiveCfg = Release|Win32
{170B0909-5F75-467F-9501-C99DEC16C6DC}.Release|x86.Build.0 = Release|Win32
{8C07F811-C81C-432C-B334-1AE6FAECF951}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{8C07F811-C81C-432C-B334-1AE6FAECF951}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{8C07F811-C81C-432C-B334-1AE6FAECF951}.Debug|Win32.ActiveCfg = Debug|Win32
{8C07F811-C81C-432C-B334-1AE6FAECF951}.Debug|Win32.Build.0 = Debug|Win32
{8C07F811-C81C-432C-B334-1AE6FAECF951}.Debug|x64.ActiveCfg = Debug|x64
{8C07F811-C81C-432C-B334-1AE6FAECF951}.Debug|x64.Build.0 = Debug|x64
{8C07F811-C81C-432C-B334-1AE6FAECF951}.Debug|x86.ActiveCfg = Debug|Win32
{8C07F811-C81C-432C-B334-1AE6FAECF951}.Debug|x86.Build.0 = Debug|Win32
{8C07F811-C81C-432C-B334-1AE6FAECF951}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{8C07F811-C81C-432C-B334-1AE6FAECF951}.Release|Mixed Platforms.Build.0 = Release|Win32
{8C07F811-C81C-432C-B334-1AE6FAECF951}.Release|Win32.ActiveCfg = Release|Win32
{8C07F811-C81C-432C-B334-1AE6FAECF951}.Release|Win32.Build.0 = Release|Win32
{8C07F811-C81C-432C-B334-1AE6FAECF951}.Release|x64.ActiveCfg = Release|x64
{8C07F811-C81C-432C-B334-1AE6FAECF951}.Release|x64.Build.0 = Release|x64
{8C07F811-C81C-432C-B334-1AE6FAECF951}.Release|x86.ActiveCfg = Release|Win32
{8C07F811-C81C-432C-B334-1AE6FAECF951}.Release|x86.Build.0 = Release|Win32
{74A69E5D-6540-43CC-9975-20989BF19EB0}.Debug|Mixed Platforms.ActiveCfg = Debug|x64
{74A69E5D-6540-43CC-9975-20989BF19EB0}.Debug|Win32.ActiveCfg = Debug|x64
{74A69E5D-6540-43CC-9975-20989BF19EB0}.Debug|x64.ActiveCfg = Release|x64
{74A69E5D-6540-43CC-9975-20989BF19EB0}.Debug|x86.ActiveCfg = Debug|x64
{74A69E5D-6540-43CC-9975-20989BF19EB0}.Release|Mixed Platforms.ActiveCfg = Release|x64
{74A69E5D-6540-43CC-9975-20989BF19EB0}.Release|Mixed Platforms.Build.0 = Release|x64
{74A69E5D-6540-43CC-9975-20989BF19EB0}.Release|Win32.ActiveCfg = Release|x64
{74A69E5D-6540-43CC-9975-20989BF19EB0}.Release|x64.ActiveCfg = Release|x64
{74A69E5D-6540-43CC-9975-20989BF19EB0}.Release|x86.ActiveCfg = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
+17 -73
View File
@@ -28,16 +28,15 @@ namespace ReleasePackagingTool
string version;
version = p.GetRedisVersion();
p.UpdateReleaseNotes(version);
p.UpdateNuSpecFiles(version);
p.BuildReleasePackage(version);
p.DocxToMd();
Console.Write("Release packaging complete.");
Environment.ExitCode = 0;
}
catch(Exception ex)
{
Console.WriteLine("Error. Failed to finish release packaging. \n" + ex.ToString());
Console.WriteLine("Error. Failed to finish release packaging.\n" + ex.ToString());
Environment.ExitCode = -1;
}
}
@@ -51,70 +50,6 @@ namespace ReleasePackagingTool
return line.Substring(start + 1, last - start - 1);
}
void DocxToMd()
{
// locate converter (pandoc v1.13.0+)
string pandocToolPath = Path.Combine(rootPath, @"msvs\tools\pandoc\pandoc.exe");
if (File.Exists(pandocToolPath))
{
var files = Directory.EnumerateFiles(Path.Combine(rootPath, @"msvs\setups\documentation"), "*.docx");
foreach (string sourceFile in files)
{
string fileName = Path.GetFileName(sourceFile);
string destFile = Path.ChangeExtension(Path.Combine(rootPath, fileName), "md");
System.Diagnostics.Process p = new Process();
p.StartInfo.FileName = pandocToolPath;
p.StartInfo.UseShellExecute = false;
p.StartInfo.Arguments = string.Format(
"-f {0} -t {1} -o \"{2}\" \"{3}\"",
"docx",
"markdown_github",
destFile,
sourceFile);
p.Start();
p.WaitForExit();
if (p.ExitCode != 0)
{
Console.WriteLine("conversion of'{0}' to '{1}' failed.", sourceFile, destFile);
}
}
}
else
{
Console.WriteLine("pandoc tool not found. docx-->md conversion will not take place.");
}
}
void UpdateReleaseNotes(string redisVersion)
{
string releaseNotesPath = Path.Combine(rootPath, @"msvs\setups\documentation\Redis on Windows Release Notes.docx");
string templatePath = Path.Combine(rootPath, @"msvs\setups\documentation\templates\Redis Release Notes Template.docx");
ForceFileErase(releaseNotesPath);
File.Copy(templatePath, releaseNotesPath);
var archive = ZipFile.Open(releaseNotesPath, ZipArchiveMode.Update);
string docuemntContent = @"word/document.xml";
ZipArchiveEntry entry = archive.GetEntry(docuemntContent);
string updatedContent;
using (TextReader tr = new StreamReader(entry.Open()))
{
string documentContent = tr.ReadToEnd();
updatedContent = documentContent.Replace(versionReplacementText, redisVersion);
}
entry.Delete();
archive.Dispose(); // forces the file to be written to disk with the documentContent entry deleted
archive = System.IO.Compression.ZipFile.Open(releaseNotesPath, ZipArchiveMode.Update);
ZipArchiveEntry updatedEntry = archive.CreateEntry(docuemntContent, CompressionLevel.Optimal);
using (TextWriter tw = new StreamWriter(updatedEntry.Open()))
{
tw.Write(updatedContent);
}
archive.Dispose(); // rewrites the file with the updated content
}
void ForceFileErase(string file)
{
if (File.Exists(file))
@@ -143,17 +78,23 @@ namespace ReleasePackagingTool
void UpdateNuSpecFiles(string redisVersion)
{
string chocTemplate = Path.Combine(rootPath, @"msvs\setups\chocolatey\template\Redis.nuspec.template");
string chocDocument = Path.Combine(rootPath, @"msvs\setups\chocolatey\Redis.nuspec");
string chocTemplate = Path.Combine(rootPath, @"msvs\setups\chocolatey\template\redis.nuspec.template");
string chocDocument = Path.Combine(rootPath, @"msvs\setups\chocolatey\redis.nuspec");
CreateTextFileFromTemplate(chocTemplate, chocDocument, versionReplacementText, redisVersion);
string nugetTemplate = Path.Combine(rootPath, @"msvs\setups\nuget\template\Redis.nuspec.template");
string nugetDocument = Path.Combine(rootPath, @"msvs\setups\nuget\Redis.nuspec");
string nugetTemplate = Path.Combine(rootPath, @"msvs\setups\nuget\template\redis.nuspec.template");
string nugetDocument = Path.Combine(rootPath, @"msvs\setups\nuget\redis.nuspec");
CreateTextFileFromTemplate(nugetTemplate, nugetDocument, versionReplacementText, redisVersion);
}
void BuildReleasePackage(string version)
{
string releasePackageDir = Path.Combine(rootPath, @"bin\Release\");
if (Directory.Exists(releasePackageDir) == false)
{
Directory.CreateDirectory(releasePackageDir);
}
string releasePackagePath = Path.Combine(rootPath, @"bin\Release\redis-" + version + ".zip");
ForceFileErase(releasePackagePath);
@@ -164,7 +105,9 @@ namespace ReleasePackagingTool
"redis-check-aof.exe",
"redis-check-dump.exe",
"redis-cli.exe",
"redis-server.exe"
"redis-server.exe",
"redis-server.pdb",
"EventLog.dll"
};
string documentsRoot = Path.Combine(rootPath, @"msvs\setups\documentation");
List<string> docuementNames = new List<string>()
@@ -172,7 +115,8 @@ namespace ReleasePackagingTool
"Redis on Windows.docx",
"Redis on Windows Release Notes.docx",
"Windows Service Documentation.docx",
"redis.windows.conf"
"redis.windows.conf",
"redis.windows-service.conf"
};
using (ZipArchive archive = ZipFile.Open(releasePackagePath, ZipArchiveMode.Create))
@@ -11,6 +11,7 @@
<AssemblyName>ReleasePackagingTool</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<IsWebBootstrapper>false</IsWebBootstrapper>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
@@ -23,7 +24,6 @@
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
@@ -51,6 +51,9 @@
<PropertyGroup>
<RunPostBuildEvent>Always</RunPostBuildEvent>
</PropertyGroup>
<PropertyGroup>
<StartupObject>ReleasePackagingTool.Program</StartupObject>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
@@ -88,7 +91,8 @@
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>$(TargetPath)</PostBuildEvent>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
@@ -0,0 +1,22 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReleasePackagingTool", "ReleasePackagingTool.csproj", "{74A69E5D-6540-43CC-9975-20989BF19EB0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{74A69E5D-6540-43CC-9975-20989BF19EB0}.Debug|x64.ActiveCfg = Debug|x64
{74A69E5D-6540-43CC-9975-20989BF19EB0}.Debug|x64.Build.0 = Debug|x64
{74A69E5D-6540-43CC-9975-20989BF19EB0}.Release|x64.ActiveCfg = Release|x64
{74A69E5D-6540-43CC-9975-20989BF19EB0}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
-3
View File
@@ -143,9 +143,6 @@
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\deps\hiredis\async.c" />
<ClCompile Include="..\..\deps\hiredis\dict.c" />
+73 -50
View File
@@ -1,50 +1,73 @@
using System;
using System.IO;
using Microsoft.Deployment.WindowsInstaller;
namespace RedisMsi.CustomActions
{
/// <summary>
/// Defines actions to take during the MSI install that don't
/// come standard with WiX.
/// </summary>
public class CustomActions
{
/// <summary>
/// Overwrites settings in the Redis config file using values from the installer.
/// </summary>
/// <param name="session">The install session context</param>
/// <returns>Returns Success when the method completes. Exceptions will bubble up and
/// cause the installer to roll back.</returns>
[CustomAction]
public static ActionResult UpdateRedisConfig(Session session)
{
// Update port
string port = session.CustomActionData["PORT"];
string configFilePath = session.CustomActionData["CONFIG_PATH"];
UpdatePortSetting(port, configFilePath);
return ActionResult.Success;
}
/// <summary>
/// Updates the port in the config file.
/// </summary>
/// <param name="portToUse">The port to have Redis listen at</param>
/// <param name="configFilePath">The path to the Redis config file</param>
private static void UpdatePortSetting(string portToUse, string configFilePath)
{
if (File.Exists(configFilePath))
{
string originalContent = File.ReadAllText(configFilePath);
string updatedContent = originalContent.Replace("port 6379", "port " + portToUse);
File.WriteAllText(configFilePath, updatedContent);
}
else
{
throw new ApplicationException("UpdateRedisConfig: Config file not found. Could not update its settings.");
}
}
}
}
using System;
using System.IO;
using Microsoft.Deployment.WindowsInstaller;
using System.ServiceProcess;
namespace RedisMsi.CustomActions
{
/// <summary>
/// Defines actions to take during the MSI install that don't
/// come standard with WiX.
/// </summary>
public class CustomActions
{
/// <summary>
/// Overwrites settings in the Redis config file using values from the installer.
/// </summary>
/// <param name="session">The install session context</param>
/// <returns>Returns Success when the method completes. Exceptions will bubble up and
/// cause the installer to roll back.</returns>
[CustomAction]
public static ActionResult UpdateRedisConfig(Session session)
{
// Update port
string port = session.CustomActionData["PORT"];
string configFilePath = session.CustomActionData["CONFIG_PATH"];
UpdatePortSetting(port, configFilePath);
return ActionResult.Success;
}
/// <summary>
/// Sets a WiX property to indicate whether the Windows Firewall service is stopped.
/// If the firewall service is stopped, the install will not succeed if it attempts
/// to add a firewall exception. Note that just setting the state of the
/// firewall to off does not pose a problem.
/// </summary>
/// <param name="session"></param>
/// <returns></returns>
[CustomAction]
public static ActionResult CheckIfFirewallServiceRunning(Session session)
{
ServiceController sc = new ServiceController("MpsSvc"); // Windows Firewall service
bool isStopped = sc.Status.Equals(ServiceControllerStatus.Stopped) || sc.Status.Equals(ServiceControllerStatus.StopPending);
if (isStopped)
{
session["FIREWALL_SERVICE_STOPPED"] = "1";
}
return ActionResult.Success;
}
/// <summary>
/// Updates the port in the config file.
/// </summary>
/// <param name="portToUse">The port to have Redis listen at</param>
/// <param name="configFilePath">The path to the Redis config file</param>
private static void UpdatePortSetting(string portToUse, string configFilePath)
{
if (File.Exists(configFilePath))
{
string originalContent = File.ReadAllText(configFilePath);
string updatedContent = originalContent.Replace("port 6379", "port " + portToUse);
File.WriteAllText(configFilePath, updatedContent);
}
else
{
throw new ApplicationException("UpdateRedisConfig: Config file not found. Could not update its settings.");
}
}
}
}
@@ -1,71 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{A917027E-D229-46C9-B969-1F4CE7D5D2CA}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>RedisMsi.CustomActions</RootNamespace>
<AssemblyName>RedisMsi.CustomActions</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<WixCATargetsPath Condition=" '$(WixCATargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.CA.targets</WixCATargetsPath>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.Deployment.WindowsInstaller">
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="CustomAction.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Content Include="CustomAction.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(WixCATargetsPath)" />
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{A917027E-D229-46C9-B969-1F4CE7D5D2CA}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>RedisMsi.CustomActions</RootNamespace>
<AssemblyName>RedisMsi.CustomActions</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<WixCATargetsPath Condition=" '$(WixCATargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.CA.targets</WixCATargetsPath>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.Deployment.WindowsInstaller">
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="CustomAction.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Content Include="CustomAction.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(WixCATargetsPath)" />
</Project>
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?define RepoDir="$(var.ProjectDir)..\..\..\" ?>
<?define BinDir="$(var.RepoDir)msvs\$(var.Platform)\$(var.Configuration)\" ?>
<Fragment>
<!--Symbols to install-->
<ComponentGroup Id="SymbolsComponents" Directory="INSTALLFOLDER">
<Component Id="cmp_redis_severPDB" Guid="*">
<File Source="$(var.BinDir)redis-server.pdb" />
</Component>
<Component Id="cmp_redis_cliPDB" Guid="*">
<File Source="$(var.BinDir)redis-cli.pdb" />
</Component>
<Component Id="cmp_redis_benchmarkPDB" Guid="*">
<File Source="$(var.BinDir)redis-benchmark.pdb" />
</Component>
<Component Id="cmp_redis_check_aofPDB" Guid="*">
<File Source="$(var.BinDir)redis-check-aof.pdb" />
</Component>
<Component Id="cmp_redis_check_dumpPDB" Guid="*">
<File Source="$(var.BinDir)redis-check-dump.pdb" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
@@ -40,7 +40,7 @@
The following component creates the firewall exception.
-->
<Component Id="cmp_firewall_exception" Guid="{1D39F01C-6C53-4DC1-B189-65F03F7E5E31}" KeyPath="yes">
<Condition><![CDATA[FIREWALL_ON = 1]]></Condition>
<Condition><![CDATA[ADD_FIREWALL_RULE = 1 AND FIREWALL_SERVICE_STOPPED <> 1]]></Condition>
<fw:FirewallException Id="fw_redis_server"
Program="[#file_redis_serverEXE]"
@@ -88,16 +88,5 @@
<RemoveFile Id="removeLogFile" Directory="LogsFolder" Name="*" On="uninstall" />
</Component>
</ComponentGroup>
<!--
Custom actions that update the redis config file during installation
-->
<Binary Id="RedisCADLL" SourceFile="$(var.RedisMsi.CustomActions.TargetDir)RedisMsi.CustomActions.CA.dll" />
<CustomAction Id="ca_UpdateRedisConfig" BinaryKey="RedisCADLL" DllEntry="UpdateRedisConfig" Execute="deferred" Return="check" Impersonate="no" />
<SetProperty Id="ca_UpdateRedisConfig" Value="CONFIG_PATH=[#file_redis_serviceCONF];PORT=[PORT];" Sequence="execute" Before="ca_UpdateRedisConfig" />
<InstallExecuteSequence>
<Custom Action="ca_UpdateRedisConfig" After="InstallFiles"><![CDATA[NOT Installed]]></Custom>
</InstallExecuteSequence>
</Fragment>
</Wix>
+30
View File
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<Binary Id="RedisCADLL" SourceFile="$(var.RedisMsi.CustomActions.TargetDir)RedisMsi.CustomActions.CA.dll" />
<!--
Custom actions that update the redis config file during installation
-->
<CustomAction Id="ca_UpdateRedisConfig" BinaryKey="RedisCADLL" DllEntry="UpdateRedisConfig" Execute="deferred" Return="check" Impersonate="no" />
<SetProperty Id="ca_UpdateRedisConfig" Value="CONFIG_PATH=[#file_redis_serviceCONF];PORT=[PORT];" Sequence="execute" Before="ca_UpdateRedisConfig" />
<InstallExecuteSequence>
<Custom Action="ca_UpdateRedisConfig" After="InstallFiles"><![CDATA[NOT Installed]]></Custom>
</InstallExecuteSequence>
<!--
Custom action that sets a property to indicate if Windows Firewall service is running
-->
<CustomAction Id="ca_CheckIfFirewallServiceRunning" BinaryKey="RedisCADLL" DllEntry="CheckIfFirewallServiceRunning" Execute="immediate" Return="check" />
<CustomAction Id="ca_SetADD_FIREWALL_RULE" Property="ADD_FIREWALL_RULE" Value="{}" />
<InstallUISequence>
<Custom Action="ca_CheckIfFirewallServiceRunning" After="LaunchConditions"><![CDATA[NOT Installed]]></Custom>
<Custom Action="ca_SetADD_FIREWALL_RULE" After="ca_CheckIfFirewallServiceRunning"><![CDATA[FIREWALL_SERVICE_STOPPED = 1]]></Custom>
</InstallUISequence>
<InstallExecuteSequence>
<Custom Action="ca_CheckIfFirewallServiceRunning" After="LaunchConditions"><![CDATA[NOT Installed]]></Custom>
<Custom Action="ca_SetADD_FIREWALL_RULE" After="ca_CheckIfFirewallServiceRunning"><![CDATA[FIREWALL_SERVICE_STOPPED = 1]]></Custom>
</InstallExecuteSequence>
</Fragment>
</Wix>
+8 -1
View File
@@ -2,6 +2,8 @@
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<UI>
<TextStyle Id="Warning" FaceName="Tahoma" Size="10" Red="255"/>
<Dialog Id="FirewallDlg" Width="370" Height="270" Title="[ProductName] Setup">
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)" />
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)" />
@@ -18,7 +20,12 @@
<Control Id="PortLabel" Type="Text" X="20" Y="60" Width="290" Height="30" NoPrefix="yes" Text="Port to run Redis on:" />
<Control Id="PortEdit" Type="Edit" Property="PORT" Height="17" Width="50" X="20" Y="100" />
<Control Id="FirewallCheckbox" Type="CheckBox" Property="FIREWALL_ON" CheckBoxValue="1" Integer="yes" Text="Add an exception to the Windows Firewall" Height="10" Width="200" X="20" Y="140" />
<Control Id="FirewallCheckbox" Type="CheckBox" Property="ADD_FIREWALL_RULE" CheckBoxValue="1" Integer="yes" Text="Add an exception to the Windows Firewall" Height="10" Width="200" X="20" Y="140">
<Condition Action="disable"><![CDATA[FIREWALL_SERVICE_STOPPED = 1]]></Condition>
</Control>
<Control Id="FirewallServiceOffText" Type="Text" Text="{\Warning}The firewall service must be running to add a new exception." Height="34" Width="280" X="20" Y="160" Hidden="yes" NoWrap="no">
<Condition Action="show"><![CDATA[FIREWALL_SERVICE_STOPPED = 1]]></Condition>
</Control>
</Dialog>
</UI>
</Fragment>
Binary file not shown.
+9 -4
View File
@@ -10,10 +10,10 @@
msiexec /i Redis-[version].msi
set port and turn off firewall exception:
msiexec /i Redis-[version].msi PORT=1234 FIREWALL_ON=""
msiexec /i Redis-[version].msi PORT=1234 ADD_FIREWALL_RULE=""
set port and turn on firewall exception:
msiexec /i Redis-[version].msi PORT=1234 FIREWALL_ON=1
msiexec /i Redis-[version].msi PORT=1234 ADD_FIREWALL_RULE=1
-->
@@ -21,7 +21,7 @@
<Product Id="*"
Name="Redis on Windows"
Language="1033"
Version="2.8.19.1"
Version="2.8.21"
Manufacturer="MSOpenTech"
UpgradeCode="{05410198-7212-4FC4-B7C8-AFEFC3DA0FBC}">
<Package InstallerVersion="200"
@@ -38,17 +38,22 @@
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
<Property Id="ARPURLINFOABOUT" Value="https://github.com/MSOpenTech/redis" />
<Property Id="PORT" Value="6379" />
<Property Id="FIREWALL_ON" Value="1" />
<Property Id="ADD_FIREWALL_RULE" Value="1" />
<Property Id="FIREWALL_SERVICE_STOPPED" Value="0" />
<!--Link-time variables-->
<WixVariable Id="WixUILicenseRtf" Value="License.rtf"/>
<WixVariable Id="WixUIDialogBmp" Value="Images/redis_background.jpg"/>
<WixVariable Id="WixUIBannerBmp" Value="Images/top_banner.jpg"/>
<WixVariable Id="DocumentationFolder" Value="..\..\setups\documentation"/>
<!--Link in custom actions, referencing one will pull in all-->
<CustomActionRef Id="ca_UpdateRedisConfig"/>
<!--Features-->
<Feature Id="ProductFeature" Title="Redis" Level="1">
<ComponentGroupRef Id="FileComponents" />
<ComponentGroupRef Id="SymbolsComponents" />
<ComponentGroupRef Id="WindowsServiceComponents" />
<ComponentGroupRef Id="DocumentationComponents" />
</Feature>
+3 -1
View File
@@ -39,7 +39,9 @@
<ItemGroup>
<Compile Include="Components\DocumentationComponents.wxs" />
<Compile Include="Components\FileComponents.wxs" />
<Compile Include="Components\SymbolsComponents.wxs" />
<Compile Include="Components\WindowsServiceComponents.wxs" />
<Compile Include="CustomActions.wxs" />
<Compile Include="Dialogs\CustomInstallDir.wxs" />
<Compile Include="Dialogs\FirewallDialog.wxs" />
<Compile Include="Product.wxs" />
@@ -56,7 +58,7 @@
</ItemGroup>
<ItemGroup>
<WixExtension Include="WixUIExtension">
<HintPath>..\..\..\..\Program Files (x86)\WiX Toolset v3.9\bin\WixUIExtension.dll</HintPath>
<HintPath>$(WixExtDir)\WixUIExtension.dll</HintPath>
<Name>WixUIExtension</Name>
</WixExtension>
<WixExtension Include="WixFirewallExtension">
+26 -15
View File
@@ -1,25 +1,36 @@
$CurDir = split-path -parent $MyInvocation.MyCommand.Definition
$ErrorActionPreference = "Stop"
$ChocolateyDir = $CurDir + "\chocolatey"
$NugetDir = $CurDir + "\nuget"
$PackagesDir = $CurDir + "\packages"
$CurDir = split-path -parent $MyInvocation.MyCommand.Definition
$PackagesDir = $CurDir + "\packages"
$ChocolateySrcDir = $CurDir + "\chocolatey"
$ChocolateyDestDir = $PackagesDir + "\chocolatey"
$NugetSrcDir = $CurDir + "\nuget"
$NugetDestDir = $PackagesDir + "\nuget"
If (Test-Path $PackagesDir){
Remove-Item $PackagesDir -recurse | Out-Null
}
New-Item $PackagesDir -type directory | Out-Null
New-Item ($PackagesDir+"\Chocolatey") -type directory | Out-Null
New-Item ($PackagesDir+"\NuGet") -type directory | Out-Null
New-Item $PackagesDir -type directory | Out-Null
New-Item $ChocolateyDestDir -type directory | Out-Null
New-Item $NugetDestDir -type directory | Out-Null
Set-Location $ChocolateyDir
Set-Location $ChocolateySrcDir
invoke-expression "chocolatey pack Redis.nuspec"
Copy-Item *.nupkg ..\packages\Chocolatey
if ($LASTEXITCODE -eq 0) {
Copy-Item *.nupkg $ChocolateyDestDir
Write-Host "Chocolatey package copied to the destination folder." -foregroundcolor black -backgroundcolor green
} else {
Write-Host "FAILED to create the Chocolatey package." -foregroundcolor white -backgroundcolor red
}
Set-Location $NugetDir
invoke-expression "NuGet Pack Redis.nuspec"
Copy-Item *.nupkg ..\packages\NuGet
Set-Location $NugetSrcDir
invoke-expression "nuget pack Redis.nuspec"
if ($LASTEXITCODE -eq 0) {
Copy-Item *.nupkg $NugetDestDir
Write-Host "NuGet package copied to the destination folder." -foregroundcolor black -backgroundcolor green
} else {
Write-Host "FAILED to create the NuGet package." -foregroundcolor white -backgroundcolor red
}
Write-Host "Run PushPackages to push the packages." -foregroundcolor red -backgroundcolor yellow
Set-Location $CurDir
Write-Host "The .nupkg files are in the 'packages' directory." -foregroundcolor black -backgroundcolor green
Write-Host "Run PushPackages to push them." -foregroundcolor red -backgroundcolor yellow
+24 -9
View File
@@ -1,17 +1,32 @@
param (
[string] $Version = $(throw 'Redis version to download is required')
)
$ErrorActionPreference = "Stop"
[Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem") | Out-Null
$CurDir = split-path -parent $MyInvocation.MyCommand.Definition
$ZipFilename = "redis-x64-" + $Version + ".zip"
$CurDir = split-path -parent $MyInvocation.MyCommand.Definition
$SourceZip = [System.IO.Path]::Combine($CurDir, $ZipFilename )
$DestinationDir = [System.IO.Path]::Combine($CurDir, "signed_binaries" )
$GithubUrl = "https://github.com/MSOpenTech/redis/releases/download/win-" + $Version + "/" + $ZipFilename
$SourceZip = [System.IO.Path]::Combine($CurDir, "..\..\bin\Release\redis-2.8.16.zip" )
$Destination = [System.IO.Path]::Combine($CurDir, "signed_binaries" )
[System.IO.File]::Delete($SourceZip)
[System.IO.Directory]::CreateDirectory($DestinationDir) | Out-Null
[System.IO.Directory]::CreateDirectory($Destination) | Out-Null
ForEach( $file in [System.IO.Directory]::EnumerateFiles($Destination) ) {
ForEach( $file in [System.IO.Directory]::EnumerateFiles($DestinationDir) ) {
[System.IO.File]::Delete($file)
}
[System.IO.Compression.ZipFile]::ExtractToDirectory($SourceZip,$Destination)
Write-Host "Downloading zip file from $GithubUrl"
(New-Object Net.WebClient).DownloadFile($GithubUrl, $SourceZip);
Write-Host "Download complete." -foregroundcolor black -backgroundcolor green
Write-Host "Binaries copied from $SourceZip to $Destination" -foregroundcolor black -backgroundcolor green
Write-Host "Sign these and then run CreatePackages.ps1" -foregroundcolor red -backgroundcolor yellow
Write-Host "Extracting files to $DestinationDir"
[System.IO.Compression.ZipFile]::ExtractToDirectory($SourceZip,$DestinationDir)
Write-Host "Extraction complete." -foregroundcolor black -backgroundcolor green
# Clean up
[System.IO.File]::Delete($SourceZip)
Write-Host "Sign the binaries and then run CreatePackages.ps1" -foregroundcolor red -backgroundcolor yellow
+14 -3
View File
@@ -2,6 +2,8 @@ param (
[string] $Version = $(throw 'Redis version to push is required')
)
$ErrorActionPreference = "Stop"
Write-Host "Ensure that the api keys have been set for chocolatey and nuget" -foregroundcolor red -backgroundcolor yellow
Write-Host " NuGet SetApiKey <your key here> -source http://chocolatey.org/" -foregroundcolor red -backgroundcolor yellow
Write-Host " NuGet SetApiKey <your key here>" -foregroundcolor red -backgroundcolor yellow
@@ -9,17 +11,26 @@ Write-Host " NuGet SetApiKey <your key here>" -foregroundcolor red -backgroundc
$CurDir = split-path -parent $MyInvocation.MyCommand.Definition
$PackagesDir = $CurDir + "\packages"
$ChocolateyDir = $PackagesDir + "\Chocolatey"
$NugetDir = $PackagesDir + "\Nuget"
$ChocolateyDir = $PackagesDir + "\chocolatey"
$NugetDir = $PackagesDir + "\nuget"
Set-Location $ChocolateyDir
$ChocolateyCommand = "chocolatey push Redis-64." + $Version + ".nupkg"
invoke-expression $ChocolateyCommand
if ($LASTEXITCODE -eq 0) {
Write-Host "Chocolatey package pushed successfully." -foregroundcolor black -backgroundcolor green
} else {
Write-Host "FAILED to push the Chocolatey package." -foregroundcolor white -backgroundcolor red
}
Set-Location $NugetDir
$NugetCommand = "NuGet push Redis-64." + $Version + ".nupkg"
invoke-expression $NugetCommand
if ($LASTEXITCODE -eq 0) {
Write-Host "NuGet package pushed successfully" -foregroundcolor black -backgroundcolor green
} else {
Write-Host "FAILED to push the NuGet package." -foregroundcolor white -backgroundcolor red
}
Set-Location $CurDir
Write-Host "The .nupkg files have been pushed!" -foregroundcolor black -backgroundcolor green
+5 -6
View File
@@ -2,22 +2,21 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>redis-64</id>
<title>redis-64</title>
<version>2.8.20</version>
<authors>Jonathan Pickett</authors>
<title>Redis 64</title>
<version>2.8.21</version>
<authors>Alexis Campailla, Enrico Giordani, Jonathan Pickett</authors>
<owners>Microsoft Open Technologies, Inc.</owners>
<summary>Redis is a very popular open-source, networked, in-memory, key-value data store known for high performance, flexibility, a rich set of data structures, and a simple straightforward API.</summary>
<description>A production-ready Windows port of Redis, including 64-bit support, Chocolatey support, and much more.</description>
<description>Redis on Windows 64-bit.</description>
<projectUrl>https://msopentech.com/opentech-projects/redis/</projectUrl>
<tags>Redis nosql cache</tags>
<copyright>Copyright Microsoft Open Technologies, Inc.</copyright>
<licenseUrl>https://github.com/MSOpenTech/redis/blob/2.8/license.txt</licenseUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<iconUrl>http://redis.io/images/redis.png</iconUrl>
<releaseNotes>Includes the changes from Redis 2.8.12 -> 2.8.20. Please see the release notes for the UNIX 2.8 branch to understand how this impacts Redis functionality.</releaseNotes>
<releaseNotes>https://raw.githubusercontent.com/MSOpenTech/redis/2.8/Redis%20on%20Windows%20Release%20Notes.md</releaseNotes>
</metadata>
<files>
<file src="..\signed_binaries\*.*" target=".\" />
<file src="..\documentation\*.*" target=".\" />
</files>
</package>
@@ -2,22 +2,21 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>redis-64</id>
<title>redis-64</title>
<title>Redis 64</title>
<version>CurrentRedisVersion</version>
<authors>Jonathan Pickett</authors>
<authors>Alexis Campailla, Enrico Giordani, Jonathan Pickett</authors>
<owners>Microsoft Open Technologies, Inc.</owners>
<summary>Redis is a very popular open-source, networked, in-memory, key-value data store known for high performance, flexibility, a rich set of data structures, and a simple straightforward API.</summary>
<description>A production-ready Windows port of Redis, including 64-bit support, Chocolatey support, and much more.</description>
<description>Redis on Windows 64-bit.</description>
<projectUrl>https://msopentech.com/opentech-projects/redis/</projectUrl>
<tags>Redis nosql cache</tags>
<copyright>Copyright Microsoft Open Technologies, Inc.</copyright>
<licenseUrl>https://github.com/MSOpenTech/redis/blob/2.8/license.txt</licenseUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<iconUrl>http://redis.io/images/redis.png</iconUrl>
<releaseNotes>Includes the changes from Redis 2.8.12 -> CurrentRedisVersion. Please see the release notes for the UNIX 2.8 branch to understand how this impacts Redis functionality.</releaseNotes>
<releaseNotes>https://raw.githubusercontent.com/MSOpenTech/redis/2.8/Redis%20on%20Windows%20Release%20Notes.md</releaseNotes>
</metadata>
<files>
<file src="..\signed_binaries\*.*" target=".\" />
<file src="..\documentation\*.*" target=".\" />
</files>
</package>
@@ -497,6 +497,9 @@ slave-priority 100
# limit for maxmemory so that there is some free RAM on the system for slave
# output buffers (but this is not needed if the policy is 'noeviction').
#
# WARNING: not setting maxmemory will cause Redis to terminate with an
# out-of-memory exception if the maxheap limit is reached.
#
# maxmemory <bytes>
# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
@@ -497,6 +497,9 @@ slave-priority 100
# limit for maxmemory so that there is some free RAM on the system for slave
# output buffers (but this is not needed if the policy is 'noeviction').
#
# WARNING: not setting maxmemory will cause Redis to terminate with an
# out-of-memory exception if the maxheap limit is reached.
#
# maxmemory <bytes>
# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
+9 -7
View File
@@ -2,22 +2,24 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>redis-64</id>
<title>redis-64</title>
<version>2.8.20</version>
<authors>Jonathan Pickett</authors>
<title>Redis-64</title>
<version>2.8.21</version>
<authors>Alexis Campailla, Enrico Giordani, Jonathan Pickett</authors>
<owners>Microsoft Open Technologies, Inc.</owners>
<summary>Redis is a very popular open-source, networked, in-memory, key-value data store known for high performance, flexibility, a rich set of data structures, and a simple straightforward API.</summary>
<description>A production-ready Windows port of Redis, including 64-bit support, Chocolatey support, and much more.</description>
<description>Redis on Windows 64-bit.</description>
<projectUrl>https://msopentech.com/opentech-projects/redis/</projectUrl>
<tags>Redis nosql cache</tags>
<copyright>Copyright Microsoft Open Technologies, Inc.</copyright>
<licenseUrl>https://github.com/MSOpenTech/redis/blob/2.8/license.txt</licenseUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<iconUrl>http://redis.io/images/redis.png</iconUrl>
<releaseNotes>Includes the changes from Redis 2.8.12 -> 2.8.20. Please see the release notes for the UNIX 2.8 branch to understand how this impacts Redis functionality.</releaseNotes>
<releaseNotes>https://raw.githubusercontent.com/MSOpenTech/redis/2.8/Redis%20on%20Windows%20Release%20Notes.md</releaseNotes>
</metadata>
<files>
<file src="..\signed_binaries\*.*" target=".\" />
<file src="..\documentation\*.*" target=".\" />
<file src="..\signed_binaries\*.exe" target=".\" />
<file src="..\signed_binaries\*.pdb" target=".\" />
<file src="..\signed_binaries\*.conf" target=".\" />
<file src="..\signed_binaries\*.docx" target=".\" />
</files>
</package>
@@ -2,22 +2,24 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>redis-64</id>
<title>redis-64</title>
<title>Redis-64</title>
<version>CurrentRedisVersion</version>
<authors>Jonathan Pickett</authors>
<authors>Alexis Campailla, Enrico Giordani, Jonathan Pickett</authors>
<owners>Microsoft Open Technologies, Inc.</owners>
<summary>Redis is a very popular open-source, networked, in-memory, key-value data store known for high performance, flexibility, a rich set of data structures, and a simple straightforward API.</summary>
<description>A production-ready Windows port of Redis, including 64-bit support, Chocolatey support, and much more.</description>
<description>Redis on Windows 64-bit.</description>
<projectUrl>https://msopentech.com/opentech-projects/redis/</projectUrl>
<tags>Redis nosql cache</tags>
<copyright>Copyright Microsoft Open Technologies, Inc.</copyright>
<licenseUrl>https://github.com/MSOpenTech/redis/blob/2.8/license.txt</licenseUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<iconUrl>http://redis.io/images/redis.png</iconUrl>
<releaseNotes>Includes the changes from Redis 2.8.12 -> CurrentRedisVersion. Please see the release notes for the UNIX 2.8 branch to understand how this impacts Redis functionality.</releaseNotes>
<releaseNotes>https://raw.githubusercontent.com/MSOpenTech/redis/2.8/Redis%20on%20Windows%20Release%20Notes.md</releaseNotes>
</metadata>
<files>
<file src="..\signed_binaries\*.*" target=".\" />
<file src="..\documentation\*.*" target=".\" />
<file src="..\signed_binaries\*.exe" target=".\" />
<file src="..\signed_binaries\*.pdb" target=".\" />
<file src="..\signed_binaries\*.conf" target=".\" />
<file src="..\signed_binaries\*.docx" target=".\" />
</files>
</package>
+49 -34
View File
@@ -563,7 +563,8 @@ vector<string> incompatibleNoPersistenceCommands{
"no_append_fsync_on_rewrite",
"auto_aof_rewrite_percentage",
"auto_aof_rewrite_on_size",
"aof_rewrite_incremental_fsync"
"aof_rewrite_incremental_fsync",
"save"
};
void ValidateCommandlineCombinations() {
@@ -595,41 +596,53 @@ void ParseCommandLineArguments(int argc, char** argv) {
string argument = string(argv[n]).substr(2, argument.length() - 2);
transform(argument.begin(), argument.end(), argument.begin(), ::tolower);
if (g_redisArgMap.find(argument) == g_redisArgMap.end()) {
stringstream err;
err << "unknown argument: " << argument;
throw invalid_argument(err.str());
}
vector<string> params;
if (argument == cSentinel) {
try {
vector<string> sentinelSubCommands = g_redisArgMap[argument]->Extract(n, argc, argv);
for (auto p : sentinelSubCommands) {
params.push_back(p);
}
} catch (invalid_argument iaerr) {
// if no subcommands could be mapped, then assume this is the parameterless --sentinel command line only argument
}
} else if (argument == cServiceRun ) {
// When the service starts the current directory is %systemdir%. This needs to be changed to the
// directory the executable is in so that the .conf file can be loaded.
char szFilePath[MAX_PATH];
if (GetModuleFileNameA(NULL, szFilePath, MAX_PATH) == 0) {
throw std::system_error(GetLastError(), system_category(), "ParseCommandLineArguments: GetModuleFileName failed");
}
string currentDir = szFilePath;
auto pos = currentDir.rfind("\\");
currentDir.erase(pos);
if (FALSE == SetCurrentDirectoryA(currentDir.c_str())) {
throw std::system_error(GetLastError(), system_category(), "SetCurrentDirectory failed");
// Some -- arguments are passed directly to redis.c::main()
if (find(cRedisArgsForMainC.begin(), cRedisArgsForMainC.end(), argument) != cRedisArgsForMainC.end()) {
if (strcasecmp(argument.c_str(), "test-memory") == 0) {
// The test-memory argument is followed by a integer value
n++;
}
} else {
params = g_redisArgMap[argument]->Extract(n, argc, argv);
// -- arguments processed before calling redis.c::main()
if (g_redisArgMap.find(argument) == g_redisArgMap.end()) {
stringstream err;
err << "unknown argument: " << argument;
throw invalid_argument(err.str());
}
vector<string> params;
if (argument == cSentinel) {
try {
vector<string> sentinelSubCommands = g_redisArgMap[argument]->Extract(n, argc, argv);
for (auto p : sentinelSubCommands) {
params.push_back(p);
}
}
catch (invalid_argument iaerr) {
// if no subcommands could be mapped, then assume this is the parameterless --sentinel command line only argument
}
} else if (argument == cServiceRun) {
// When the service starts the current directory is %systemdir%. This needs to be changed to the
// directory the executable is in so that the .conf file can be loaded.
char szFilePath[MAX_PATH];
if (GetModuleFileNameA(NULL, szFilePath, MAX_PATH) == 0) {
throw std::system_error(GetLastError(), system_category(), "ParseCommandLineArguments: GetModuleFileName failed");
}
string currentDir = szFilePath;
auto pos = currentDir.rfind("\\");
currentDir.erase(pos);
if (FALSE == SetCurrentDirectoryA(currentDir.c_str())) {
throw std::system_error(GetLastError(), system_category(), "SetCurrentDirectory failed");
}
} else {
params = g_redisArgMap[argument]->Extract(n, argc, argv);
}
g_argMap[argument].push_back(params);
n += (int) params.size();
}
g_argMap[argument].push_back(params);
n += (int)params.size();
} else if (string(argv[n]).substr(0, 1) == "-") {
// Do nothing, the - arguments are passed to redis.c::main() as they are
} else {
confFile = true;
confFilePath = argv[n];
@@ -641,7 +654,9 @@ void ParseCommandLineArguments(int argc, char** argv) {
throw std::system_error(GetLastError(), system_category(), "ParseCommandLineArguments: GetCurrentDirectoryA failed");
}
if (confFile) ParseConfFile(confFilePath, cwd, g_argMap);
if (confFile) {
ParseConfFile(confFilePath, cwd, g_argMap);
}
// grab directory where RDB/AOF/DAT files will be created so that service install can add access allowed ACE to path
string fileCreationDirectory = ".\\";
+3
View File
@@ -64,3 +64,6 @@ const string cNo = "no";
const string cDefaultSyslogIdent = "redis";
const string cDefaultLogfile = "stdout";
/* List of -- command arguments to be passed to redis::main() unaltered */
const vector<string> cRedisArgsForMainC = {"help", "version", "test-memory"};
+2 -2
View File
@@ -32,7 +32,7 @@
#include "Win32_ANSI.h"
#include "win32_util.h"
#include <string>
#include "..\redisLog.h"
#include "Win32_RedisLog.h"
using namespace std;
#define CATCH_AND_REPORT() catch(const std::exception &){::redisLog(REDIS_WARNING, "FDAPI: std exception");}catch(...){::redisLog(REDIS_WARNING, "FDAPI: other exception");}
@@ -1138,7 +1138,7 @@ BOOL ParseStorageAddress(const char *ip, int port, SOCKADDR_STORAGE* pSotrageAdd
return TRUE;
}
int StorageSize(SOCKADDR_STORAGE *ss) {
int StorageSize(const SOCKADDR_STORAGE *ss) {
switch (ss->ss_family) {
case AF_INET:
return sizeof(SOCKADDR_IN);
+1 -1
View File
@@ -260,7 +260,7 @@ int FDAPI_UpdateAcceptContext( int fd );
// other networking functions
BOOL ParseStorageAddress(const char *ip, int port, SOCKADDR_STORAGE* pSotrageAddr);
int StorageSize(SOCKADDR_STORAGE *ss);
int StorageSize(const SOCKADDR_STORAGE *ss);
// macroize CRT definitions to point to our own
#ifndef FDAPI_NOCRTREDEFS
+11 -10
View File
@@ -19,7 +19,6 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\RedisLog.c" />
<ClCompile Include="win32fixes.c" />
<ClCompile Include="Win32_ANSI.c" />
<ClCompile Include="Win32_CommandLine.cpp" />
@@ -29,14 +28,16 @@
<ClCompile Include="Win32_fdapi_crt.cpp" />
<ClCompile Include="Win32_QFork.cpp" />
<ClCompile Include="Win32_QFork_impl.c" />
<ClCompile Include="Win32_RedisLog.c" />
<ClCompile Include="win32_rfdmap.cpp" />
<ClCompile Include="Win32_service.cpp" />
<ClCompile Include="Win32_StackTrace.cpp" />
<ClCompile Include="Win32_ThreadControl.c" />
<ClCompile Include="win32_util.c" />
<ClCompile Include="Win32_variadicFunctor.cpp" />
<ClCompile Include="win32_wsiocp.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\redisLog.h" />
<ClInclude Include="win32fixes.h" />
<ClInclude Include="Win32_ANSI.h" />
<ClInclude Include="Win32_CommandLine.h" />
@@ -46,9 +47,13 @@
<ClInclude Include="Win32_fdapi_crt.h" />
<ClInclude Include="Win32_QFork.h" />
<ClInclude Include="Win32_QFork_impl.h" />
<ClInclude Include="Win32_RedisLog.h" />
<ClInclude Include="win32_rfdmap.h" />
<ClInclude Include="Win32_Service.h" />
<ClInclude Include="Win32_SmartHandle.h" />
<ClInclude Include="Win32_StackTrace.h" />
<ClInclude Include="Win32_ThreadControl.h" />
<ClInclude Include="win32_types.h" />
<ClInclude Include="win32_util.h" />
<ClInclude Include="Win32_variadicFunctor.h" />
<ClInclude Include="win32_winapifamily.h" />
@@ -150,8 +155,7 @@ link.exe -dll -noentry resources/EventLog.res -out:$(TargetDir)EventLog.dll
</Link>
<Lib>
<IgnoreSpecificDefaultLibraries>MSVCRT</IgnoreSpecificDefaultLibraries>
<AdditionalDependencies>
</AdditionalDependencies>
<AdditionalDependencies>DbgHelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@@ -170,8 +174,7 @@ link.exe -dll -noentry resources/EventLog.res -out:$(TargetDir)EventLog.dll
</Link>
<Lib>
<IgnoreSpecificDefaultLibraries>MSVCRT</IgnoreSpecificDefaultLibraries>
<AdditionalDependencies>
</AdditionalDependencies>
<AdditionalDependencies>DbgHelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
<CustomBuild>
<Command>
@@ -198,8 +201,7 @@ link.exe -dll -noentry resources/EventLog.res -out:$(TargetDir)EventLog.dll
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Lib>
<AdditionalDependencies>
</AdditionalDependencies>
<AdditionalDependencies>DbgHelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -221,8 +223,7 @@ link.exe -dll -noentry resources/EventLog.res -out:$(TargetDir)EventLog.dll
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Lib>
<AdditionalDependencies>
</AdditionalDependencies>
<AdditionalDependencies>DbgHelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
<CustomBuild>
<Command>
+99 -84
View File
@@ -21,7 +21,6 @@
*/
#include "win32_types.h"
#include "Win32_FDAPI.h"
#include <Windows.h>
@@ -42,7 +41,9 @@
#include "Win32_SmartHandle.h"
#include "Win32_Service.h"
#include "Win32_CommandLine.h"
#include "..\redisLog.h"
#include "Win32_RedisLog.h"
#include "Win32_StackTrace.h"
#include "Win32_ThreadControl.h"
#include <vector>
#include <map>
@@ -52,6 +53,7 @@
#include <exception>
#include <algorithm>
#include <memory>
using namespace std;
#ifndef PAGE_REVERT_TO_FILE_MAP
@@ -188,9 +190,9 @@ struct QForkControl {
QForkControl* g_pQForkControl;
HANDLE g_hQForkControlFileMap;
HANDLE g_hForkedProcess;
HANDLE g_hForkedProcess = 0;
DWORD g_systemAllocationGranularity;
int g_SlaveExitCode = 0; // For slave process
int g_ChildExitCode = 0; // For child process
bool ReportSpecialSystemErrors(int error) {
switch (error)
@@ -246,27 +248,27 @@ bool ReportSpecialSystemErrors(int error) {
}
}
BOOL QForkSlaveInit(HANDLE QForkConrolMemoryMapHandle, DWORD ParentProcessID) {
BOOL QForkChildInit(HANDLE QForkConrolMemoryMapHandle, DWORD ParentProcessID) {
try {
SmartHandle shParent(
OpenProcess(SYNCHRONIZE | PROCESS_DUP_HANDLE, TRUE, ParentProcessID),
string("Could not open parent process"));
SmartHandle shMMFile(shParent, QForkConrolMemoryMapHandle);
SmartFileView<QForkControl> sfvMasterQForkControl(
SmartFileView<QForkControl> sfvParentQForkControl(
shMMFile,
FILE_MAP_COPY,
string("Could not map view of QForkControl in slave. Is system swap file large enough?"));
g_pQForkControl = sfvMasterQForkControl;
string("Could not map view of QForkControl in child. Is system swap file large enough?"));
g_pQForkControl = sfvParentQForkControl;
// duplicate handles and stuff into control structure (master protected by PAGE_WRITECOPY)
SmartHandle dupHeapFileHandle(shParent, sfvMasterQForkControl->heapMemoryMapFile);
// duplicate handles and stuff into control structure (parent protected by PAGE_WRITECOPY)
SmartHandle dupHeapFileHandle(shParent, sfvParentQForkControl->heapMemoryMapFile);
g_pQForkControl->heapMemoryMapFile = dupHeapFileHandle;
SmartHandle dupForkedProcessReady(shParent,sfvMasterQForkControl->forkedProcessReady);
SmartHandle dupForkedProcessReady(shParent, sfvParentQForkControl->forkedProcessReady);
g_pQForkControl->forkedProcessReady = dupForkedProcessReady;
SmartHandle dupOperationComplete(shParent,sfvMasterQForkControl->operationComplete);
SmartHandle dupOperationComplete(shParent, sfvParentQForkControl->operationComplete);
g_pQForkControl->operationComplete = dupOperationComplete;
SmartHandle dupOperationFailed(shParent,sfvMasterQForkControl->operationFailed);
SmartHandle dupOperationFailed(shParent, sfvParentQForkControl->operationFailed);
g_pQForkControl->operationFailed = dupOperationFailed;
// create section handle on MM file
@@ -280,7 +282,7 @@ BOOL QForkSlaveInit(HANDLE QForkConrolMemoryMapHandle, DWORD ParentProcessID) {
0,
#endif
LODWORD(mmSize),
string("Could not open file mapping object in slave"));
string("Could not open file mapping object in child"));
g_pQForkControl->heapMemoryMap = sfmhMapFile;
@@ -306,9 +308,9 @@ BOOL QForkSlaveInit(HANDLE QForkConrolMemoryMapHandle, DWORD ParentProcessID) {
// execute requested operation
if (g_pQForkControl->typeOfOperation == OperationType::otRDB) {
g_SlaveExitCode = do_rdbSave(g_pQForkControl->globalData.filename);
g_ChildExitCode = do_rdbSave(g_pQForkControl->globalData.filename);
} else if (g_pQForkControl->typeOfOperation == OperationType::otAOF) {
g_SlaveExitCode = do_aofSave(g_pQForkControl->globalData.filename);
g_ChildExitCode = do_aofSave(g_pQForkControl->globalData.filename);
} 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);
@@ -321,7 +323,7 @@ BOOL QForkSlaveInit(HANDLE QForkConrolMemoryMapHandle, DWORD ParentProcessID) {
WSA_FLAG_OVERLAPPED);
}
g_SlaveExitCode = do_socketSave(g_pQForkControl->globalData.fds,
g_ChildExitCode = do_socketSave(g_pQForkControl->globalData.fds,
g_pQForkControl->globalData.numfds,
g_pQForkControl->globalData.clientids,
pipe_write_fd);
@@ -337,21 +339,18 @@ BOOL QForkSlaveInit(HANDLE QForkConrolMemoryMapHandle, DWORD ParentProcessID) {
}
catch(std::system_error syserr) {
if (ReportSpecialSystemErrors(syserr.code().value()) == false) {
::redisLog(REDIS_WARNING, "QForkSlaveInit: system error caught. error code=0x%08x, message=%s\n", syserr.code().value(), syserr.what());
g_pQForkControl = NULL;
if (g_pQForkControl != NULL) {
if (g_pQForkControl->operationFailed != NULL) {
SetEvent(g_pQForkControl->operationFailed);
}
}
return FALSE;
::redisLog(REDIS_WARNING, "QForkChildInit: system error caught. error code=0x%08x, message=%s\n", syserr.code().value(), syserr.what());
}
}
catch(std::runtime_error runerr) {
::redisLog(REDIS_WARNING, "QForkSlaveInit: runtime error caught. message=%s\n", runerr.what());
::redisLog(REDIS_WARNING, "QForkChildInit: runtime error caught. message=%s\n", runerr.what());
}
if (g_pQForkControl != NULL) {
if (g_pQForkControl->operationFailed != NULL) {
SetEvent(g_pQForkControl->operationFailed);
}
g_pQForkControl = NULL;
SetEvent(g_pQForkControl->operationFailed);
return FALSE;
}
return FALSE;
}
@@ -409,7 +408,7 @@ string GetWorkingDirectory() {
return g_MMFDir;
}
BOOL QForkMasterInit( __int64 maxheapBytes ) {
BOOL QForkParentInit(__int64 maxheapBytes) {
try {
// allocate file map for qfork control so it can be passed to the forked process
g_hQForkControlFileMap = CreateFileMappingW(
@@ -505,13 +504,7 @@ BOOL QForkMasterInit( __int64 maxheapBytes ) {
"CreateFileW failed.");
}
// There is a strange random failure toawrds the end of mapping the heap in the forked process in the VEH if
// the underlying MMF is not larger than the MM space we are using. This seems to be some sort of
// memory->file allocation granularity issue. Increasing the size of the file (by 16MB) takes care of the
// issue in all cases.
const size_t extraMMF = 64 * cAllocationGranularity;
SIZE_T mmSize = g_pQForkControl->availableBlocksInHeap * cAllocationGranularity + extraMMF;
SIZE_T mmSize = g_pQForkControl->availableBlocksInHeap * cAllocationGranularity;
g_pQForkControl->heapMemoryMap =
CreateFileMappingW(
g_pQForkControl->heapMemoryMapFile,
@@ -600,14 +593,14 @@ BOOL QForkMasterInit( __int64 maxheapBytes ) {
}
catch(std::system_error syserr) {
if (ReportSpecialSystemErrors(syserr.code().value()) == false) {
::redisLog(REDIS_WARNING, "QForkMasterInit: system error caught. error code=0x%08x, message=%s\n", syserr.code().value(), syserr.what());
::redisLog(REDIS_WARNING, "QForkParentInit: system error caught. error code=0x%08x, message=%s\n", syserr.code().value(), syserr.what());
}
}
catch(std::runtime_error runerr) {
::redisLog(REDIS_WARNING, "QForkMasterInit: runtime error caught. message=%s\n", runerr.what());
::redisLog(REDIS_WARNING, "QForkParentInit: runtime error caught. message=%s\n", runerr.what());
}
catch(...) {
::redisLog(REDIS_WARNING, "QForkMasterInit: other exception caught.\n");
::redisLog(REDIS_WARNING, "QForkParentInit: other exception caught.\n");
}
return FALSE;
}
@@ -642,15 +635,24 @@ LONG CALLBACK VectoredHeapMapper(PEXCEPTION_POINTERS info) {
else
{
DWORD err = GetLastError();
::redisLog(REDIS_WARNING, "MapViewOfFileEx failed with error 0x%08X.\n", err);
::redisLog(REDIS_WARNING, "\n\n=== REDIS BUG REPORT START: Cut & paste starting from here ===");
::redisLog(REDIS_WARNING, "--- FATAL ERROR MAPPING VIEW OF MAP FILE");
::redisLog(REDIS_WARNING, "\t MapViewOfFileEx failed with error 0x%08X.", err);
::redisLog(REDIS_WARNING, "\t startOfMapping 0x%p", startOfMapping);
::redisLog(REDIS_WARNING, "\t heapStart 0x%p\n", heapStart);
::redisLog(REDIS_WARNING, "\t heapEnd 0x%p\n", heapEnd);
::redisLog(REDIS_WARNING, "\t failing access location 0x%p\n", failingMemoryAddress);
::redisLog(REDIS_WARNING, "\t offset into mmf to start mapping 0x%p\n", mmfOffset);
::redisLog(REDIS_WARNING, "\t start of new mapping 0x%p\n", startOfMapping);
::redisLog(REDIS_WARNING, "\t heapStart 0x%p", heapStart);
::redisLog(REDIS_WARNING, "\t heapEnd 0x%p", heapEnd);
::redisLog(REDIS_WARNING, "\t failing access location 0x%p", failingMemoryAddress);
::redisLog(REDIS_WARNING, "\t offset into mmf to start mapping 0x%p", mmfOffset);
::redisLog(REDIS_WARNING, "\t start of new mapping 0x%p", startOfMapping);
::redisLog(REDIS_WARNING, "\t bytes to map 0x%p\n", bytesToMap);
::redisLog(REDIS_WARNING, "\t continuing exception handler search\n");
if (err == 0x000005AF) {
::redisLog(REDIS_WARNING, "The system paging file is too small for this operation to complete.");
::redisLog(REDIS_WARNING, "See https://github.com/MSOpenTech/redis/wiki/Memory-Configuration");
::redisLog(REDIS_WARNING, "for more information on configuring the system paging file for Redis.");
}
::redisLog(REDIS_WARNING, "\n=== REDIS BUG REPORT END. Make sure to include from START to END. ===\n\n");
// Call exit to avoid executing the Unhandled Exceptiont Handler since we don't need a call stack
exit(1);
}
}
}
@@ -660,7 +662,8 @@ LONG CALLBACK VectoredHeapMapper(PEXCEPTION_POINTERS info) {
// QFork API
StartupStatus QForkStartup(int argc, char** argv) {
bool foundSlaveFlag = false;
bool foundChildFlag = false;
int sentinelMode = checkForSentinelMode(argc, argv);
HANDLE QForkConrolMemoryMapHandle = NULL;
DWORD PPID = 0;
__int64 maxheapBytes = -1;
@@ -672,8 +675,8 @@ StartupStatus QForkStartup(int argc, char** argv) {
g_systemAllocationGranularity = si.dwAllocationGranularity;
if (g_argMap.find(cQFork) != g_argMap.end()) {
// slave command line looks like: --QFork [QForkConrolMemoryMap handle] [parent process id]
foundSlaveFlag = true;
// Child command line looks like: --QFork [QForkConrolMemoryMap handle] [parent process id]
foundChildFlag = true;
char* endPtr;
QForkConrolMemoryMapHandle = (HANDLE)strtoul(g_argMap[cQFork].at(0).at(0).c_str(),&endPtr,10);
char* end = NULL;
@@ -732,11 +735,13 @@ StartupStatus QForkStartup(int argc, char** argv) {
*/
int64_t maxMemoryPlusHalf = (3 * maxmemoryBytes) / 2;
if( maxmemoryBytes != -1 ) {
maxheapBytes = (maxheapBytes > maxMemoryPlusHalf) ? maxheapBytes : maxMemoryPlusHalf;
if (maxheapBytes < maxMemoryPlusHalf) {
maxheapBytes = maxMemoryPlusHalf;
}
}
if( maxheapBytes == -1 )
{
if (checkForSentinelMode(argc, argv)) {
if( maxheapBytes == -1 ) {
if (sentinelMode == 1) {
// Sentinel mode does not need a large heap. This conserves disk space and page file reservation requirements.
maxheapBytes = cSentinelHeapSize;
} else {
@@ -748,16 +753,16 @@ StartupStatus QForkStartup(int argc, char** argv) {
}
}
if (foundSlaveFlag) {
if (foundChildFlag) {
LPVOID exceptionHandler = AddVectoredExceptionHandler( 1, VectoredHeapMapper );
StartupStatus retVal = StartupStatus::ssFAILED;
try {
retVal = QForkSlaveInit( QForkConrolMemoryMapHandle, PPID ) ? StartupStatus::ssSLAVE_EXIT : StartupStatus::ssFAILED;
retVal = QForkChildInit(QForkConrolMemoryMapHandle, PPID) ? StartupStatus::ssCHILD_EXIT : StartupStatus::ssFAILED;
} catch (...) { }
RemoveVectoredExceptionHandler(exceptionHandler);
return retVal;
} else {
return QForkMasterInit(maxheapBytes) ? StartupStatus::ssCONTINUE_AS_MASTER : StartupStatus::ssFAILED;
return QForkParentInit(maxheapBytes) ? StartupStatus::ssCONTINUE_AS_PARENT : StartupStatus::ssFAILED;
}
}
@@ -832,7 +837,7 @@ void CopyForkOperationData(OperationType type, LPVOID globalData, int sizeOfGlob
throw std::system_error(
GetLastError(),
system_category(),
"BeginForkOperation: VirtualProtect failed");
"BeginForkOperation: VirtualProtect failed for the fork control map");
}
if (VirtualProtect(
g_pQForkControl->heapStart,
@@ -842,7 +847,7 @@ void CopyForkOperationData(OperationType type, LPVOID globalData, int sizeOfGlob
throw std::system_error(
GetLastError(),
system_category(),
"BeginForkOperation: VirtualProtect failed");
"BeginForkOperation: VirtualProtect failed for the heap");
}
}
@@ -896,19 +901,20 @@ void CreateChildProcess(PROCESS_INFORMATION *pi, char* logfile, DWORD dwCreation
throw system_error(
GetLastError(),
system_category(),
"Problem creating slave process" );
"Problem creating child process" );
}
g_hForkedProcess = pi->hProcess;
}
typedef void (*CHILD_PID_HOOK)(DWORD pid);
BOOL BeginForkOperation(OperationType type, LPVOID globalData, int sizeOfGlobalData, DWORD* childPID, uint32_t dictHashSeed, char* logfile, CHILD_PID_HOOK pidHook = NULL) {
pid_t BeginForkOperation(OperationType type, LPVOID globalData, int sizeOfGlobalData, uint32_t dictHashSeed, char* logfile, CHILD_PID_HOOK pidHook = NULL) {
PROCESS_INFORMATION pi;
try {
pi.hProcess = INVALID_HANDLE_VALUE;
pi.dwProcessId = -1;
if(pidHook != NULL) {
if (pidHook != NULL) {
CreateChildProcess(&pi, logfile, CREATE_SUSPENDED);
pidHook(pi.dwProcessId);
CopyForkOperationData(type, globalData, sizeOfGlobalData, dictHashSeed);
@@ -918,7 +924,6 @@ BOOL BeginForkOperation(OperationType type, LPVOID globalData, int sizeOfGlobalD
CreateChildProcess(&pi, logfile, 0);
}
*childPID = pi.dwProcessId;
CloseHandle(pi.hThread);
// wait for "forked" process to map memory
@@ -929,7 +934,7 @@ BOOL BeginForkOperation(OperationType type, LPVOID globalData, int sizeOfGlobalD
"Forked Process did not respond in a timely manner.");
}
return TRUE;
return pi.dwProcessId;
}
catch(std::system_error syserr) {
::redisLog(REDIS_WARNING, "BeginForkOperation: system error caught. error code=0x%08x, message=%s\n", syserr.code().value(), syserr.what());
@@ -940,34 +945,32 @@ BOOL BeginForkOperation(OperationType type, LPVOID globalData, int sizeOfGlobalD
catch(...) {
::redisLog(REDIS_WARNING, "BeginForkOperation: other exception caught.\n");
}
if(pi.hProcess != INVALID_HANDLE_VALUE) {
if (pi.hProcess != INVALID_HANDLE_VALUE) {
TerminateProcess(pi.hProcess, 1);
}
return FALSE;
return -1;
}
BOOL BeginForkOperation_Rdb(
pid_t BeginForkOperation_Rdb(
char *filename,
LPVOID globalData,
int sizeOfGlobalData,
DWORD* childPID,
unsigned __int32 dictHashSeed,
char* logfile)
{
strcpy_s(g_pQForkControl->globalData.filename, filename);
return BeginForkOperation(otRDB, globalData, sizeOfGlobalData, childPID, dictHashSeed, logfile);
return BeginForkOperation(otRDB, globalData, sizeOfGlobalData, dictHashSeed, logfile);
}
BOOL BeginForkOperation_Aof(
pid_t BeginForkOperation_Aof(
char *filename,
LPVOID globalData,
int sizeOfGlobalData,
DWORD* childPID,
unsigned __int32 dictHashSeed,
char* logfile)
{
strcpy_s(g_pQForkControl->globalData.filename, filename);
return BeginForkOperation(otAOF, globalData, sizeOfGlobalData, childPID, dictHashSeed, logfile);
return BeginForkOperation(otAOF, globalData, sizeOfGlobalData, dictHashSeed, logfile);
}
void BeginForkOperation_Socket_PidHook(DWORD dwProcessId) {
@@ -978,14 +981,13 @@ void BeginForkOperation_Socket_PidHook(DWORD dwProcessId) {
}
}
BOOL BeginForkOperation_Socket(
pid_t BeginForkOperation_Socket(
int *fds,
int numfds,
uint64_t *clientids,
int pipe_write_fd,
LPVOID globalData,
int sizeOfGlobalData,
DWORD* childPID,
unsigned __int32 dictHashSeed,
char* logfile)
{
@@ -1001,7 +1003,6 @@ BOOL BeginForkOperation_Socket(
return BeginForkOperation(otSocket,
globalData,
sizeOfGlobalData,
childPID,
dictHashSeed,
logfile,
BeginForkOperation_Socket_PidHook);
@@ -1016,8 +1017,20 @@ OperationStatus GetForkOperationStatus() {
return OperationStatus::osFAILED;
}
if (WaitForSingleObject(g_pQForkControl->forkedProcessReady, 0) == WAIT_OBJECT_0) {
return OperationStatus::osINPROGRESS;
if (g_hForkedProcess && WaitForSingleObject(g_pQForkControl->forkedProcessReady, 0) == WAIT_OBJECT_0) {
// Verify if the child process is still running
if (WaitForSingleObject(g_hForkedProcess, 0) == WAIT_OBJECT_0) {
// The child process is not running, close the handle and report the status
// setting the operationFailed event
CloseHandle(g_hForkedProcess);
g_hForkedProcess = 0;
if (g_pQForkControl->operationFailed != NULL) {
SetEvent(g_pQForkControl->operationFailed);
}
return OperationStatus::osFAILED;
} else {
return OperationStatus::osINPROGRESS;
}
}
return OperationStatus::osUNSTARTED;
@@ -1034,8 +1047,8 @@ BOOL AbortForkOperation()
system_category(),
"EndForkOperation: Killing forked process failed.");
}
g_hForkedProcess = 0;
CloseHandle(g_hForkedProcess);
g_hForkedProcess = 0;
}
return EndForkOperation(NULL);
@@ -1117,7 +1130,7 @@ void RejoinCOWPages(HANDLE mmHandle, byte* mmStart, size_t mmSize) {
throw std::system_error(
GetLastError(),
system_category(),
"RejoinCOWPages: MapViewOfFileEx failed. Please upgrade your OS to Win8 or newer.");
"RejoinCOWPages: MapViewOfFileEx failed.");
}
}
}
@@ -1136,7 +1149,7 @@ BOOL EndForkOperation(int * pExitCode) {
}
if (pExitCode != NULL) {
GetExitCodeProcess(g_hForkedProcess, (DWORD*)pExitCode);
GetExitCodeProcess(g_hForkedProcess, (DWORD*)pExitCode);
}
CloseHandle(g_hForkedProcess);
@@ -1319,6 +1332,8 @@ extern "C"
InitTimeFunctions();
ParseCommandLineArguments(argc, argv);
SetupLogging();
StackTraceInit();
InitThreadControl();
} catch (system_error syserr) {
exit(-1);
} catch (runtime_error runerr) {
@@ -1367,16 +1382,16 @@ extern "C"
if (IsPersistenceAvailable() == TRUE) {
StartupStatus status = QForkStartup(argc, argv);
if (status == ssCONTINUE_AS_MASTER) {
if (status == ssCONTINUE_AS_PARENT) {
int retval = redis_main(argc, argv);
QForkShutdown();
return retval;
} else if (status == ssSLAVE_EXIT) {
// slave is done - clean up and exit
} else if (status == ssCHILD_EXIT) {
// child is done - clean up and exit
QForkShutdown();
return g_SlaveExitCode;
return g_ChildExitCode;
} else if (status == ssFAILED) {
// master or slave failed initialization
// parent or child failed initialization
return 1;
} else {
// unexpected status return
+6 -9
View File
@@ -45,8 +45,8 @@ typedef enum operationStatus {
typedef enum startupStatus {
ssFAILED = 0, // Something went wrong, exit program with error.
ssCONTINUE_AS_MASTER = 1, // Master qfork initialization complete, continue as master instance. Call QForkShutdown when exiting.
ssSLAVE_EXIT = 2 // Slave completed operation. Call QForkShutdown and exit.
ssCONTINUE_AS_PARENT = 1, // Parent qfork initialization complete, continue as parent instance. Call QForkShutdown when exiting.
ssCHILD_EXIT = 2 // Child completed operation. Call QForkShutdown and exit.
} StartupStatus;
#define MAX_GLOBAL_DATA 10000
@@ -65,31 +65,28 @@ typedef struct QForkBeginInfo {
StartupStatus QForkStartup(int argc, char** argv);
BOOL QForkShutdown();
// For master process use only
BOOL BeginForkOperation_Rdb(
// For parent process use only
pid_t BeginForkOperation_Rdb(
char* fileName,
LPVOID globalData,
int sizeOfGlobalData,
DWORD* childPID,
unsigned __int32 dictHashSeed,
char* logfile);
BOOL BeginForkOperation_Aof(
pid_t BeginForkOperation_Aof(
char* fileName,
LPVOID globalData,
int sizeOfGlobalData,
DWORD* childPID,
unsigned __int32 dictHashSeed,
char* logfile);
BOOL BeginForkOperation_Socket(
pid_t BeginForkOperation_Socket(
int *fds,
int numfds,
uint64_t *clientids,
int pipe_write_fd,
LPVOID globalData,
int sizeOfGlobalData,
DWORD* childPID,
unsigned __int32 dictHashSeed,
char* logfile);
@@ -20,16 +20,16 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "win32_Interop/win32_types.h"
#include "redisLog.h"
#include "Win32_types.h"
#include "Win32_RedisLog.h"
#include <stdio.h>
#include <stdarg.h>
#include <malloc.h>
#include <string.h>
#include <process.h>
#include "redis.h"
#include "win32_Interop/win32Fixes.h"
#include "win32_Interop/Win32_EventLog.h"
#include "../redis.h"
#include "Win32Fixes.h"
#include "Win32_EventLog.h"
#include <time.h>
#include <assert.h>
+219
View File
@@ -0,0 +1,219 @@
/*
* 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_StackTrace.h"
#include "Win32_RedisLog.h"
#include <DbgHelp.h>
#include <signal.h>
#include <stdio.h>
static IMAGEHLP_SYMBOL64* pSymbol = (IMAGEHLP_SYMBOL64*) malloc(sizeof(IMAGEHLP_SYMBOL64) + MAX_PATH*sizeof(TCHAR));
static IMAGEHLP_LINE64 line;
static BOOLEAN processingException = FALSE;
static CHAR modulePath[MAX_PATH];
static LPTOP_LEVEL_EXCEPTION_FILTER defaultTopLevelExceptionHandler = NULL;
static const char* exceptionDescription(const DWORD& code)
{
switch (code) {
case EXCEPTION_ACCESS_VIOLATION: return "EXCEPTION_ACCESS_VIOLATION";
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: return "EXCEPTION_ARRAY_BOUNDS_EXCEEDED";
case EXCEPTION_BREAKPOINT: return "EXCEPTION_BREAKPOINT";
case EXCEPTION_DATATYPE_MISALIGNMENT: return "EXCEPTION_DATATYPE_MISALIGNMENT";
case EXCEPTION_FLT_DENORMAL_OPERAND: return "EXCEPTION_FLT_DENORMAL_OPERAND";
case EXCEPTION_FLT_DIVIDE_BY_ZERO: return "EXCEPTION_FLT_DIVIDE_BY_ZERO";
case EXCEPTION_FLT_INEXACT_RESULT: return "EXCEPTION_FLT_INEXACT_RESULT";
case EXCEPTION_FLT_INVALID_OPERATION: return "EXCEPTION_FLT_INVALID_OPERATION";
case EXCEPTION_FLT_OVERFLOW: return "EXCEPTION_FLT_OVERFLOW";
case EXCEPTION_FLT_STACK_CHECK: return "EXCEPTION_FLT_STACK_CHECK";
case EXCEPTION_FLT_UNDERFLOW: return "EXCEPTION_FLT_UNDERFLOW";
case EXCEPTION_ILLEGAL_INSTRUCTION: return "EXCEPTION_ILLEGAL_INSTRUCTION";
case EXCEPTION_IN_PAGE_ERROR: return "EXCEPTION_IN_PAGE_ERROR";
case EXCEPTION_INT_DIVIDE_BY_ZERO: return "EXCEPTION_INT_DIVIDE_BY_ZERO";
case EXCEPTION_INT_OVERFLOW: return "EXCEPTION_INT_OVERFLOW";
case EXCEPTION_INVALID_DISPOSITION: return "EXCEPTION_INVALID_DISPOSITION";
case EXCEPTION_NONCONTINUABLE_EXCEPTION: return "EXCEPTION_NONCONTINUABLE_EXCEPTION";
case EXCEPTION_PRIV_INSTRUCTION: return "EXCEPTION_PRIV_INSTRUCTION";
case EXCEPTION_SINGLE_STEP: return "EXCEPTION_SINGLE_STEP";
case EXCEPTION_STACK_OVERFLOW: return "EXCEPTION_STACK_OVERFLOW";
default: return "UNKNOWN EXCEPTION";
}
}
/* Returns the index of the last backslash in the file path */
int GetFilenameStart(CHAR* path) {
int pos = 0;
int found = 0;
if (path != NULL) {
while (path[pos] != '\0' && pos < MAX_PATH) {
if (path[pos] == '\\') {
found = pos + 1;
}
++pos;
}
}
return found;
}
#ifdef _WIN64
void LogStackTrace() {
BOOL result;
HANDLE thread;
HANDLE process;
CONTEXT context;
STACKFRAME64 stack;
ULONG frame;
DWORD64 dw64Displacement;
DWORD dwDisplacement;
memset(&stack, 0, sizeof(STACKFRAME64));
memset(pSymbol, '\0', sizeof(*pSymbol) + MAX_PATH);
memset(&modulePath[0], '\0', sizeof(modulePath));
line.LineNumber = 0;
RtlCaptureContext(&context);
process = GetCurrentProcess();
thread = GetCurrentThread();
dw64Displacement = 0;
stack.AddrPC.Offset = context.Rip;
stack.AddrPC.Mode = AddrModeFlat;
stack.AddrStack.Offset = context.Rsp;
stack.AddrStack.Mode = AddrModeFlat;
stack.AddrFrame.Offset = context.Rbp;
stack.AddrFrame.Mode = AddrModeFlat;
for (frame = 0;; frame++){
result = StackWalk64(
IMAGE_FILE_MACHINE_AMD64,
process,
thread,
&stack,
&context,
NULL,
SymFunctionTableAccess64,
SymGetModuleBase64,
NULL
);
pSymbol->MaxNameLength = MAX_PATH;
pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
SymGetSymFromAddr64(process, stack.AddrPC.Offset, &dw64Displacement, pSymbol);
SymGetLineFromAddr64(process, stack.AddrPC.Offset, &dwDisplacement, &line);
DWORD64 moduleBase = SymGetModuleBase64(process, stack.AddrPC.Offset);
if (moduleBase)
{
GetModuleFileNameA((HINSTANCE) moduleBase, modulePath, MAX_PATH);
}
redisLog(REDIS_WARNING | REDIS_LOG_RAW, "%s!%s(%s:%d)(0x%08LX, 0x%08LX, 0x%08LX, 0x%08LX)\n",
&modulePath[GetFilenameStart(modulePath)],
pSymbol->Name,
line.FileName,
line.LineNumber,
stack.Params[0],
stack.Params[1],
stack.Params[2],
stack.Params[3]
);
if (!result) {
break;
}
}
}
#else
void LogStackTrace() {}
#endif
void StackTraceInfo() {
redisLog(REDIS_WARNING, "--- STACK TRACE");
LogStackTrace();
}
void ServerInfo() {
redisLog(REDIS_WARNING, "--- INFO OUTPUT");
// Call antirez routine to log the info output
redisLogRaw(REDIS_WARNING | REDIS_LOG_RAW, genRedisInfoString("all"));
}
void BugReportEnd(){
redisLogRaw(REDIS_WARNING,
"\n=== REDIS BUG REPORT END. Make sure to include from START to END. ===\n\n"
" Please report this bug by following the instructions at:\n\n"
" http://github.com/MSOpenTech/redis/wiki/Submitting-an-Issue\n\n"
" Suspect RAM error? Use redis-server --test-memory to verify it.\n\n"
);
}
LONG WINAPI UnhandledExceptiontHandler(PEXCEPTION_POINTERS info) {
if (!processingException) {
try {
const char* exDescription = "Exception code not available";
processingException = true;
if (info->ExceptionRecord != NULL && info->ExceptionRecord->ExceptionCode != NULL) {
exDescription = exceptionDescription(info->ExceptionRecord->ExceptionCode);
}
// Call antirez routine to log the start of the bug report
bugReportStart();
redisLog(REDIS_WARNING, "--- %s", exDescription);
StackTraceInfo();
//ServerInfo();
BugReportEnd();
processingException = false;
}
catch (...) {};
}
if (defaultTopLevelExceptionHandler != NULL) {
defaultTopLevelExceptionHandler(info);
}
return EXCEPTION_CONTINUE_SEARCH;
}
/* Handler to trap abort() calls */
extern "C" void AbortHandler(int signal_number) {
bugReportStart();
redisLog(REDIS_WARNING, "--- ABORT");
StackTraceInfo();
BugReportEnd();
}
void InitSymbols() {
// Preload symbols so they will be available in case of out-of-memory exception
SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_UNDNAME);
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
HANDLE process = GetCurrentProcess();
SymInitialize(process, NULL, TRUE);
}
void StackTraceInit(void) {
InitSymbols();
// Global handler for unhandled exceptions
defaultTopLevelExceptionHandler = SetUnhandledExceptionFilter(UnhandledExceptiontHandler);
// Handler for abort()
signal(SIGABRT, &AbortHandler);
}
+32
View File
@@ -0,0 +1,32 @@
/*
* 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
#include "win32_types.h"
#include <Windows.h>
void StackTraceInit(void);
extern "C" typedef char *sds;
extern "C" sds genRedisInfoString(char *section);
extern "C" void bugReportStart(void);
+111
View File
@@ -0,0 +1,111 @@
/*
* 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 <Windows.h>
#include <assert.h>
volatile LONG g_NumWorkerThreads = 0;
// Safe mode means the threads are not touching the heap, or they are suspended because of an explicit suspension request
// Threads in safe mode because they are not touching the heap will block if trying to transition to unsafe mode while a suspension is requested
volatile LONG g_NumWorkerThreadsInSafeMode = 0;
volatile LONG g_SuspensionRequested = 0;
HANDLE g_hResumeFromSuspension;
CRITICAL_SECTION g_ThreadControlMutex;
void InitThreadControl() {
InitializeCriticalSection(&g_ThreadControlMutex);
g_hResumeFromSuspension = CreateEvent(NULL, TRUE, TRUE, NULL);
if (!g_hResumeFromSuspension) {
exit(GetLastError());
}
}
void IncrementWorkerThreadCount() {
EnterCriticalSection(&g_ThreadControlMutex);
g_NumWorkerThreads++;
LeaveCriticalSection(&g_ThreadControlMutex);
}
void DecrementWorkerThreadCount() {
EnterCriticalSection(&g_ThreadControlMutex);
g_NumWorkerThreads--;
LeaveCriticalSection(&g_ThreadControlMutex);
}
// Returns TRUE if threads are already in safe mode or suspended
BOOL SuspensionCompleted() {
BOOL result;
EnterCriticalSection(&g_ThreadControlMutex);
result = (g_NumWorkerThreadsInSafeMode == g_NumWorkerThreads);
LeaveCriticalSection(&g_ThreadControlMutex);
return result;
}
// This is meant to be called from the main thread only.
void RequestSuspension() {
if (!g_SuspensionRequested) {
if (!ResetEvent(g_hResumeFromSuspension)) {
exit(GetLastError());
}
_InterlockedOr(&g_SuspensionRequested, 1);
}
}
void ResumeFromSuspension() {
// This is meant to be called from the main thread only.
assert(g_SuspensionRequested && SuspensionCompleted());
_InterlockedAnd(&g_SuspensionRequested, 0);
if (!SetEvent(g_hResumeFromSuspension)) {
exit(GetLastError());
}
}
void WorkerThread_EnterSafeMode() {
EnterCriticalSection(&g_ThreadControlMutex);
g_NumWorkerThreadsInSafeMode++;
LeaveCriticalSection(&g_ThreadControlMutex);
}
void WorkerThread_ExitSafeMode() {
for(;;) {
EnterCriticalSection(&g_ThreadControlMutex);
if (g_SuspensionRequested) {
LeaveCriticalSection(&g_ThreadControlMutex);
if (WaitForSingleObject(g_hResumeFromSuspension, INFINITE) != WAIT_OBJECT_0) {
exit(GetLastError());
}
continue;
} else {
g_NumWorkerThreadsInSafeMode--;
LeaveCriticalSection(&g_ThreadControlMutex);
break;
}
}
}
@@ -19,19 +19,25 @@
* 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 */
#ifdef __cplusplus
extern "C" {
#endif
#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 InitThreadControl();
void IncrementWorkerThreadCount();
void DecrementWorkerThreadCount();
void RequestSuspension();
BOOL SuspensionCompleted();
void ResumeFromSuspension();
void SetVerbosity(int verbosity);
void WorkerThread_EnterSafeMode();
void WorkerThread_ExitSafeMode();
#ifdef __cplusplus
}
#endif
-8
View File
@@ -1702,10 +1702,6 @@ static FORCEINLINE void* win32mmap(size_t size) {
#else
void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
#endif
if( ptr == NULL )
{
printf( "VirtualAlloc/COWAlloc fail!\n");
}
return (ptr != 0)? ptr: MFAIL;
}
@@ -1716,10 +1712,6 @@ static FORCEINLINE void* win32direct_mmap(size_t size) {
#else
void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, PAGE_READWRITE);
#endif
if( ptr == NULL )
{
printf( "VirtualAlloc/COWAlloc fail!\n");
}
return (ptr != 0)? ptr: MFAIL;
}
+3 -3
View File
@@ -68,7 +68,7 @@ this should preceed the other arguments passed to redis. For instance:
#include <sstream>
#include <vector>
#include <iostream>
#include "..\redisLog.h"
#include "Win32_RedisLog.h"
#include "Win32_CommandLine.h"
using namespace std;
@@ -483,10 +483,10 @@ DWORD WINAPI ServiceWorkerThread(LPVOID lpParam) {
main(argc, argv);
for (int a = 0; a < argc; a++) {
delete argv[a];
delete[] argv[a];
argv[a] = nullptr;
}
delete argv;
delete[] argv;
argv = nullptr;
SetEvent(g_ServiceStoppedEvent);
+86 -99
View File
@@ -22,139 +22,126 @@
#include "win32_types.h"
#include "win32_rfdmap.h"
RFDMap& RFDMap::getInstance() {
static RFDMap instance; // Instantiated on first use. Guaranteed to be destroyed.
static RFDMap instance; // Instantiated on first use. Guaranteed to be destroyed.
return instance;
}
RFDMap::RFDMap() { maxRFD = minRFD; };
RFDMap::RFDMap() {
InitializeCriticalSection(&mutex);
maxRFD = minRFD;
}
RFD RFDMap::getNextRFDAvailable() {
if( RFDRecyclePool.empty() == false ) {
int RFD = RFDRecyclePool.front();
RFDRecyclePool.pop();
return RFD;
} else {
maxRFD = minRFD + (int)SocketToRFDMap.size() + (int)PosixFDToRFDMap.size();
return maxRFD;
}
RFD rfd;
EnterCriticalSection(&mutex);
if (RFDRecyclePool.empty() == false) {
rfd = RFDRecyclePool.front();
RFDRecyclePool.pop();
} else {
maxRFD = minRFD + (int) SocketToRFDMap.size() + (int) PosixFDToRFDMap.size();
rfd = maxRFD;
}
LeaveCriticalSection(&mutex);
return rfd;
}
RFD RFDMap::addSocket(SOCKET s) {
if (SocketToRFDMap.find(s) != SocketToRFDMap.end()) {
return invalidRFD;
}
RFD rfd = getNextRFDAvailable();
SocketToRFDMap[s] = rfd;
RFDToSocketMap[rfd] = s;
return rfd;
RFD rfd;
EnterCriticalSection(&mutex);
if (SocketToRFDMap.find(s) != SocketToRFDMap.end()) {
rfd = invalidRFD;
} else {
rfd = getNextRFDAvailable();
SocketToRFDMap[s] = rfd;
RFDToSocketMap[rfd] = s;
}
LeaveCriticalSection(&mutex);
return rfd;
}
void RFDMap::removeSocket(SOCKET s) {
S2RFDIterator mit = SocketToRFDMap.find(s);
if(mit == SocketToRFDMap.end()) {
// redisLog( REDIS_DEBUG, "RFDMap::removeSocket() - failed to find socket!" );
return;
void RFDMap::removeSocket(SOCKET s) {
EnterCriticalSection(&mutex);
S2RFDIterator mit = SocketToRFDMap.find(s);
if (mit != SocketToRFDMap.end()) {
RFD rfd = (*mit).second;
RFDRecyclePool.push(rfd);
RFDToSocketMap.erase(rfd);
SocketToRFDMap.erase(s);
}
RFD rfd = (*mit).second;
RFDRecyclePool.push(rfd);
RFDToSocketMap.erase(rfd);
SocketToRFDMap.erase(s);
LeaveCriticalSection(&mutex);
}
RFD RFDMap::addPosixFD(int posixFD) {
if (PosixFDToRFDMap.find(posixFD) != PosixFDToRFDMap.end()) {
// redisLog( REDIS_DEBUG, "RFDMap::addPosixFD() - posixFD already exists!" );
return invalidRFD;
}
RFD rfd = getNextRFDAvailable();
PosixFDToRFDMap[posixFD] = rfd;
RFDToPosixFDMap[rfd] = posixFD;
return rfd;
RFD rfd;
EnterCriticalSection(&mutex);
if (PosixFDToRFDMap.find(posixFD) != PosixFDToRFDMap.end()) {
rfd = invalidRFD;
} else {
rfd = getNextRFDAvailable();
PosixFDToRFDMap[posixFD] = rfd;
RFDToPosixFDMap[rfd] = posixFD;
}
LeaveCriticalSection(&mutex);
return rfd;
}
void RFDMap::removePosixFD(int posixFD) {
PosixFD2RFDIterator mit = PosixFDToRFDMap.find(posixFD);
if(mit == PosixFDToRFDMap.end()) {
// redisLog( REDIS_DEBUG, "RFDMap::removePosixFD() - failed to find posix FD!" );
return;
void RFDMap::removePosixFD(int posixFD) {
EnterCriticalSection(&mutex);
PosixFD2RFDIterator mit = PosixFDToRFDMap.find(posixFD);
if (mit != PosixFDToRFDMap.end()) {
RFD rfd = (*mit).second;
RFDRecyclePool.push(rfd);
RFDToPosixFDMap.erase(rfd);
PosixFDToRFDMap.erase(posixFD);
}
RFD rfd = (*mit).second;
RFDRecyclePool.push(rfd);
RFDToPosixFDMap.erase(rfd);
PosixFDToRFDMap.erase(posixFD);
LeaveCriticalSection(&mutex);
}
SOCKET RFDMap::lookupSocket(RFD rfd) {
if (RFDToSocketMap.find(rfd) != RFDToSocketMap.end()) {
return RFDToSocketMap[rfd];
} else {
// redisLog( REDIS_DEBUG, "RFDMap::lookupSocket() - failed to find socket!" );
return INVALID_SOCKET;
}
SOCKET socket = INVALID_SOCKET;
EnterCriticalSection(&mutex);
if (RFDToSocketMap.find(rfd) != RFDToSocketMap.end()) {
socket = RFDToSocketMap[rfd];
}
LeaveCriticalSection(&mutex);
return socket;
}
int RFDMap::lookupPosixFD(RFD rfd) {
if (RFDToPosixFDMap.find(rfd) != RFDToPosixFDMap.end()) {
return RFDToPosixFDMap[rfd];
} else if (rfd >= 0 && rfd <= 2) {
return rfd;
}
else {
// redisLog( REDIS_DEBUG, "RFDMap::lookupPosixFD() - failed to find posix FD!" );
return -1;
}
int posixFD = -1;
EnterCriticalSection(&mutex);
if (RFDToPosixFDMap.find(rfd) != RFDToPosixFDMap.end()) {
posixFD = RFDToPosixFDMap[rfd];
} else if (rfd >= 0 && rfd <= 2) {
posixFD = rfd;
}
LeaveCriticalSection(&mutex);
return posixFD;
}
RFD RFDMap::lookupRFD(SOCKET s) {
if (SocketToRFDMap.find(s) != SocketToRFDMap.end()) {
return SocketToRFDMap[s];
} else {
// redisLog( REDIS_DEBUG, "RFDMap::lookupFD() - failed to map SOCKET to RFD!" );
return invalidRFD;
}
}
RFD RFDMap::lookupRFD(int posixFD) {
if (PosixFDToRFDMap.find(posixFD) != PosixFDToRFDMap.end()) {
return PosixFDToRFDMap[posixFD];
} else {
// redisLog( REDIS_DEBUG, "RFDMap::lookupFD() - failed to map posixFD to RFD!" );
return invalidRFD;
}
}
RFD RFDMap::getMinRFD() {
return minRFD;
}
RFD RFDMap::getMaxRFD() {
return maxRFD;
}
bool RFDMap::SetSocketState( SOCKET s, RedisSocketState state )
{
bool RFDMap::SetSocketState(SOCKET s, RedisSocketState state) {
bool result = false;
EnterCriticalSection(&mutex);
S2StateIterator sit = SocketToStateMap.find(s);
if(sit != SocketToStateMap.end() ) {
if (sit != SocketToStateMap.end()) {
SocketToStateMap[s] = state;
return true;
} else {
return false;
result = true;
}
LeaveCriticalSection(&mutex);
return result;
}
bool RFDMap::GetSocketState( SOCKET s, RedisSocketState& state )
{
bool RFDMap::GetSocketState(SOCKET s, RedisSocketState& state) {
bool result = false;
EnterCriticalSection(&mutex);
S2StateIterator sit = SocketToStateMap.find(s);
if(sit != SocketToStateMap.end() ) {
if (sit != SocketToStateMap.end()) {
state = SocketToStateMap[s];
return true;
} else {
return false;
result = true;
}
LeaveCriticalSection(&mutex);
return result;
}
+37 -49
View File
@@ -23,15 +23,12 @@
#pragma once
#include <errno.h>
#define INCL_WINSOCK_API_PROTOTYPES 0 // Important! Do not include Winsock API definitions to avoid conflicts with API entry points defnied below.
#include <WinSock2.h>
#include "ws2tcpip.h"
//#include <io.h>
#include <map>
#include <queue>
using namespace std;
typedef struct {
@@ -69,65 +66,56 @@ public:
private:
RFDMap();
RFDMap(RFDMap const&); // Don't implement to guarantee singleton semantics
void operator=(RFDMap const&); // Don't implement to guarantee singleton semantics
RFDMap(RFDMap const&); // Don't implement to guarantee singleton semantics
void operator=(RFDMap const&); // Don't implement to guarantee singleton semantics
private:
SocketToRFDMapType SocketToRFDMap;
SocketToStateMapType SocketToStateMap;
SocketToRFDMapType SocketToRFDMap;
SocketToStateMapType SocketToStateMap;
PosixFDToRFDMapType PosixFDToRFDMap;
RFDToSocketMapType RFDToSocketMap;
RFDToPosixFDMapType RFDToPosixFDMap;
RFDRecyclePoolType RFDRecyclePool;
public:
const static int minRFD = 3; // 0, 1 and 2 are reserved for stdin, stdout and stderr
RFD maxRFD;
const static int invalidRFD = -1;
RFDToSocketMapType RFDToSocketMap;
RFDToPosixFDMapType RFDToPosixFDMap;
RFDRecyclePoolType RFDRecyclePool;
private:
/* Gets the next available Redis File Descriptor. Redis File Descriptors are always
non-negative integers, with the first three being reserved for stdin(0),
stdout(1) and stderr(2). */
RFD getNextRFDAvailable();
const static int minRFD = 3; // 0, 1 and 2 are reserved for stdin, stdout and stderr
RFD maxRFD;
CRITICAL_SECTION mutex;
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);
const static int invalidRFD = -1;
/* Removes a socket from the list of sockets. Also removes the associated
file descriptor. */
void removeSocket(SOCKET s);
private:
/* Gets the next available Redis File Descriptor. Redis File Descriptors are always
non-negative integers, with the first three being reserved for stdin(0),
stdout(1) and stderr(2). */
RFD getNextRFDAvailable();
/* Adds a posixFD (used with low-level CRT posix file functions) to the posixFD map. Returns
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);
/* Removes a socket from the list of sockets. Also removes the associated
file descriptor. */
void removeSocket(SOCKET s);
/* 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);
RFD addPosixFD(int posixFD);
/* Removes a socket from the list of sockets. Also removes the associated
file descriptor. */
void removePosixFD(int posixFD);
/* Returns the socket associated with a file descriptor. */
SOCKET lookupSocket(RFD rfd);
/* Removes a socket from the list of sockets. Also removes the associated
file descriptor. */
void removePosixFD(int posixFD);
/* Returns the socket associated with a file descriptor. */
int lookupPosixFD(RFD rfd);
SOCKET lookupSocket(RFD rfd);
/* Returns the RFD associated with a socket. */
RFD lookupRFD(SOCKET s);
/* Returns the socket associated with a file descriptor. */
int lookupPosixFD(RFD rfd);
/* Returns the RFD associated with a posix FD. */
RFD lookupRFD(int posixFD);
/* Returns the smallest RFD available */
RFD getMinRFD();
/* Returns the largest FD allocated so far */
RFD getMaxRFD();
bool SetSocketState( SOCKET s, RedisSocketState state );
bool GetSocketState( SOCKET s, RedisSocketState& state );
bool SetSocketState(SOCKET s, RedisSocketState state);
bool GetSocketState(SOCKET s, RedisSocketState& state);
};
+7 -7
View File
@@ -51,17 +51,17 @@ typedef __int64 PORT_LONGLONG;
typedef unsigned __int64 PORT_ULONGLONG;
typedef double PORT_LONGDOUBLE;
#if defined(_WIN64)
#ifdef _WIN64
typedef __int64 ssize_t;
typedef __int64 PORT_LONG;
typedef unsigned __int64 PORT_ULONG;
#else
typedef _W64 long ssize_t;
typedef _W64 long PORT_LONG;
typedef _W64 unsigned long PORT_ULONG;
typedef long ssize_t;
typedef long PORT_LONG;
typedef unsigned long PORT_ULONG;
#endif
#if defined(_WIN64)
#ifdef _WIN64
#define PORT_LONG_MAX _I64_MAX
#define PORT_LONG_MIN _I64_MIN
#define PORT_ULONG_MAX _UI64_MAX
@@ -72,6 +72,6 @@ typedef double PORT_LONGDOUBLE;
#endif
/* The maximum possible size_t value has all bits set */
#define MAX_SIZE_T (~(size_t)0)
#define MAX_SIZE_T (~(size_t)0)
typedef int pid_t;
+8 -10
View File
@@ -31,7 +31,6 @@
#include <errno.h>
#include <assert.h>
static void *iocpState;
static HANDLE iocph;
static fnGetSockState * aeGetSockState;
@@ -94,7 +93,7 @@ int aeWinQueueAccept(int listenfd) {
return -1;
}
return TRUE;
return 0;
}
/* listen using extension function to get faster accepts */
@@ -126,7 +125,7 @@ int aeWinListen(int rfd, int backlog) {
/* return the queued accept socket */
int aeWinAccept(int fd, struct sockaddr *sa, socklen_t *len) {
aeSockState *sockstate;
int acceptsock;
int acceptfd;
int result;
SOCKADDR *plocalsa;
SOCKADDR *premotesa;
@@ -139,7 +138,6 @@ int aeWinAccept(int fd, struct sockaddr *sa, socklen_t *len) {
return SOCKET_ERROR;
}
areq = sockstate->reqs;
if (areq == NULL) {
errno = EWOULDBLOCK;
@@ -148,9 +146,9 @@ int aeWinAccept(int fd, struct sockaddr *sa, socklen_t *len) {
sockstate->reqs = areq->next;
acceptsock = (int)areq->accept;
acceptfd = (int)areq->accept;
result = FDAPI_UpdateAcceptContext(acceptsock);
result = FDAPI_UpdateAcceptContext(acceptfd);
if (result == SOCKET_ERROR) {
errno = WSAGetLastError();
return SOCKET_ERROR;
@@ -158,7 +156,7 @@ int aeWinAccept(int fd, struct sockaddr *sa, socklen_t *len) {
locallen = *len;
FDAPI_GetAcceptExSockaddrs(
acceptsock,
acceptfd,
areq->buf,
0,
sizeof(struct sockaddr_storage),
@@ -170,10 +168,10 @@ int aeWinAccept(int fd, struct sockaddr *sa, socklen_t *len) {
memcpy(sa, premotesa, locallen);
*len = locallen;
aeWinSocketAttach(acceptsock);
aeWinSocketAttach(acceptfd);
// Save remote address to support aeWinGetPeerName()
if ((acceptsockstate = aeGetExistingSockState(iocpState, acceptsock)) == NULL) {
if ((acceptsockstate = aeGetExistingSockState(iocpState, acceptfd)) == NULL) {
errno = WSAEINVAL;
return SOCKET_ERROR;
}
@@ -187,7 +185,7 @@ int aeWinAccept(int fd, struct sockaddr *sa, socklen_t *len) {
return SOCKET_ERROR;
}
return acceptsock;
return acceptfd;
}
int aeWinGetPeerName(int fd, struct sockaddr *addr, socklen_t * addrlen) {
+11 -6
View File
@@ -20,6 +20,7 @@
#include <string.h>
#include <assert.h>
//#include <io.h>
#include "Win32_ThreadControl.h"
/* Redefined here to avoid redis.h so it can be used in other projects */
#define REDIS_NOTUSED(V) ((void) V)
@@ -149,12 +150,16 @@ typedef struct thread_params
/* Proxy function by windows thread requirements */
static unsigned __stdcall win32_proxy_threadproc(void *arg) {
IncrementWorkerThreadCount();
__try {
thread_params *p = (thread_params *) arg;
p->func(p->arg);
thread_params *p = (thread_params *) arg;
p->func(p->arg);
/* Dealocate params */
free(p);
/* Dealocate params */
free(p);
} __finally {
DecrementWorkerThreadCount();
}
_endthreadex(0);
return 0;
@@ -679,7 +684,7 @@ int truncate(const char *path, PORT_LONGLONG length) {
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)) {
if (FALSE == (SetFilePointerEx(toTruncate, newSize, NULL, FILE_BEGIN) && SetEndOfFile(toTruncate))) {
errno = ENOENT;
return -1;
} else {
-1
View File
@@ -178,7 +178,6 @@ int getrusage(int who, struct rusage * rusage);
#endif /*SIG_SETMASK*/
typedef void (*__p_sig_fn_t)(int);
typedef DWORD pid_t;
#ifndef _SIGSET_T_
#define _SIGSET_T_
+14 -34
View File
@@ -220,14 +220,14 @@ void stopAppendOnly(void) {
server.aof_state = REDIS_AOF_OFF;
/* rewrite operation in progress? kill it, wait child exit */
if (server.aof_child_pid != -1) {
redisLog(REDIS_NOTICE, "Killing running AOF rewrite child: %Id", /* PORTABILITY FIX %ld -> %Id */
redisLog(REDIS_NOTICE, "Killing running AOF rewrite child: %Id", WIN_PORT_FIX /* %ld -> %Id */
(PORT_LONG) server.aof_child_pid);
#ifdef _WIN32
AbortForkOperation();
#else
{
int statloc;
if (kill(server.aof_child_pid,SIGUSR1) != -1)
if (kill(server.aof_child_pid,SIGUSR1) != -1)
wait3(&statloc,0,NULL);
}
#endif
@@ -1289,36 +1289,6 @@ void aofClosePipes(void) {
* finally will rename(2) the temp file in the actual file name.
* The the new file is reopened as the new append only file. Profit!
*/
#ifdef _WIN32
int rewriteAppendOnlyFileBackground(void) {
PORT_LONGLONG start;
char tmpfile[256];
if (server.aof_child_pid != -1) return REDIS_ERR;
start = ustime();
snprintf(tmpfile,256,"temp-rewriteaof-bg-%d.aof", (int) getpid());
if (BeginForkOperation_Aof(tmpfile, &server, sizeof(server), &server.aof_child_pid, dictGetHashFunctionSeed(), server.logfile) == FALSE) {
redisLog(REDIS_WARNING,
"Can't rewrite append only file in background: fork: %s",
strerror(errno));
return REDIS_ERR;
}
server.stat_fork_time = ustime()-start;
redisLog(REDIS_NOTICE,
"Background append only file rewriting started by pid %d",server.aof_child_pid);
server.aof_rewrite_scheduled = 0;
server.aof_rewrite_time_start = time(NULL);
updateDictResizePolicy();
/* We set appendseldb to -1 in order to force the next call to the
* feedAppendOnlyFile() to issue a SELECT command, so the differences
* accumulated by the parent into server.aof_rewrite_buf will start
* with a SELECT statement and it will be safe to merge. */
server.aof_selected_db = -1;
return REDIS_OK;
}
#else
int rewriteAppendOnlyFileBackground(void) {
pid_t childpid;
PORT_LONGLONG start;
@@ -1326,13 +1296,21 @@ int rewriteAppendOnlyFileBackground(void) {
if (server.aof_child_pid != -1) return REDIS_ERR;
if (aofCreatePipes() != REDIS_OK) return REDIS_ERR;
start = ustime();
#ifndef _WIN32
if ((childpid = fork()) == 0) {
#endif
char tmpfile[256];
/* Child */
#ifndef _WIN32
/* Child */
closeListeningSockets(0);
redisSetProcTitle("redis-aof-rewrite");
#endif
snprintf(tmpfile,256,"temp-rewriteaof-bg-%d.aof", (int) getpid());
#ifdef _WIN32
childpid = BeginForkOperation_Aof(tmpfile, &server, sizeof(server), dictGetHashFunctionSeed(), server.logfile);
#else
if (rewriteAppendOnlyFile(tmpfile) == REDIS_OK) {
size_t private_dirty = zmalloc_get_private_dirty();
@@ -1346,6 +1324,7 @@ int rewriteAppendOnlyFileBackground(void) {
exitFromChild(1);
}
} else {
#endif
/* Parent */
server.stat_fork_time = ustime()-start;
server.stat_fork_rate = (double) zmalloc_used_memory() * 1000000 / server.stat_fork_time / (1024*1024*1024); /* GB per second. */
@@ -1369,10 +1348,11 @@ int rewriteAppendOnlyFileBackground(void) {
server.aof_selected_db = -1;
replicationScriptCacheFlush();
return REDIS_OK;
#ifndef _WIN32
}
#endif
return REDIS_OK; /* unreached */
}
#endif
void bgrewriteaofCommand(redisClient *c) {
if (server.aof_child_pid != -1) {
+6
View File
@@ -64,6 +64,7 @@
#include "bio.h"
#ifdef _WIN32
#include "win32_Interop/win32fixes.h"
#include "Win32_Interop/Win32_ThreadControl.h"
#endif
static pthread_t bio_threads[REDIS_BIO_NUM_OPS];
@@ -158,6 +159,7 @@ void *bioProcessBackgroundJobs(void *arg) {
#endif
pthread_mutex_lock(&bio_mutex[type]);
/* Block SIGALRM so we are sure that only the main thread will
* receive the watchdog signal. */
sigemptyset(&sigset);
@@ -171,7 +173,11 @@ void *bioProcessBackgroundJobs(void *arg) {
/* The loop always starts with the lock hold. */
if (listLength(bio_jobs[type]) == 0) {
WIN32_ONLY(WorkerThread_EnterSafeMode());
pthread_cond_wait(&bio_condvar[type],&bio_mutex[type]);
WIN32_ONLY(pthread_mutex_unlock(&bio_mutex[type]));
WIN32_ONLY(WorkerThread_ExitSafeMode());
WIN32_ONLY(pthread_mutex_lock(&bio_mutex[type]));
continue;
}
/* Pop the job from the queue. */
+4
View File
@@ -481,8 +481,12 @@ void _redisAssertWithInfo(redisClient *c, robj *o, char *estr, char *file, int l
void _redisPanic(char *msg, char *file, int line) {
bugReportStart();
redisLog(REDIS_WARNING,"------------------------------------------------");
#ifdef _WIN32
redisLog(REDIS_WARNING, "Fatal Error: %s #%s:%d", msg, file, line);
#else
redisLog(REDIS_WARNING,"!!! Software Failure. Press left mouse button to continue");
redisLog(REDIS_WARNING,"Guru Meditation: %s #%s:%d",msg,file,line);
#endif
#ifdef HAVE_BACKTRACE
redisLog(REDIS_WARNING,"(forcing SIGSEGV in order to print the stack trace)");
#endif
+1 -1
View File
@@ -547,7 +547,7 @@ sds latencyCommandGenSparkeline(char *event, struct latencyTimeSeries *ts) {
}
graph = sdscatprintf(graph,
"%s - high %Iu ms, low %Iu ms (all time high %Iu ms)\n", event, /* PORTABILITY FIX %ld -> %Id, %lu -> %Iu */
"%s - high %Iu ms, low %Iu ms (all time high %Iu ms)\n", event, WIN_PORT_FIX /* %ld -> %Id, %lu -> %Iu */
(PORT_ULONG) max, (PORT_ULONG) min, (PORT_ULONG) ts->max);
for (j = 0; j < LATENCY_GRAPH_COLS; j++)
graph = sdscatlen(graph,"-",1);
+11 -2
View File
@@ -228,12 +228,21 @@ void memtest_compare_times(PORT_ULONG *m, size_t bytes, int pass, int times) {
void memtest_test(size_t megabytes, int passes) {
size_t bytes = megabytes * 1024 * 1024;
#ifdef _WIN32
PORT_ULONG *m = VirtualAllocEx(
GetCurrentProcess(),
NULL,
bytes,
MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN,
PAGE_READWRITE);
#else
PORT_ULONG *m = malloc(bytes);
#endif
int pass = 0;
if (m == NULL) {
fprintf(stderr,"Unable to allocate %Iu megabytes: %s",
megabytes,strerror(errno)); WIN_PORT_FIX /* %zu -> %Iu */
fprintf(stderr,"Unable to allocate %Iu megabytes: %s", WIN_PORT_FIX /* %zu -> %Iu */
megabytes,strerror(errno));
exit(1);
}
while (pass != passes) {
+1 -1
View File
@@ -140,7 +140,7 @@ robj *createStringObjectFromLongDouble(PORT_LONGDOUBLE value, int humanfriendly)
* way that is "non surprising" for the user (that is, most small
* decimal numbers will be represented in a way that when converted
* back into a string are exactly the same as what the user typed.) */
len = snprintf(buf,sizeof(buf),"%.15Lf",value); WIN_PORT_FIX /* %.17 -> %.15 on Windows the magic number is 15 */
len = snprintf(buf,sizeof(buf),"%.15Lf",value); WIN_PORT_FIX /* %.17 -> %.15 on Windows the magic number is 15 */
/* Now remove trailing zeroes after the '.' */
if (strchr(buf,'.') != NULL) {
char *p = buf+len-1;
+11 -26
View File
@@ -788,24 +788,6 @@ werr:
return REDIS_ERR;
}
#ifdef _WIN32
int rdbSaveBackground(char *filename) {
PORT_LONGLONG start;
start = ustime();
server.dirty_before_bgsave = server.dirty;
if (BeginForkOperation_Rdb(filename, &server, sizeof(server), &server.rdb_child_pid, dictGetHashFunctionSeed(), server.logfile)) {
server.stat_fork_time = ustime()-start;
server.rdb_child_type = REDIS_RDB_CHILD_TYPE_DISK;
updateDictResizePolicy();
return REDIS_OK;
} else {
redisLog(REDIS_WARNING,"Can't save in background: fork: %s", strerror(errno));
return REDIS_ERR;
}
}
#else
int rdbSaveBackground(char *filename) {
pid_t childpid;
PORT_LONGLONG start;
@@ -816,6 +798,9 @@ int rdbSaveBackground(char *filename) {
server.lastbgsave_try = time(NULL);
start = ustime();
#ifdef _WIN32
childpid = BeginForkOperation_Rdb(filename, &server, sizeof(server), dictGetHashFunctionSeed(), server.logfile);
#else
if ((childpid = fork()) == 0) {
int retval;
@@ -834,6 +819,7 @@ int rdbSaveBackground(char *filename) {
}
exitFromChild((retval == REDIS_OK) ? 0 : 1);
} else {
#endif
/* Parent */
server.stat_fork_time = ustime()-start;
server.stat_fork_rate = (double) zmalloc_used_memory() * 1000000 / server.stat_fork_time / (1024*1024*1024); /* GB per second. */
@@ -850,10 +836,11 @@ int rdbSaveBackground(char *filename) {
server.rdb_child_type = REDIS_RDB_CHILD_TYPE_DISK;
updateDictResizePolicy();
return REDIS_OK;
#ifndef _WIN32
}
#endif
return REDIS_OK; /* unreached */
}
#endif
void rdbRemoveTempFile(pid_t childpid) {
char tmpfile[256];
@@ -1482,7 +1469,9 @@ int rdbSaveToSlavesSockets(void) {
/* Create the child process. */
start = ustime();
#ifndef _WIN32
#ifdef _WIN32
childpid = BeginForkOperation_Socket(fds, numfds, clientids, pipefds[1], &server, sizeof(server), dictGetHashFunctionSeed(), server.logfile);
#else
if ((childpid = fork()) == 0) {
/* Child */
int retval;
@@ -1549,12 +1538,6 @@ int rdbSaveToSlavesSockets(void) {
zfree(clientids);
exitFromChild((retval == REDIS_OK) ? 0 : 1);
} else {
#else // #ifndef _WIN32
if (!BeginForkOperation_Socket(fds, numfds, clientids, pipefds[1], &server, sizeof(server), &server.rdb_child_pid, dictGetHashFunctionSeed(), server.logfile)) {
redisLog(REDIS_WARNING,"Can't save in background: fork: %s", strerror(errno));
return REDIS_ERR;
} else {
childpid = server.rdb_child_pid;
#endif
/* Parent */
zfree(clientids); /* Not used by parent. Free ASAP. */
@@ -1576,7 +1559,9 @@ int rdbSaveToSlavesSockets(void) {
updateDictResizePolicy();
zfree(fds);
return REDIS_OK;
#ifndef _WIN32
}
#endif
return REDIS_OK; /* unreached */
}
+16 -15
View File
@@ -57,28 +57,29 @@
/* File maping used in redis-check-dump */
/* mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); */
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) {
HANDLE h;
void *data;
HANDLE h;
void *data;
(void)offset;
(void) offset;
if ((flags != MAP_SHARED) || (prot != PROT_READ)) {
/* Not supported in this port */
return MAP_FAILED;
if ((flags != MAP_SHARED) || (prot != PROT_READ)) {
/* Not supported in this port */
return MAP_FAILED;
};
h = CreateFileMapping((HANDLE)_get_osfhandle(fd),
NULL,PAGE_READONLY,0,0,NULL);
h = CreateFileMapping((HANDLE) _get_osfhandle(fd), NULL, PAGE_READONLY, 0, 0, NULL);
if (!h) {
return MAP_FAILED;
}
if (!h) return MAP_FAILED;
data = MapViewOfFileEx(h, FILE_MAP_READ, 0, 0, length, start);
CloseHandle(h);
data = MapViewOfFileEx(h, FILE_MAP_READ,0,0,length,start);
if (!data) {
return MAP_FAILED;
}
CloseHandle(h);
if (!data) return MAP_FAILED;
return data;
return data;
}
/* Unmap file mapping */
+43 -44
View File
@@ -29,6 +29,10 @@
#ifdef _WIN32
#include "win32_Interop\win32_util.h"
#include "Win32_Interop\Win32_FDAPI.h"
#include "Win32_Interop\Win32_ThreadControl.h"
#include <locale.h>
#define LOG_LOCAL0 0
#endif
#include "redis.h"
@@ -39,11 +43,7 @@
#include <time.h>
#include <signal.h>
#ifdef _WIN32
#include <locale.h>
#define LOG_LOCAL0 0
#include "redisLog.h"
#else
#ifndef _WIN32
#include <sys/wait.h>
#include <arpa/inet.h>
#include <sys/resource.h>
@@ -60,10 +60,8 @@
#include <limits.h>
#include <float.h>
#include <math.h>
#ifndef _WIN32
#include <locale.h>
#ifdef _WIN32
#include "Win32_Interop\Win32_FDAPI.h"
#endif
/* Our shared "common" objects */
@@ -1148,10 +1146,10 @@ int serverCron(struct aeEventLoop *eventLoop, PORT_LONGLONG id, void *clientData
if (!server.sentinel_mode) {
run_with_period(5000) {
redisLog(REDIS_VERBOSE,
"%Iu clients connected (%Iu slaves), %Iu bytes in use",
"%Iu clients connected (%Iu slaves), %Iu bytes in use", WIN_PORT_FIX /* %zu -> %Iu */
listLength(server.clients)-listLength(server.slaves),
listLength(server.slaves),
zmalloc_used_memory()); WIN_PORT_FIX /* %zu -> %Iu */
zmalloc_used_memory());
}
}
@@ -1172,19 +1170,23 @@ int serverCron(struct aeEventLoop *eventLoop, PORT_LONGLONG id, void *clientData
/* Check if a background saving or AOF rewrite in progress terminated. */
if (server.rdb_child_pid != -1 || server.aof_child_pid != -1) {
#ifdef _WIN32
if (GetForkOperationStatus() == osCOMPLETE || GetForkOperationStatus() == osFAILED) {
int exitCode;
int bySignal;
bySignal = (int)(GetForkOperationStatus() == osFAILED);
redisLog(REDIS_WARNING, (bySignal ? "fork operation failed" : "fork operation complete"));
EndForkOperation(&exitCode);
if (server.rdb_child_pid != -1) {
backgroundSaveDoneHandler(exitCode, bySignal);
} else {
backgroundRewriteDoneHandler(exitCode, bySignal);
}
updateDictResizePolicy();
}
if (GetForkOperationStatus() == osCOMPLETE || GetForkOperationStatus() == osFAILED) {
RequestSuspension();
if (SuspensionCompleted()) {
int exitCode;
int bySignal;
bySignal = (int)(GetForkOperationStatus() == osFAILED);
redisLog(REDIS_WARNING, (bySignal ? "fork operation failed" : "fork operation complete"));
EndForkOperation(&exitCode);
ResumeFromSuspension();
if (server.rdb_child_pid != -1) {
backgroundSaveDoneHandler(exitCode, bySignal);
} else {
backgroundRewriteDoneHandler(exitCode, bySignal);
}
updateDictResizePolicy();
}
}
#else
int statloc;
pid_t pid;
@@ -1453,23 +1455,8 @@ void initServerConfig(void) {
server.saveparams = NULL;
server.loading = 0;
server.logfile = zstrdup(REDIS_DEFAULT_LOGFILE);
#ifdef _WIN32
// this is handled before redis_main() in Win32_QFork.cpp:::SetupLogging()
/*
if (RunningAsService()) {
server.syslog_enabled = 1;
server.syslog_ident = zstrdup(GetServiceName());
} else {
server.syslog_ident = zstrdup(REDIS_DEFAULT_SYSLOG_IDENT);
server.syslog_enabled = REDIS_DEFAULT_SYSLOG_ENABLED;
}
setSyslogEnabled(server.syslog_enabled);
setSyslogIdent(server.syslog_ident);
*/
#else
server.syslog_enabled = REDIS_DEFAULT_SYSLOG_ENABLED;
server.syslog_enabled = REDIS_DEFAULT_SYSLOG_ENABLED;
server.syslog_ident = zstrdup(REDIS_DEFAULT_SYSLOG_IDENT);
#endif
server.syslog_facility = LOG_LOCAL0;
server.daemonize = REDIS_DEFAULT_DAEMONIZE;
server.aof_state = REDIS_AOF_OFF;
@@ -2731,12 +2718,14 @@ sds genRedisInfoString(char *section) {
"os:%s %s %s\r\n"
"arch_bits:%d\r\n"
"multiplexing_api:%s\r\n"
#ifndef _WIN32
"gcc_version:%d.%d.%d\r\n"
#endif
"process_id:%ld\r\n"
"run_id:%s\r\n"
"tcp_port:%d\r\n"
#ifdef _WIN32
"uptime_in_seconds:%lld\r\n" /* BUGBUG: fix %lld */
"uptime_in_seconds:%lld\r\n"
"uptime_in_days:%lld\r\n"
#else
"uptime_in_seconds:%jd\r\n"
@@ -2757,10 +2746,12 @@ sds genRedisInfoString(char *section) {
#endif
server.arch_bits,
aeGetApiName(),
#ifndef _WIN32
#ifdef __GNUC__
__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__,
#else
0,0,0,
#endif
#endif
(PORT_LONG) getpid(),
server.runid,
@@ -2902,7 +2893,7 @@ sds genRedisInfoString(char *section) {
"aof_current_size:%lld\r\n"
"aof_base_size:%lld\r\n"
"aof_pending_rewrite:%d\r\n"
"aof_buffer_length:%Iu\r\n"
"aof_buffer_length:%Iu\r\n" WIN_PORT_FIX /* %zu -> %Iu */
"aof_rewrite_buffer_length:%lu\r\n"
"aof_pending_bio_fsync:%llu\r\n"
"aof_delayed_fsync:%lu\r\n",
@@ -2912,7 +2903,7 @@ sds genRedisInfoString(char *section) {
sdslen(server.aof_buf),
aofRewriteBufferSize(),
bioPendingJobsOfType(REDIS_BIO_AOF_FSYNC),
server.aof_delayed_fsync); WIN_PORT_FIX /* %zu -> %Iu */
server.aof_delayed_fsync);
}
if (server.loading) {
@@ -3688,9 +3679,17 @@ void loadDataFromDisk(void) {
}
void redisOutOfMemoryHandler(size_t allocation_size) {
redisLog(REDIS_WARNING,"Out Of Memory allocating %Iu bytes!",
allocation_size); WIN_PORT_FIX /* %zu -> %Iu */
#ifdef _WIN32
bugReportStart();
redisLog(REDIS_WARNING, "Out Of Memory allocating %Iu bytes.", /* %zu -> %Iu */
allocation_size);
// Call abort() instead of forcing an access violation in redisPanic
abort();
#else
redisLog(REDIS_WARNING,"Out Of Memory allocating %zu bytes!",
allocation_size);
redisPanic("Redis aborting for OUT OF MEMORY");
#endif
}
void redisSetProcTitle(char *title) {
+3 -3
View File
@@ -73,7 +73,7 @@ typedef PORT_LONGLONG mstime_t; /* millisecond time type. */
#include "latency.h" /* Latency monitor API */
#include "sparkline.h" /* ASII graphs API */
#include "redisLog.h" /* moved logging for hiredis and RedisCli usage /*
#include "Win32_Interop/Win32_RedisLog.h" /* moved logging for hiredis and RedisCli usage /*
/* Error codes */
#define REDIS_OK 0
@@ -94,7 +94,7 @@ typedef PORT_LONGLONG mstime_t; /* millisecond time type. */
#define REDIS_SHARED_INTEGERS 10000
#define REDIS_SHARED_BULKHDR_LEN 32
#ifdef _WIN32
// see redisLog.h
// see Win32_RedisLog.h
#else
#define REDIS_MAX_LOGMSG_LEN 1024 /* Default maximum length of syslog messages */
#endif
@@ -314,7 +314,7 @@ typedef PORT_LONGLONG mstime_t; /* millisecond time type. */
#define REDIS_SORTKEY_MAX 1024
#ifdef _WIN32
// see redisLog.h
// see Win32_RedisLog.h
#else
/* Log levels */
#define REDIS_DEBUG 0
+2 -2
View File
@@ -283,7 +283,7 @@ void replicationFeedMonitors(redisClient *c, list *monitors, int dictid, robj **
for (j = 0; j < argc; j++) {
if (argv[j]->encoding == REDIS_ENCODING_INT) {
cmdrepr = sdscatprintf(cmdrepr, "\"%Id\"", (PORT_LONG) argv[j]->ptr); /* PORTABILITY FIX %ld -> %Id */
cmdrepr = sdscatprintf(cmdrepr, "\"%Id\"", (PORT_LONG) argv[j]->ptr); WIN_PORT_FIX /* %ld -> %Id */
} else {
cmdrepr = sdscatrepr(cmdrepr,(char*)argv[j]->ptr,
sdslen(argv[j]->ptr));
@@ -1041,7 +1041,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 = IF_WIN32(strtoll,strtol)(buf+1,NULL,10);
server.repl_transfer_size = IF_WIN32(strtoll,strtol)(buf+1,NULL,10); /* BUGBUG: verify for 32bit support */
redisLog(REDIS_NOTICE,
"MASTER <-> SLAVE sync: receiving %lld bytes from master",
(PORT_LONGLONG) server.repl_transfer_size);
+9 -6
View File
@@ -612,11 +612,12 @@ void scriptingEnableGlobalsProtection(lua_State *lua) {
/* strict.lua from: http://metalua.luaforge.net/src/lib/strict.lua.html.
* Modified to be adapted to Redis. */
s[j++]="local dbg=debug\n";
s[j++]="local mt = {}\n";
s[j++]="setmetatable(_G, mt)\n";
s[j++]="mt.__newindex = function (t, n, v)\n";
s[j++]=" if debug.getinfo(2) then\n";
s[j++]=" local w = debug.getinfo(2, \"S\").what\n";
s[j++]=" if dbg.getinfo(2) then\n";
s[j++]=" local w = dbg.getinfo(2, \"S\").what\n";
s[j++]=" if w ~= \"main\" and w ~= \"C\" then\n";
s[j++]=" error(\"Script attempted to create global variable '\"..tostring(n)..\"'\", 2)\n";
s[j++]=" end\n";
@@ -624,11 +625,12 @@ void scriptingEnableGlobalsProtection(lua_State *lua) {
s[j++]=" rawset(t, n, v)\n";
s[j++]="end\n";
s[j++]="mt.__index = function (t, n)\n";
s[j++]=" if debug.getinfo(2) and debug.getinfo(2, \"S\").what ~= \"C\" then\n";
s[j++]=" if dbg.getinfo(2) and dbg.getinfo(2, \"S\").what ~= \"C\" then\n";
s[j++]=" error(\"Script attempted to access unexisting global variable '\"..tostring(n)..\"'\", 2)\n";
s[j++]=" end\n";
s[j++]=" return rawget(t, n)\n";
s[j++]="end\n";
s[j++]="debug = nil\n";
s[j++]=NULL;
for (j = 0; s[j] != NULL; j++) code = sdscatlen(code,s[j],strlen(s[j]));
@@ -732,10 +734,11 @@ void scriptingInit(void) {
* information about the caller, that's what makes sense from the point
* of view of the user debugging a script. */
{
char *errh_func = "function __redis__err__handler(err)\n"
" local i = debug.getinfo(2,'nSl')\n"
char *errh_func = "local dbg = debug\n"
"function __redis__err__handler(err)\n"
" local i = dbg.getinfo(2,'nSl')\n"
" if i and i.what == 'C' then\n"
" i = debug.getinfo(3,'nSl')\n"
" i = dbg.getinfo(3,'nSl')\n"
" end\n"
" if i then\n"
" return i.source .. ':' .. i.currentline .. ': ' .. err\n"
+9 -9
View File
@@ -776,7 +776,7 @@ void sentinelRunPendingScripts(void) {
CloseHandle( pi.hThread );
sentinel.running_scripts++;
sentinelEvent(REDIS_DEBUG, "+script-child", NULL, "%ld", (long) sj->pid); /* BUGBUG: fix %ld */
sentinelEvent(REDIS_DEBUG, "+script-child", NULL, "%Id", (PORT_LONG) sj->pid); WIN_PORT_FIX /* %ld -> %Id */
} else {
sentinelEvent(REDIS_WARNING,"-script-error",NULL,
"%s %d %d", sj->argv[0], 99, 0);
@@ -845,8 +845,8 @@ void sentinelCollectTerminatedScripts(void) {
if(WaitForSingleObject(sj->hScriptProcess,0) == WAIT_OBJECT_0) {
GetExitCodeProcess(sj->hScriptProcess,&exitCode);
sentinelEvent(REDIS_DEBUG,"-script-child",NULL,"%ld %d %d",
(long) sj->pid, exitCode, 0); /* BUGBUG: fix %ld */
sentinelEvent(REDIS_DEBUG, "-script-child", NULL, "%Id %d %d", WIN_PORT_FIX /* %ld -> %Id*/
(PORT_LONG) sj->pid, exitCode, 0);
/* at this point the process ID may be recycled by Windows */
CloseHandle(sj->hScriptProcess);
@@ -932,8 +932,8 @@ void sentinelKillTimedoutScripts(void) {
if (sj->flags & SENTINEL_SCRIPT_RUNNING &&
(now - sj->start_time) > SENTINEL_SCRIPT_MAX_RUNTIME)
{
sentinelEvent(REDIS_WARNING, "-script-timeout", NULL, "%s %ld",
sj->argv[0], (long) sj->pid); /* BUGBUG */
sentinelEvent(REDIS_WARNING, "-script-timeout", NULL, "%s %Id", WIN_PORT_FIX /* %ld -> %Id*/
sj->argv[0], (PORT_LONG) sj->pid);
#ifdef _WIN32
TerminateProcess(sj->hScriptProcess,1);
#else
@@ -1607,16 +1607,16 @@ void rewriteConfigSentinelOption(struct rewriteConfigState *state) {
/* sentinel down-after-milliseconds */
if (master->down_after_period != SENTINEL_DEFAULT_DOWN_AFTER) {
line = sdscatprintf(sdsempty(),
"sentinel down-after-milliseconds %s %ld",
master->name, (long) master->down_after_period); /* BUGBUG */
"sentinel down-after-milliseconds %s %Id", WIN_PORT_FIX /* %ld -> %Id*/
master->name, (PORT_LONG) master->down_after_period);
rewriteConfigRewriteLine(state,"sentinel",line,1);
}
/* sentinel failover-timeout */
if (master->failover_timeout != SENTINEL_DEFAULT_FAILOVER_TIMEOUT) {
line = sdscatprintf(sdsempty(),
"sentinel failover-timeout %s %ld",
master->name, (long) master->failover_timeout); /* BUGBUG */
"sentinel failover-timeout %s %Id", WIN_PORT_FIX /* %ld -> %Id*/
master->name, (PORT_LONG) master->failover_timeout);
rewriteConfigRewriteLine(state,"sentinel",line,1);
}
+2 -2
View File
@@ -131,8 +131,8 @@ pthread_mutex_t used_memory_mutex = PTHREAD_MUTEX_INITIALIZER;
#endif
static void zmalloc_default_oom(size_t size) {
fprintf(stderr, "zmalloc: Out of memory trying to allocate %Iu bytes\n",
size); WIN_PORT_FIX /* %zu -> %Iu */
fprintf(stderr, "zmalloc: Out of memory trying to allocate %Iu bytes\n", WIN_PORT_FIX /* %zu -> %Iu */
size);
fflush(stderr);
abort();
}
+6 -3
View File
@@ -88,8 +88,9 @@ tags {"aof"} {
test "Bad format: Server should have logged an error" {
set pattern "*Bad file format reading the append only file*"
set retry 10
#WIN_PORT_FIX 'tail -n1' -> 'tail -1'
while {$retry} {
set result [exec tail -n1 < [dict get $srv stdout]]
set result [exec tail -1 < [dict get $srv stdout]]
if {[string match $pattern $result]} {
break
}
@@ -113,8 +114,9 @@ tags {"aof"} {
test "Unfinished MULTI: Server should have logged an error" {
set pattern "*Unexpected end of file reading the append only file*"
set retry 10
#WIN_PORT_FIX 'tail -n1' -> 'tail -1'
while {$retry} {
set result [exec tail -n1 < [dict get $srv stdout]]
set result [exec tail -1 < [dict get $srv stdout]]
if {[string match $pattern $result]} {
break
}
@@ -137,8 +139,9 @@ tags {"aof"} {
test "Short read: Server should have logged an error" {
set pattern "*Unexpected end of file reading the append only file*"
set retry 10
#WIN_PORT_FIX 'tail -n1' -> 'tail -1'
while {$retry} {
set result [exec tail -n1 < [dict get $srv stdout]]
set result [exec tail -1 < [dict get $srv stdout]]
if {[string match $pattern $result]} {
break
}
+2 -1
View File
@@ -69,8 +69,9 @@ start_server {tags {"aofrw"}} {
r bgrewriteaof
r config set appendonly no
r exec
#WIN_PORT_FIX 'tail -n5' -> 'tail -5'
wait_for_condition 50 100 {
[string match {*Killing*AOF*child*} [exec tail -n5 < [srv 0 stdout]]]
[string match {*Killing*AOF*child*} [exec tail -5 < [srv 0 stdout]]]
} else {
fail "Can't find 'Killing AOF child' into recent logs"
}