Compare commits

..
727 Commits
Author SHA1 Message Date
Enrico Giordani 08bde3edf6 [Setup] Updated version number in appveyor.yml. 2015-07-15 15:30:12 +02:00
Enrico Giordani ee99b82f45 [Fix] Memory was not properly released at the end of the memory test.
[Change] Hard-coded memory test loops changed from 50 to 5.
[Setup] Updated the release notes.
2015-07-15 14:06:31 +02:00
Enrico Giordani 965b6e0311 [Setup] Updated the release notes. 2015-07-15 13:07:28 +02:00
Enrico Giordani 3818822373 [Setup] Nuget/Chocolatey packages update.
[Change] Updated the ReleasePackagingTool to include all .pdb files.
[Change] Updated the nuget/chocolatey templates to conform with the guidelines:
         - Replaced the Redis logo with the Redis icon.
         - Changed the package title.
         - Changed the package description.
         - Removed the package summary to use a short version of the decription
           instead.
 [Change] Updated license.txt to 2015.
2015-07-15 13:07:28 +02:00
Enrico Giordani 97461656ed [Fix] Bug report fixes.
[Fix] If an exception occured while building the server info data, the footer
      was not logged.
[Fix] Uncommented the ServerInfo() call that was commented out by mistake in a
      previous commit.
2015-07-15 13:07:27 +02:00
Enrico Giordani 5e905ce07e [Setup] Updated the release number and the release notes (2.8.2101). 2015-07-15 13:07:27 +02:00
Enrico Giordani 7b920de231 [Fix] Added API mapping for fclose() and fileno().
This fix resolves issue #235 https://github.com/MSOpenTech/redis/issues/235
2015-07-15 13:07:26 +02:00
Enrico Giordani 2b7dc05763 [Fix] Memory corruption. Merged fix from Azure fork (by Mike Montwill).
"in-kernel writes don't always observe cow pages correctly".
https://github.com/Azure/redis/commit/69c780f8a62e6a96c3f64adf23004beac7a90abf
2015-07-15 13:07:26 +02:00
Enrico Giordani f9660d1c72 [Fix] Socket blocking state.
Changed the logic to make sure the returned value is initialized.
2015-07-15 13:07:25 +02:00
Enrico Giordani 24d0115bd6 [Cleanup] Code cleanup: variables initialization and validation. 2015-07-15 13:07:25 +02:00
Enrico Giordani 2b502cfb16 [Change] Rolled back "Workaround for getpeername() issue".
The workaround https://github.com/MSOpenTech/redis/commit/0f79d723965a46e59dfbd239ad66c2d7c4bf5eeb is not anymore required since the root problem has been fixed (in another commit).
2015-07-15 13:07:24 +02:00
Enrico Giordani 8746390c28 [Change] Removed the forkedProcessReady event.
The event was used to wait for the child process to map the memory, but it's
not required since the memory is already VirtualProtect(ed).
2015-07-15 13:07:24 +02:00
Enrico Giordani 14d318dfe5 [Fix] aeWinQueueAccept wrong return value.
[Change] Variable name acceptsocket changed to acceptfd.
2015-07-15 13:07:23 +02:00
Enrico Giordani 5a00959c87 [Cleanup] Tabs->spaces, formatting. 2015-07-15 13:07:23 +02:00
Enrico Giordani a37f64953b [Change] Removed extra space allocated at the end of the mmap file.
[Log] Improved error messages.
2015-07-15 13:07:22 +02:00
Enrico Giordani c3495c8f3a [Fix] RFDMap was not thread safe.
[Cleanup] Removed unused/commented out code, tabs->spaces.
2015-07-15 13:07:22 +02:00
Enrico Giordani 7370c06011 [Fix] UnhandledExceptiontHandler internal exception handling. 2015-07-15 13:07:21 +02:00
Enrico Giordani 37a42c8e55 [Cleanup] Removed unused include. 2015-07-15 13:07:21 +02:00
Enrico Giordani b0d93b92e7 [Cleanup] Removed useless platform definition from RedisServer.sln 2015-07-15 13:07:21 +02:00
Enrico Giordani 3506673f9d [Cleanup] Changed variable type to match function return value.
checkForSentinelMode() returns an int, not a bool.
2015-07-15 13:07:20 +02:00
Enrico Giordani 0244fa1e44 [Cleanup] Minor change to method signature.
The method input parameter has been changed to a const.
2015-07-15 13:07:20 +02:00
Enrico Giordani 47e02c0f9d [Cleanup] Removed non-existent file from hiredis project. 2015-07-15 13:07:19 +02:00
Enrico Giordani 69b7cb04ba [WinPort] Explicit cast. 2015-07-15 13:07:19 +02:00
Enrico Giordani 9b7ebf7b78 [Setup] Move ReleasePackagingTool to its own solution.
- Removed unused code in ReleasePackagingTool.
 - Chocolatey package now imports the documentation files from the same folder
   where the binaries files are.
2015-07-15 13:07:18 +02:00
Enrico Giordani 94ae678f6e [Fix] The stack trace was not logged when Redis is running as a service. 2015-07-15 13:07:18 +02:00
Enrico Giordani b67f9d8e9a [Setup] EventLog.dll excluded from NuGet package. 2015-07-15 13:07:17 +02:00
Enrico Giordani 04c770910e [Setup] Updated the scripts to create/push the NuGet/Chocolatey packages.
- [Change] The binaries added to the packages 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 in the source folder
            along with the binaries.
 - [Fix] PullBinaries.ps1: replaced hardcoded Redis version number with input
         parameter.
 - [Fix] Improved error handling.
2015-07-15 13:07:17 +02:00
Enrico Giordani 32aea31d74 [Fix] Fork code for background processing 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.
2015-07-15 13:07:16 +02:00
Enrico Giordani d82a361542 [Fix] Deleting char** correctly (by @zeliard) 2015-07-15 13:07:02 +02:00
Alexis Campailla b8009c220a Fix 32-bit build 2015-06-24 23:10:27 +02:00
Alexis Campailla 4f384b9e58 Update appveyor version 2015-06-24 21:36:57 +02:00
Alexis Campailla b84d390111 Fix child process handle closing 2015-06-24 20:53:17 +02:00
Enrico Giordani fdbf5328c2 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.
2015-06-24 17:43:54 +02:00
Enrico Giordani 05b20f0e4b Change BUG REPORT closing message to point to a different git hub page. 2015-06-24 13:05:53 +02:00
Enrico Giordani 1cb3e84814 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
2015-06-24 11:59:45 +02:00
Enrico Giordani 8ea708f9e1 New release notes format (similar to Redis on UNIX) 2015-06-24 01:21:27 +02:00
Enrico Giordani e2df601222 Fixed broken link in README. 2015-06-24 01:16:02 +02:00
Enrico Giordani 93d00065e4 Minor update to the README. 2015-06-24 01:12:49 +02:00
Enrico Giordani bd2ee4d2da Warning message in config files for the maxmemory flag. 2015-06-23 23:40:50 +02:00
Enrico Giordani 2943ec7db6 Cleaned up the UnhandledExceptiontHandler() code.
Minor changes.
2015-06-23 21:56:31 +02:00
Enrico Giordani b805f2be89 Calling abort() in redisOutOfMemoryHandler().
Changed out-of-memory error report.
2015-06-23 19:02:03 +02:00
Enrico Giordani 18a653318d Commented out printf calls in dlmalloc. 2015-06-23 18:55:53 +02:00
Enrico Giordani f01052fb5d Changed #if defined(_WIN64) to #ifdef _WIN64
It was causing an appveyor build failure.
2015-06-23 18:44:32 +02:00
Enrico Giordani a4865f06a9 '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'.
2015-06-23 18:15:20 +02:00
Enrico Giordani 3de4f6cb47 Change misleading variables/functions names: master->parent, slave->child.
Master and Slave labels were using for the Parent and Child processes.
2015-06-23 16:54:23 +02:00
Enrico Giordani 453b582eed Updated authors and description for nuget and chocolatey. 2015-06-23 13:46:45 +02:00
Enrico Giordani e91c9eeef7 Merge branch '2.8-enrico' of https://github.com/janeasystems/redis-private into 2.8-enrico 2015-06-23 13:40:41 +02:00
Enrico Giordani dc3285af0b Update Redis on Windows Release Notes.md 2015-06-23 11:42:51 +02:00
Enrico Giordani 5c05765d9a Typos in warning message. 2015-06-22 21:23:08 +02:00
Enrico Giordani 510cc9bd3e Replaced AddVectoredExceptionHandler with SetUnhandledExceptionFilter
for unhandled exception handling.
Added log warning if the maxmemory flag is not set.
2015-06-22 19:57:52 +02:00
Enrico Giordani 4993487b25 Fixed links in README. 2015-06-22 17:33:41 +02:00
Enrico Giordani 710d179f91 Added text to links. 2015-06-22 17:25:21 +02:00
Enrico Giordani 04c1ba4c56 Updated documentation. 2015-06-22 17:15:48 +02:00
Enrico Giordani 019d317a10 Use MEM_TOP_DOWN flag to allocate memory for memtest. 2015-06-22 13:58:40 +02:00
NickMRamirez 3b4bd2f84e 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
2015-06-22 13:38:36 +02:00
Enrico Giordani 3935ffb302 RejoinCOWPages and background threads should be synchronized (part 2) 2015-06-22 12:35:10 +02:00
Enrico Giordani 87e43c5ce6 Changed error message. 2015-06-22 11:23:04 +02:00
Alexis Campailla af7ca8ca28 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
2015-06-19 21:22:48 +02:00
Alexis Campailla 3cd7d92bf3 Build ReleasePackagingTool in Debug for Debug solution configuration 2015-06-19 19:31:22 +02:00
Enrico Giordani 4742811f48 Comment wording. 2015-06-19 12:05:32 +02:00
Enrico Giordani 2c8c937325 Cleaned up a few #ifdef _WIN32. 2015-06-19 00:24:32 +02:00
Enrico Giordani 2772b6388e Indentation. 2015-06-19 00:22:32 +02:00
Enrico Giordani f8cc98586e StackTrace and info report. 2015-06-19 00:20:19 +02:00
Enrico Giordani d6ede8b354 Moved RedisLog.* to Win32_Interop and renamed to Win32_RedisLog.*
Deleted unused file msvs/RedisLog.h
2015-06-11 17:03:08 +02:00
Enrico Giordani 13f36c88e0 Added symbols to MSI.
Also updated the release number to 2.8.21.
2015-06-11 16:05:41 +02:00
Enrico Giordani c68970e268 Enabled dlmalloc DEBUG mode in the debug build. 2015-06-11 15:30:04 +02:00
Enrico Giordani 1cf1db97ae Final portability fixes for 'long' type. 2015-06-10 23:08:53 +02:00
Enrico Giordani 365c4c7559 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
2015-06-10 12:37:41 +02:00
Enrico Giordani fb63c21f81 Comment.
added a note in case 32bit support will be brought back.
2015-06-10 12:15:57 +02:00
Enrico Giordani bf260ec746 Test portability fix.
the 'redis-sentinel' binary is not currently built on Windows, the quick
workaround is to call 'redis-server --sentinel'
2015-06-10 00:43:46 +02:00
Enrico Giordani 2975545e6a Restored support for the command argument --test-memory
along with -h, --help, -v, --version
2015-06-09 17:21:56 +02:00
Enrico Giordani 64c14409d9 Added back the RealeasePackaingTool project in the RedisServer.sln build
It was removed by mistake in a previous commit.
2015-06-08 20:40:08 +02:00
Enrico Giordani eaf29cc8aa Truncate AOF in case of unexpected EOF.
The Win32 port was not truncating the AOF file.
2015-06-08 20:35:31 +02:00
Enrico Giordani 91d01bf8fb Win32 portability for tests: fix the syntax to invoke 'tail'.
tail -nX file -> tail -X file
2015-06-08 16:23:53 +02:00
antirez fbb9d619f7 Fix 2.8.21 release notes to give full credits. 2015-06-04 12:00:21 +02:00
antirez 7f8b865a65 Redis 2.8.21 2015-06-04 11:32:24 +02:00
Alexis Campailla c59c110e34 More PORT_LONG replacements 2015-06-03 13:39:54 +02:00
Ben Murphy 700b863f13 hide access to debug table 2015-06-03 13:36:02 +02:00
Ben Murphy 5a1b22ad7f disable loading lua bytecode 2015-06-03 13:36:02 +02:00
Enrico Giordani 0aa1c741fc Portability fixes (replaced long with PORT_LONG)
Eliminated 'long' from antirez code, in favor of
PORT_LONG, PORT_LONGLONG, etc.

Portability fixes for LONG_MAX, LONG_MIN.

Replaces some #ifdef _WIN32
2015-06-03 13:15:37 +02:00
Alexis Campailla 3a87d02e1d Fix tabs and indentation 2015-06-03 13:10:35 +02:00
zeliard da310484b0 Fix wrong pointer castings for x64 support 2015-06-03 13:08:33 +02:00
zeliard a2f2a687d5 fix wrong memset argument 2015-06-03 13:08:32 +02:00
zeliard b3b9464bc4 Fix pointer casting for supporting a 64bit case 2015-06-03 13:08:09 +02:00
antirez 1eeb9bd714 Scripting: Lua cmsgpack lib updated to include str8 support 2015-06-03 08:45:56 +02:00
Alexis Campailla f6a2137047 Portability fixes
Add WIN_PORT_FIX macro
Fixed debug oom command
2015-06-01 15:58:31 +02:00
Alexis Campailla 642df0ee9a Minor fixes in VectoredHeapMapper
Fixed boundary check heapEnd
Improved logging
2015-06-01 14:57:39 +02:00
Alexis Campailla 9e7b21ca43 Eliminate #ifdefs related to off_t 2015-05-29 18:03:51 +02:00
Alexis Campailla 03492e244f Add portability macros 2015-05-29 17:48:57 +02:00
Alexis Campailla 97c4b7b827 Merge 2.8 branch from antirez\redis into 2.8 2015-05-29 17:26:06 +02:00
Alexis Campailla 72d34a87e3 Portability fixes (ssize_t, off_t)
Fix definition of ssize_t and off_t.
2015-05-29 15:26:02 +02:00
Alexis Campailla 6ac1b5db87 test: integration\aof continue run on test failure
When the set client statement throws an exception
the whole test run is aborted.

TODO: verify if this a Windows specific issue
2015-05-28 15:36:28 +02:00
therealbill 22ee2f9cd5 adding a sentinel command: "flushconfig"
This new command triggers a config flush to save the in-memory config to
disk. This is useful for cases of a configuration management system or a
package manager wiping out your sentinel config while the process is
still running - and has not yet been restarted. It can also be useful
for scripting a backup and migrate or clone of a running sentinel.
2015-05-25 12:06:57 +02:00
antirez cdedad2322 Sentinel: CKQUORUM tests 2015-05-19 12:27:26 +02:00
antirez 76412ec9c0 Sentinel: SENTINEL CKQUORUM command
A way for monitoring systems to check that Sentinel is technically able
to reach the quorum and failover, using the currently visible Sentinels.
2015-05-19 12:27:26 +02:00
antirez f42fcff6d2 Rewrite smoveCommand test with ternary operator 2015-05-15 17:39:39 +02:00
Glenn Nethercutt 19382c8be6 uphold the smove contract to return 0 when the element is not a member of the source set, even if source=dest 2015-05-15 17:39:39 +02:00
Jungtaek Lim bea224308b protocol error log should be seen debug/verbose level 2015-05-15 17:06:45 +02:00
antirez 22979836e5 Fix 2.8.20 changelog typo 2015-05-05 11:50:30 +02:00
antirez 11934a9f32 Redis 2.8.20 2015-05-05 11:14:33 +02:00
orangemocha 199eb9f568 Merge pull request #237 from MSOpenTech/WixInstaller
Add MSI installer. This is taken from https://github.com/MSOpenTech/redis/pull/210, with a few more tweaks.
2015-05-04 18:55:53 +02:00
Alexis Campailla e28dbb53ad Move MSI to a separate solution
Move MSI to a separate solution, so that builing RedisServer.sln
doesn't require having the Wix Toolset installed.
2015-05-04 18:40:34 +02:00
Alexis Campailla 4a9a87bb20 Updated MSI version number to 2.8.19.1 2015-05-04 08:24:40 -07:00
Alexis Campailla 7b336b19fd Updated license in source tree and MSI 2015-05-04 08:24:35 -07:00
Alexis Campailla 21f69fdf7c msi: added/renamed configuration files
Added redis.windows.conf
Renamed redis.service.conf to redis.windows-service.conf
2015-05-04 08:24:31 -07:00
Alexis Campailla 28735c1d38 Add full license text for Wix UI components 2015-05-04 08:24:26 -07:00
Alexis Campailla d835f244ad MSI fixes & tweaks 2015-05-04 08:24:21 -07:00
Alexis Campailla 9a8aade257 Fix msi build 2015-05-04 08:24:16 -07:00
NickMRamirez 23fdac78a6 Added redis.service.conf that turns on logging to the Windows event viewer. This required that we also log to a file with the logfile setting, otherwise messages are not written to the event viewer...probably a mishandling of Windows OS. The event viewer requires a messages resource in the form of a DLL, so I updated the Win32_Interop project to have a custom build step to compile EventLog.res into EventLog.dll. Updated the WiX project to create the Windows event source and also the directory where the event log file will be written. 2015-05-04 08:24:12 -07:00
NickMRamirez 454a4a920b Updated Word doc to include information about how the Windows service works if installed with the MSI. 2015-05-04 08:24:07 -07:00
NickMRamirez 8e4dcd5360 Added a dialog to the installer that lets the user customize the port and firewall exception. The port will update the config file via a new WiX Custom action project. 2015-05-04 08:24:02 -07:00
NickMRamirez a38bbe72e1 Added a UI to the WiX installer. Also, added license text and branded logo images for Redis. 2015-05-04 08:23:58 -07:00
NickMRamirez a4d2df10b8 Removed WiX compiler binaries. We'll be relying on the developer to have installed WiX instead. 2015-05-04 08:23:53 -07:00
NickMRamirez 7e68545292 Removing x86 WiX installer 2015-05-04 08:23:47 -07:00
NickMRamirez c5db422f6d Removed CONFIG WiX property from install command-line instructions. It might be better to use the default and set the config path later. 2015-05-04 08:23:42 -07:00
NickMRamirez c998816b65 Updated path to WixFirewallExentsion.dll 2015-05-04 08:23:38 -07:00
NickMRamirez 87835eb268 Adding missing WiX compiler and linker .exe files that were ignored by .gitignore 2015-05-04 08:23:33 -07:00
NickMRamirez d5119c4882 Added firewall exception for Redis service 2015-05-04 08:23:13 -07:00
NickMRamirez 733dd88d70 Added WiX binaries to source control for 64-bit Windows Installer so that devs won't have to install WiX. 2015-05-04 08:17:14 -07:00
NickMRamirez 437a9c35ce Added a 64-bit Windows installer 2015-05-04 08:16:03 -07:00
NickMRamirez 9bc6c6eeb6 Added WiX binaries to source control so that dev doesn't have to install WiX. 2015-05-04 08:14:58 -07:00
NickMRamirez 1167266815 Initial commit of WiX installer for Redis 2015-05-04 08:14:11 -07:00
FuGangqiang 8db3969971 sdsfree x and y 2015-05-04 13:03:06 +02:00
FuGangqiang 98756d4c0d fix doc example 2015-05-04 13:03:06 +02:00
FuGangqiang 7316fda33a fix typo 2015-05-04 13:03:06 +02:00
Itamar Haber a5bada19be update copyright year 2015-05-04 12:56:52 +02:00
therealbill f0ab4fd6fd Making sentinel flush config on +slave
Originally, only the +slave event which occurs when a slave is
reconfigured during sentinelResetMasterAndChangeAddress triggers a flush
of the config to disk.  However, newly discovered slaves don't
apparently trigger this flush but do trigger the +slave event issuance.

So if you start up a sentinel, add a master, then add a slave to the
master (as a way to reproduce it) you'll see the +slave event issued,
but the sentinel config won't be updated with the known-slave entry.

This change makes sentinel do the flush of the config if a new slave is
deteted in sentinelRefreshInstanceInfo.
2015-05-04 12:55:30 +02:00
antirez e4c54498db Sentinel: remove useless sentinelFlushConfig() call
To rewrite the config in the loop that adds slaves back after a master
reset, in order to handle switching to another master, is useless: it
just adds latency since there is an fsync call in the inner loop,
without providing any additional guarantee, but the contrary, since if
after the first loop iteration the server crashes we end with just a
single slave entry losing all the other informations.

It is wiser to rewrite the config at the end when the full new
state is configured.
2015-05-04 12:55:30 +02:00
Yossi Gottlieb 81a8ebd7f0 Fix Redis server crash when Lua command exceeds client output buffer
limit.
2015-05-04 12:20:28 +02:00
clark.kang c4d4c1ed12 fix sentinel memory leak 2015-05-04 12:18:13 +02:00
Alexis Campailla 05e0ac85cc Fix tabs in Win32_QFork.cpp 2015-05-01 13:23:15 +02:00
Alexis Campailla 0481910ed0 Fix Windows version check
Correclty check for Windows 8 version (6.2), in case this code
path gets re-enabled again.
Note that Windows 10 has version number 10.0, so it would finally
take the code path originally intended for Windows 8 and higher.
2015-05-01 13:12:02 +02:00
Alexis Campailla 624163165b Disabling use of PAGE_REVERT_TO_FILE_MAP
VirtualProtect is failing with ERROR_INVALID_PARAMETER.
It's possible that this code path never worked because it is
checking for Windows version 8.0. Windows 8's version number is 6.2,
not 8.0.

Conflicts:
	src/Win32_Interop/Win32_QFork.cpp
2015-05-01 13:11:02 +02:00
Alexis Campailla 6076412a35 Qfork: RejoinCOWPages issue with swapping
Fix for https://github.com/MSOpenTech/redis/issues/167

RejoinCOWPages used to call QueryWorkingSetEx to figure out
which pages had been dirtied since the memory map was protected
with PAGE_WRITECOPY. But dirty pages that had been swapped out to
the system page file would be reported as not valid
(VirtualAttributes.Valid == 0) and so we wouldn't restore them into
the file map.
QueryWorkingSetEx only gives information about pages that are in the
working set at the time it is called. Pages can be forced into the
working set using VirtualLock, but that seems like a potentially
risky / expensive solution.
I implemented a solution that uses VirtualQuery to find out which
regions have changed protection from PAGE_WRITECOPY.
2015-05-01 12:40:15 +02:00
antirez 081a0c943f Fix Sentinel memory leak (hiredis bug)
This fixes issue #2535, that was actually an hiredis library bug (I
submitted an issue and fix to the redis/hiredis repo as well).

When an asynchronous hiredis connection subscribes to a Pub/Sub channel
and gets an error, and in other related conditions, the function
redisProcessCallbacks() enters a code path where the link is
disconnected, however the function returns before freeing the allocated
reply object. This causes a memory leak. The memory leak was trivial to
trigger in Redis Sentinel, which uses hiredis, every time we tried to
subscribe to an instance that required a password, in case the Sentinel
was configured either with the wrong password or without password at
all. In this case, the -AUTH error caused the leaking code path to be
executed.

It was verified with Valgrind that after this change the leak no longer
happens in Sentinel with a misconfigured authentication password.
2015-04-28 22:15:12 +02:00
antirez d593ae8ab6 sha1.c: use standard uint32_t. 2015-04-27 12:08:03 +02:00
Oran Agra c72253ec54 fixes to diskless replication.
master was closing the connection if the RDB transfer took long time.
and also sent PINGs to the slave before it got the initial ACK, in which case the slave wouldn't be able to find the EOF marker.
2015-04-01 15:21:08 +02:00
antirez 83eb5e7f54 Test: regression for issue #2473. 2015-03-27 12:11:46 +01:00
antirez 96aa610666 Replication: disconnect blocked clients when switching to slave role.
Bug as old as Redis and blocking operations. It's hard to trigger since
only happens on instance role switch, but the results are quite bad
since an inconsistency between master and slave is created.

How to trigger the bug is a good description of the bug itself.

1. Client does "BLPOP mylist 0" in master.
2. Master is turned into slave, that replicates from New-Master.
3. Client does "LPUSH mylist foo" in New-Master.
4. New-Master propagates write to slave.
5. Slave receives the LPUSH, the blocked client get served.

Now Master "mylist" key has "foo", Slave "mylist" key is empty.

Highlights:

* At step "2" above, the client remains attached, basically escaping any
  check performed during command dispatch: read only slave, in that case.
* At step "5" the slave (that was the master), serves the blocked client
  consuming a list element, which is not consumed on the master side.

This scenario is technically likely to happen during failovers, however
since Redis Sentinel already disconnects clients using the CLIENT
command when changing the role of the instance, the bug is avoided in
Sentinel deployments.

Closes #2473.
2015-03-24 16:14:49 +01:00
Alexis Campailla 8c5b7fd244 fork: let child terminate without requiring signal from parent
The quasi-fork child was waiting for an explicit signal from the parent
before terminating. This synchronization step is unnecessary, and
it makes the child hang if the parent terminates for any reason
while the fork operation is in progress.
In that scenario, and consistently with the Posix version, the child
now completes the fork operation and terminates freely when done.

This fixes https://github.com/MSOpenTech/redis/issues/228
2015-03-23 13:40:27 -07:00
Alexis Campailla 92abb1268b set errno on socket write error
Also introducing some utility functions for translating Windows
error codes to errno error codes.
This part was adapted from existing code in libuv:
https://github.com/libuv/libuv/blob/v1.x/src/win/error.c
2015-03-09 14:47:32 +01:00
antirez 1f5e7b8863 Config: activerehashing option support in CONFIG SET. 2015-03-08 15:34:00 +01:00
antirez f8f40afd5d Fix iterator for issue #2438.
Itereator misuse due to analyzeLatencyForEvent() accessing the
dictionary during the iteration, without the iterator being
reclared as safe.
2015-03-04 11:49:53 -08:00
Alexis Campailla 0f79d72396 Workaround for getpeername() issue
getpeername() is returning invalid addresses on ipv6 sockets accepted
with AcceptEx, filling only 16 bytes of the address structure.
Providing a workaround by saving the remote address returned by
GetAcceptExSockaddrs, which is valid.
2015-02-25 12:27:07 +01:00
Alexis Campailla 322d708f21 getpeername returns 0 on error 2015-02-24 18:11:23 +01:00
Alexis Campailla c3f758c923 Update redis.windows.conf 2015-02-24 18:09:07 +01:00
Alexis Campailla fe6fff14d1 redlis-cli crash on non-printable chars
The debug version of isprint() raises an assert when the input value
is not EOF or in the range 0 through 0xFF, inclusive.
The trick is that the char value needs to be passed as unsigned,
before being converted to int.
2015-02-24 17:16:52 +01:00
Alexis Campailla a39e4ae65d Handle absolute paths for config files 2015-02-24 16:28:33 +01:00
Alexis Campailla b02a6d191d Minor documenation bug (confusing dir and heapdir)
See https://github.com/MSOpenTech/redis/issues/218
2015-02-24 15:31:11 +01:00
Scott Ganyo 1fe315d6d9 Update README.md 2015-02-13 14:24:44 +01:00
Robert Hahn b167e972d2 issue 180: fixed handling of the alt gr key on international keyboards 2015-02-13 14:09:50 +01:00
Alexis Campailla 768e061172 Abort on OOM
It looks like https://github.com/MSOpenTech/redis/commit/62cc0e320d9afe28cc44a642d9e8f5e1c0e5d775#diff-07ce465381b20e496c6fb51bedd3491fR3105
inadvertently made the Windows side not abort when an OOM occurs.
2015-02-13 03:03:58 +01:00
Charles Hooper 1f4074e957 override histfile from env - fixes #831 and copies #833 2015-02-10 14:55:17 +01:00
antirez 9e83d2d26f redis-cli --lru-test implemented (cache workload simulator). 2015-02-10 14:55:17 +01:00
antirez ccbec34fad redis-cli: interactive reconnection for latency modes.
--stat mode already used to reconnect automatically if the server is no
longer available. This is useful since this is an interactive mode used
for debugging, however the same applies to --latency and --latency-dist
modes, so now both use the reconnecting command execution as well.

The reconnection code was modified to use basic VT100 escape sequences
in order to play better with different kinds of output on the screen
when the reconnection happens, and to hide the reconnection attempt
output when finally the reconnection happens.
2015-02-10 14:55:17 +01:00
antirez d29eb68f20 redis-cli --latecy-dist reverted to gray scale.
So far not able to find a color palette within the 256 colors which is
not confusing. However I believe it is a possible task, so will try
better later.
2015-02-10 14:55:17 +01:00
antirez 657f719760 redis-cli --latency-dist now uses a color palette.
Still not happy with the result but low grays are hard to see in certain
monitors with a non perfect gamma.
2015-02-10 14:55:17 +01:00
antirez ff13fa787d redis-cli latency dist: add new top HL. 2015-02-10 14:55:17 +01:00
antirez f6f3cb9458 Add missing latency-dest legend symbol. 2015-02-10 14:55:17 +01:00
antirez 9d9be0e09d Initial implementation of redis-cli --latency-dist. 2015-02-10 14:55:17 +01:00
antirez d4047f7261 Faster memory efficiency test.
This test on Linux was extremely slow, since in Tcl we can't enable
easily tcp-nodelay, so the busy loop used to take *a lot* with bigger
writes. Fixed using pipelining.
2015-02-10 14:48:22 +01:00
Alexis Campailla b93dc1c727 Port diskless replication to Windows
During diskless replication the master forks a child, which on posix
simply inherits the socket file descriptors for the connections to
the slaves.
A unix pipe is also used for the child to report the results back
to the master.

The bulk of the porting work is in making sure that the socket
file descriptors and pipe file descriptor are propagated correctly
from the master to its child.
2015-02-06 16:08:50 +01:00
Alexis Campailla b713fda58f Remove useless qfork synchronization event
There is no apparent reason for the child to wait for the
startOperation event to be signaled.
2015-02-06 16:06:53 +01:00
Alexis Campailla 5677f532f8 Refactor BeginForkOperation
Refactor BeginForkOperation in preparation for diskless replication:
- Separate copying of operation data and child process creation
- Provide specific entry points for each operation type
2015-02-06 15:42:47 +01:00
mattcollier 61290d819d Update redis-cli.c
Code was adding '\n'  (line 521) to the end of NIL values exlusively making csv output inconsistent.  Removed '\n'
2015-02-02 22:50:53 +01:00
orangemocha 3942d52957 Merge pull request #216 from MSOpenTech/orangemocha-CrashOnLargeInsert
Bug fixes
2015-02-02 16:40:01 +01:00
Alexis Campailla 9fd03a982d Fix AV in AllocHeapBlock 2015-02-02 16:10:05 +01:00
antirez 18dc769104 luaRedisGenericCommand(): log error at WARNING level when re-entered.
Rationale is that when re-entering, it is likely due to Lua debugging
hooks. Returning an error will be ignored in most cases, going totally
unnoticed. With the log at least we leave a trace.

Related to issue #2302.
2015-01-22 10:36:23 +01:00
antirez 1dea8b5a29 luaRedisGenericCommand() recursion: just return an error.
Instead of calling redisPanic() to abort the server.

Related to issue #2302.
2015-01-22 10:36:19 +01:00
antirez a0ba7b3f00 Panic on recursive calls to luaRedisGenericCommand().
Related to issue #2302.
2015-01-22 10:36:15 +01:00
antirez e7aa5fb5ef AOF rewrite: set iterator var to NULL when freed.
The cleanup code expects that if 'di' is not NULL, it is a valid
iterator that should be freed.

The result of this bug was a crash of the AOF rewriting process if an
error occurred after the DBs data are written and the iterator is no
longer valid.
2015-01-21 16:42:56 +01:00
antirez 8a41dae49f Add "-lrt" in Makefile for Solaris.
This fix is from @NanXiao, however I was not able to retain authorship
because the Pull Request original repository was removed.
2015-01-09 11:54:52 +01:00
antirez 50cdedd127 Check for __sun macro in solarisfixes.h, not in includers. 2015-01-09 11:22:35 +01:00
antirez 77608ae5ac README section about make distclean reworded / extended. 2015-01-08 16:35:53 +01:00
Jungtaek Lim 5165fb98af Explain make distclean which seems not well known 2015-01-08 16:35:49 +01:00
Alexis Campailla bc8d23c64a Merge branch release-2.8.17 into 2.8 2015-01-06 14:40:16 -05:00
Alexis Campailla 7796c039cb Fix redis-cli pipe mode
Pipe mode was broken due to CRT's translation of CRLF sequences.
2015-01-02 17:48:09 -05:00
Alexis Campailla 69ff2feb70 Merge version 2.8.19 from antirez into 2.8 2014-12-26 16:14:57 +01:00
Alexis Campailla bc2ce9d6e0 Merge version 2.8.18 from antirez into 2.8
Conflicts:
	deps/linenoise/linenoise.c
	deps/lua/src/lua_cjson.c
	redis.conf
	src/anet.c
	src/config.c
	src/networking.c
	src/object.c
	src/rdb.c
	src/redis.c
	src/redis.h
	src/replication.c
	tests/support/server.tcl
2014-12-26 15:20:36 +01:00
Alexis Campailla 8d5716c03e Merge branch 'release-2.8.17' into 2.8
Conflicts:
	bin/release/redis-2.8.17.zip
2014-12-24 00:20:37 +01:00
Alexis Campailla a87bca3e7b replaced // comments #2150 2014-12-24 00:18:58 +01:00
Alexis Campailla a659c7c13a Merge commit 'c94db2ba3849ffe2ae1b3da04bd2860a601afcd5' into release-2.8.17
Conflicts:
	bin/release/redis-2.8.17.zip
2014-12-23 15:01:22 +01:00
antirez 22a0fe8de6 INFO loading stats: three fixes.
1. Server unxtime may remain not updated while loading AOF, so ETA is
not updated correctly.

2. Number of processed byte was not initialized.

3. Possible division by zero condition (likely cause of issue #1932).
2014-12-23 14:52:57 +01:00
Alexis Campailla 1ba3989480 replaced // comments #2150 2014-12-23 01:46:44 +01:00
Alexis Campailla 5c3f6b9d1f redis-benchmark AUTH command to be discarded after the first send #2150
Cherry pick 560ec60ed4
2014-12-22 20:54:17 +01:00
Alon Diamant 585884da45 Fixed memory leaks in rdbSaveToSlavesSockets() 2014-12-22 11:01:21 +01:00
Alexis Campailla c94db2ba38 Fix missing time functions initialization in redis-benchmark
Commit 08e4226e59 broke redis-benchmark.

Made time function initialization automatic on first execution.
Added explicit initialization of time functions in redis-benchmark, to
avoid additional cost on first benchmark execution.
2014-12-20 18:03:34 +01:00
antirez ca3dd5e5ed Fix adjustOpenFilesLimit() logging to match real state.
Fixes issue #2225.
2014-12-19 10:05:09 +01:00
Rhommel Lamas 6f0a7353a6 Add redis-sentinel symlink to a relative path 2014-12-17 12:27:44 +01:00
Alexis Campailla 3b1d4ec032 Move release binaries to release page
Adopting the suggestions at https://github.com/MSOpenTech/redis/issues/172
We no longer commit the binaries into the repo.
Instead, we create periodic releases on the release page.
2014-12-16 16:36:10 +01:00
antirez 902b877dc0 Redis 2.8.19. 2014-12-16 09:18:20 +01:00
antirez 02d465c8fe Don't log admin commands in MONITOR.
Otherwise there are security risks, especially when providing Redis as a
service, the user may "sniff" for admin commands renamed to an
unguessable string via rename-command in redis.conf.
2014-12-13 09:00:03 +01:00
antirez 4d8f4262a4 List of commands flagged as admin commands modified.
The old list did not made much sense... and the flag is currently not
used at all, so no side effects.
2014-12-13 08:59:43 +01:00
Salvatore Sanfilippo d4fc65309d Merge pull request #2092 from rhoml/rhoml-install-sentinel
Adds a symlink for redis-sentinel when Make install
2014-12-12 22:58:56 +01:00
antirez e47e460f1f Lua cmsgpack lib updated to latest version.
It fixes a bad bug that crashes the server in certain conditions
as shown in issue #2210.
2014-12-12 22:57:09 +01:00
Rhommel Lamas 5509c141f8 Add symlink to redis-sentinel during make install 2014-12-12 20:00:08 +01:00
antirez 7de1ef773e SORT: Don't sort Set elements if not needed.
Related to #2094.
2014-12-11 16:01:21 +01:00
Matt Stancliff e945a546af Fix zero-ordering SORT when called against lists
People mostly use SORT against lists, but our prior
behavior was pretending lists were an unordered bag
requiring a forced-sort when no sort was requested.

We can just use the native list ordering to ensure
consistency across replicaion and scripting calls.

Closes #2079
Closes #545 (again)
2014-12-11 16:01:09 +01:00
Ben Dowling d81c38316b Update redis_init_script.tpl
status command currently reports success when redis has crashed and the pid file still exists. Changing to check the actual process is running.
2014-12-11 15:21:53 +01:00
zhanghailei dba57ea910 FIXED redis-benchmark's idle mode.With idle mode shouldn't create write event 2014-12-11 15:21:53 +01:00
Sun He 888ea17548 zipmap.c: update comments above 2014-12-09 16:01:13 +01:00
Deepak Verma 86ebc139c2 replaced // comments #2150 2014-12-09 15:26:26 +01:00
azure provisioned user 3d73f088e1 redis-benchmark AUTH command to be discarded after the first send #2150 2014-12-09 15:26:26 +01:00
Sun He 76d53a6770 sds.c: Correct two spelling mistakes in comments 2014-12-09 15:14:14 +01:00
Sun He 4848cf9335 sds.c/sdscatvprintf: set va_end to finish va_list cpy 2014-12-09 15:14:14 +01:00
Sun He d2f584fa53 sds.c: Correct some comments 2014-12-09 15:14:13 +01:00
Serghei Iakovlev 2ed3f09cc3 Update whatisdoing.sh
Improved getting pid
2014-12-09 13:01:31 +01:00
antirez 77b997d429 Include stropts only if __sun is defined. 2014-12-09 12:59:43 +01:00
Jan-Erik Rediger d409371193 Fix implicit declaration of ioctl on Solaris 2014-12-09 12:57:59 +01:00
Johan Bergström 23b96c02a5 Silence _BSD_SOURCE warnings in glibc 2.20 and forward
See https://sourceware.org/glibc/wiki/Release/2.20#Packaging_Changes
2014-12-09 12:24:30 +01:00
antirez a47a042ea6 Mark whatisdoing.sh as deprecated in top-comment. 2014-12-09 12:18:47 +01:00
Serghei Iakovlev b5737d2d19 getting pid fixes
```sh
$ ~ pidof redis-server
# nothing

$ ~ ps aux | grep [r]edis
redis      593  0.0  0.0  36900  5564 ?        Ssl  Dec02   1:37 /usr/bin/redis-server 127.0.0.1:6379
klay     15927  0.0  0.0  16772  6068 pts/6    S+   13:58   0:00 redis-cli

$ ~ uname -a
Linux edge 3.17.4-1-ARCH #1 SMP PREEMPT Fri Nov 21 21:14:42 CET 2014 x86_64 GNU/Linux
```
2014-12-09 12:09:31 +01:00
Sun He a598e0894b sparkline.c: AddSample skip Empty label 2014-12-09 11:28:53 +01:00
Sun He 7d480abab4 sparkline.c: mov label-ini into the AddSample Function 2014-12-09 11:28:53 +01:00
Jan-Erik Rediger 2f3c860979 Only ignore sigpipe in interactive mode
This allows shell pipes to correctly end redis-cli.

Ref #2066
2014-12-09 09:01:10 +01:00
antirez 0c211a1953 Simplify lua_cmsgpack macro and fix build on old Linux distros.
Thanks to @badboy for the help in checking the build after the fix.
2014-12-05 10:52:56 +01:00
Alexis Campailla 08e4226e59 Revisit time functions
Addressing https://github.com/MSOpenTech/redis/issues/188

- Made gettimeofday use GetSystemTimePreciseAsFileTime when available
- Introduced definitions for gettimeofday_fast and gettimeofday_precise,
  so that calls can be specialized based on specific usage requirements
- Introduced GetHighResRelativeTime, for high-resolution relative time
  measurements on all Windows versions.
2014-12-04 18:26:53 +01:00
Alexis Campailla 7827f41357 Issue 173: add child process log messages to main log file
Slave processes were not using the master process log file.
On Unix this is relying on the server.logfile variable being available
to the slave processes through fork(), and reopening the logfile
in the slaves (on every log event).
On Windows we don't use server.logfile and require an explicity call
to setLogFile.
I resorted to explicitly passing the logfile to the slaves as a
command line argument, so the logfile argument (and logging) can be
available to the slave before qfork and globals setup have completed.

Writing to the same file atomically from multiple processes requires
using CreateFile with FILE_APPEND_DATA, instead of fopen, which provides
atomicity on Unix but not on Windows.

Also changed the implementation to not reopen the logfile on every
log event, and not flushing the file on every write. Performance is
dramaticaly improved this way.
2014-12-04 16:02:45 +01:00
antirez d6ada4d1a8 Redis 2.8.18. 2014-12-04 11:36:52 +01:00
antirez 7c671c09a1 Check that tcp-backlog is matched by /proc/sys/net/core/somaxconn. 2014-12-04 11:07:55 +01:00
antirez d56ef62983 Network bandwidth tracking + refactoring.
Track bandwidth used by clients and replication (but diskless
replication is not tracked since the actual transfer happens in the
child process).

This includes a refactoring that makes tracking new instantaneous
metrics simpler.
2014-12-03 12:17:18 +01:00
antirez f60c8c0999 Don't show the ASCII logo if syslog is enabled.
Closes issue #1935.
2014-12-03 10:52:09 +01:00
antirez 04231cb7d7 Regression test for issue #2175. 2014-12-03 10:41:06 +01:00
antirez 6e0277769d Handle infinite explicitly in createStringObjectFromLongLong(). 2014-12-03 10:41:06 +01:00
antirez 42695fdfe6 Use exp format and more precision output for ZSCAN.
Ref: issue #2175
2014-12-03 10:41:06 +01:00
antirez 164ad2ead1 Over 80 chars comment trimmed in pfcountCommand(). 2014-12-02 17:03:15 +01:00
antirez 0e40124d0f Mark PFCOUNT as read-only, even if not true.
PFCOUNT is technically speaking a write command, since the cached value
of the HLL is exposed in the data structure (design error, mea culpa), and
can be modified by PFCOUNT.

However if we flag PFCOUNT as "w", read only slaves can't execute the
command, which is a problem since there are environments where slaves
are used to scale PFCOUNT reads.

Nor it is possible to just prevent PFCOUNT to modify the data structure
in slaves, since without the cache we lose too much efficiency.

So while this commit allows slaves to create a temporary inconsistency
(the strings representing the HLLs in the master and slave can be
different in certain moments) it is actually harmless.

In the long run this should be probably fixed by turning the HLL into a
more opaque representation, for example by storing the cached value in
the part of the string which is not exposed (this should be possible
with SDS strings).
2014-12-02 17:01:55 +01:00
antirez d0cc96f053 Mark diskless replication as experimental in redis.conf. 2014-12-02 14:13:44 +01:00
antirez a81043959a Test: wait for actual startup in start_server.
start_server now uses return value from Tcl exec to get the server pid,
however this introduces errors that depend from timing: a lot of the
testing code base assumed the server to be actually up and running when
server_start returns.

So the old code that waits to see the pid in the log file was restored.
2014-11-28 12:57:40 +01:00
antirez f0c00a14ed Test: try to cleanup still running Redis instances on exit.
It's hard to run the Redis test continuously if it leaks processes on
exceptions / errors.
2014-11-28 12:57:30 +01:00
antirez 3ac62dff23 Test framework: exit on timeout with report.
There was no sane way to detect tests that may never end because of
Redis bugs or tests bugs.
2014-11-28 12:54:17 +01:00
antirez 60c09dcf09 redis-benchmark: default num of requests is now 100000.
10000 completes in a too short time and may easily provide unreliable
figures because of tiny duration.
2014-11-28 10:38:58 +01:00
Matthias Petschick e689e93663 fix benchmark memleak in loop mode 2014-11-28 10:38:54 +01:00
antirez 01854f87e8 Document redis-cli --stat in --help output. 2014-11-25 18:25:58 +01:00
Matt Stancliff e305df099a Fix lua-cmsgpack 64 bit integer on 32 bit platform
This syncs lua-cmsgpack with the mattsta/lua-cmsgpack upstream.

Fixes #2161
2014-11-25 15:56:57 +01:00
antirez 9854d03fad Avoid valgrind memory leak false positive in processInlineBuffer().
zmalloc(0) cauesd to actually trigger a non-zero allocation since with
standard libc malloc we have our own zmalloc header for memory tracking,
but at the same time the returned pointer is at the end of the block and
not in the middle. This triggers a false positive when testing with
valgrind.

When the inline protocol args count is 0, we now avoid reallocating
c->argv, preventing the issue to happen.
2014-11-25 14:51:04 +01:00
antirez 5ddf56f9b1 Attempt to prevent false positives in replication test. 2014-11-24 11:55:16 +01:00
antirez b19e745780 scripting.tcl tests order fixed to match unstable branch. 2014-11-14 17:28:58 +01:00
antirez ce96069676 lua_cjson.c Lua includes: angled -> quoted. 2014-11-14 17:28:54 +01:00
antirez ead8e31b28 Fix non-linux builds error introduced with THP checks. 2014-11-14 17:28:49 +01:00
Matt Stancliff 5d8c88fdc1 Lua: add cmsgpack scripting tests
Basically: test to make sure we can load cmsgpack
and do some sanity checks to make sure pack/unpack works
properly.  We also have a bonus test for circular encoding
and decoding because I was curious how it worked.
2014-11-14 17:28:45 +01:00
Matt Stancliff 381863be5c Lua: upgrade cmsgpack to 0.4.0
Main reasons for upgrade:
  - Remove a warning when building Redis
  - Add multi pack/unpack
  - Improve memory usage and use Lua allocator properly
  - Fix some edge case encoding/decoding bugs
2014-11-14 17:28:40 +01:00
Matt Stancliff a7b58f1569 Lua: remove new warning added by cjson header
clang doesn't like "extern inline" when no definition
is given right away.
2014-11-14 17:28:35 +01:00
Matt Stancliff 56e1861398 Lua: Use Redis solaris compatability for cjson too
cjson calls isinf, but some Solaris versions don't have isinf
even with the attempted fix we have in deps/Makefile.

We can harmlessly include the Redis solarisfixes.h header to
give cjson proper isinf.

Note: cjson has a compile-time setting for using their own defined
isinf, but the Redis definition in solarisfixes.h is more complete.

Fixes antirez#1620
2014-11-14 17:28:32 +01:00
Matt Stancliff e2983dd03f Lua: Upgrade cjson to 2.1.0 (2012-03-01)
The new cjson has some improvements over our current version including
increased platform compatability, a new resource limit to restrict
decode depth, and better invalid number handling.

One minor change was required to deps/Makefile because this version
of cjson doesn't export itself globally, so we added a quick little
define of -DENABLE_CJSON_GLOBAL.

cjson now has an optional higher performing float parsing interface,
but we are not including it (g_fmt.c, dtoa.c) because it requires
endianness declaration during compile time.

This commit is exactly lua_cjson.c from 2.1.0 with one minor
change of altering the two Lua includes for local search
instead of system-wide importing.
2014-11-14 17:28:27 +01:00
Matt Stancliff 2828bbd511 Lua: add cjson scripting test
Two simple decode tests added mainly to check that
the 'cjson' global gets registered and is usable.
2014-11-14 17:28:23 +01:00
Matt Stancliff 1e501d9fd6 Lua: Add bitop
A few people have written custom C commands because bit
manipulation isn't exposed through Lua.  Let's give
them Mike Pall's bitop.

This adds bitop 1.0.2 (2012-05-08) from http://bitop.luajit.org/

bitop is imported as "bit" into the global namespace.

New Lua commands: bit.tobit, bit.tohex, bit.bnot, bit.band, bit.bor, bit.bxor,
bit.lshift, bit.rshift, bit.arshift, bit.rol, bit.ror, bit.bswap

Verification of working (the asserts would abort on error, so (nil) is correct):
127.0.0.1:6379> eval "assert(bit.tobit(1) == 1); assert(bit.band(1) == 1); assert(bit.bxor(1,2) == 3); assert(bit.bor(1,2,4,8,16,32,64,128) == 255)" 0
(nil)
127.0.0.1:6379> eval 'assert(0x7fffffff == 2147483647, "broken hex literals"); assert(0xffffffff == -1 or 0xffffffff == 2^32-1, "broken hex literals"); assert(tostring(-1) == "-1", "broken tostring()"); assert(tostring(0xffffffff) == "-1" or tostring(0xffffffff) == "4294967295", "broken tostring()")' 0
(nil)

Tests also integrated into the scripting tests and can be run with:
./runtest --single unit/scripting

Tests are excerpted from `bittest.lua` included in the bitop distribution.
2014-11-14 17:28:19 +01:00
unknown eb88474985 issue 181: config file ignored when --service-name argument passed 2014-11-13 16:41:51 -08:00
antirez d9326cb83d THP detection for LATENCY DOCTOR. 2014-11-12 11:17:31 +01:00
antirez 011cfdfb6b Check THP support at startup and warn about it. 2014-11-12 11:17:27 +01:00
antirez c0266d87ae THP detection / reporting functions added. 2014-11-12 11:17:24 +01:00
antirez a5fcf44fcc Diskless SYNC: fix RDB EOF detection.
RDB EOF detection was relying on the final part of the RDB transfer to
be a magic 40 bytes EOF marker. However as the slave is put online
immediately, and because of sockets timeouts, the replication stream is
actually contiguous with the RDB file.

This means that to detect the EOF correctly we should either:

1) Scan all the stream searching for the mark. Sucks CPU-wise.
2) Start to send the replication stream only after an acknowledge.
3) Implement a proper chunked encoding.

For now solution "2" was picked, so the master does not start to send
ASAP the stream of commands in the case of diskless replication. We wait
for the first REPLCONF ACK command from the slave, that certifies us
that the slave correctly loaded the RDB file and is ready to get more
data.
2014-11-11 17:27:22 +01:00
antirez ec1ab0f18b Disconnect timedout slave: regression introduced with diskless repl. 2014-11-11 17:25:58 +01:00
unknown 9acbc2cc68 issue 182: provide docx file content as github markdown for easier reading for those without a .docx file viewer. 2014-11-08 23:02:51 -08:00
unknown 0287e7da15 binaries for issue 170 2014-11-05 15:39:56 -08:00
unknown 47406f9591 issue 170: Patching part of the LP64/LLP64 ABI issue in order to ease immediate replication pain. 2014-11-05 15:39:34 -08:00
Matt Stancliff eb67ca0f00 redis-cli: ignore SIGPIPE network errors
Closes #2066
2014-10-30 12:02:32 +01:00
antirez bb9ad32cb0 Fix DEBUG POPULATE warning for lack of casting. 2014-10-29 14:36:55 +01:00
antirez a37f8ec8b4 DEBUG POPULATE two args form implemented.
The old DEBUG POPULATE form for automatic creation of test keys is:

    DEBUG POPULATE <count>

Now an additional form is available:

    DEBUG POPULATE <count> <prefix>

When prefix is not specified, it defaults to "key", so the keys are
named incrementally from key:0 to key:<count-1>. Otherwise the specified
prefix is used instead of "key".

The command is useful in order to populate different Redis instances
with key names guaranteed to don't collide. There are other debugging
uses, for example it is possible to add additional N keys using a count
of N and a random prefix at every call.
2014-10-29 14:36:55 +01:00
antirez b2509d7759 redis-cli: add missing newline in error message. 2014-10-29 14:35:48 +01:00
antirez 9b7a190c82 Diskless replication: missing listRewind() added.
This caused BGSAVE to be triggered a second time without any need when
we switch from socket to disk target via the command

    CONFIG SET repl-diskless-sync no

and there is already a slave waiting for the BGSAVE to start.
Also comments clarified about what is happening.
2014-10-29 14:34:58 +01:00
antirez 49629a2e34 Log slave ip:port in more log messages. 2014-10-29 14:34:58 +01:00
antirez 081eeb9f6b Use new slave name function for diskless repl reporting. 2014-10-29 14:34:58 +01:00
antirez 72ea77af0b Added a function to get slave name for logs. 2014-10-29 14:34:51 +01:00
antirez 16319c69b1 Diskless replication: log BGSAVE delay only when it is non-zero. 2014-10-29 14:34:25 +01:00
antirez bafd3f646f Document repl-diskless-sync-delay in redis.conf. 2014-10-29 14:34:25 +01:00
antirez f71c4d54d1 Diskless sync delay is now configurable. 2014-10-29 14:34:18 +01:00
antirez 4b520177b3 Remove duplicated log message about starting BGSAVE. 2014-10-29 14:33:50 +01:00
antirez 7e8a471baf Diskless replication documented inside example redis.conf. 2014-10-29 14:33:50 +01:00
antirez d57ed95222 Diskless replication tested with the multiple slaves consistency test. 2014-10-29 14:33:50 +01:00
antirez 7d32dfc69f Diskless replication: child -> parent communication improved.
Child now reports full info to the parent including IDs of slaves in
failure state and exit code.
2014-10-29 14:33:50 +01:00
antirez 7728ee809d Translate rio fdset target EWOULDBLOCK error into ETIMEDOUT.
EWOULDBLOCK with the fdset rio target is returned when we try to write
but the send timeout socket option triggered an error. Better to
translate the error in something the user can actually recognize as a
timeout.
2014-10-29 14:33:50 +01:00
antirez 7cffd74b38 Diskless replication: set / reset socket send timeout.
We need to avoid that a child -> slaves transfer can continue forever.
We use the same timeout used as global replication timeout, which is
documented to also affect I/O operations during bulk transfers.
2014-10-29 14:33:50 +01:00
antirez eff8fb6f39 anet.c: new API anetSendTimeout(). 2014-10-29 14:33:50 +01:00
antirez c38bb5b2ea Diskless replication: less debugging printfs around. 2014-10-29 14:33:50 +01:00
antirez 348c4f6ce3 rio.c fdset write() method fixed: wrong type for return value. 2014-10-29 14:33:50 +01:00
antirez a7d0137075 rio fdset target: handle short writes.
While the socket is set in blocking mode, we still can get short writes
writing to a socket.
2014-10-29 14:33:50 +01:00
antirez 23bf435f54 anet.c: API to set sockets back to blocking mode. 2014-10-29 14:33:50 +01:00
antirez 9a521e6c74 Diskless replication: rio fdset target new supports buffering.
To perform a socket write() for each RDB rio API write call was
extremely unefficient, so now rio has minimal buffering capabilities.
Writes are accumulated into a buffer and only when a given limit is
reacehd are actually wrote to the N slaves FDs.

Trivia: rio lacked support for buffering since our targets were:

1) Memory buffers.
2) C standard I/O.

Both were buffered already.
2014-10-29 14:33:50 +01:00
antirez 9588973fda Diskless replication: Various fixes to backgroundSaveDoneHandlerSocket() 2014-10-29 14:33:50 +01:00
antirez 8a618971bd Diskless replication: don't send "\n" pings to slaves.
This is useful for normal replication in order to refresh the slave
when we are persisting on disk, but for diskless replication the
child is already receiving data while in WAIT_BGSAVE_END state.
2014-10-29 14:33:50 +01:00
antirez b794b94797 Diskless replication: remove 40 bytes EOF mark from end of RDB file. 2014-10-29 14:33:50 +01:00
antirez 3f1f29fdf3 Diskless replication: swap inverted branches to compute read len. 2014-10-29 14:33:50 +01:00
antirez dbc6e9a1ef Diskless replication: don't enter the read-payload branch forever. 2014-10-29 14:33:49 +01:00
antirez adf55b2337 syncReadLine(): actually enforce buffer size limits. 2014-10-29 14:33:49 +01:00
antirez 89f82a25e1 Diskless replication: EOF:<mark> streaming support slave side. 2014-10-29 14:33:49 +01:00
antirez 583a762cd9 Diskless replication: redis.conf and CONFIG SET/GET support. 2014-10-29 14:33:49 +01:00
antirez 31b0e13268 Diskless replication: trigger a BGSAVE after a config change.
If we turn from diskless to disk-based replication via CONFIG SET, we
need a way to start a BGSAVE if there are slaves alerady waiting for a
BGSAVE to start. Normally with disk-based replication we do it as soon
as the previous child exits, but when there is a configuration change
via CONFIG SET, we may have slaves in WAIT_BGSAVE_START state without
an RDB background process currently active.
2014-10-29 14:33:49 +01:00
antirez d403e4ae63 Diskless replication flag renamed repl_diskless -> repl_diskless_sync. 2014-10-29 14:33:49 +01:00
antirez 2f0b58e4ed Diskless replication: trigger diskless RDB transfer if needed. 2014-10-29 14:33:49 +01:00
antirez 82bfae5b70 Diskless replication: handle putting the slave online. 2014-10-29 14:33:49 +01:00
antirez 132c108f17 Diskless replication: read report from child. 2014-10-29 14:33:49 +01:00
antirez e82ec2c5d8 Diskless replication: child writes report to parent. 2014-10-29 14:33:49 +01:00
antirez 2ed67e4a9e rio.c fdset target: tolerate (and report) a subset of FDs in error.
Fdset target is used when we want to write an RDB file directly to
slave's sockets. In this setup as long as there is a single slave that
is still receiving our payload, we want to continue sennding instead of
aborting. However rio calls should abort of no FD is ok.

Also we want the errors reported so that we can signal the parent who is
ok and who is broken, so there is a new set integers with the state of
each fd. Zero is ok, non-zero is the errno of the failure, if avaialble,
or a generic EIO.
2014-10-29 14:33:49 +01:00
antirez 51864fcdd7 Diskless replication: parent-child pipe and a few TODOs. 2014-10-29 14:33:49 +01:00
antirez 1b4cadb664 Diskless replication: RDB -> slaves transfer draft implementation. 2014-10-29 14:33:49 +01:00
antirez 38dee9dc51 rio.c: draft implementation of fdset target implemented. 2014-10-29 14:33:49 +01:00
antirez 5d295fea12 rio.c refactoring before adding a new target. 2014-10-29 14:33:49 +01:00
antirez aef4c60c78 Add some comments in syncCommand() to clarify RDB target. 2014-10-29 14:33:49 +01:00
antirez 81abd1e178 Define different types of RDB childs.
We need to remember what is the saving strategy of the current RDB child
process, since the configuration may be modified at runtime via CONFIG
SET and still we'll need to understand, when the child exists, what to
do and for what goal the process was initiated: to create an RDB file
on disk or to write stuff directly to slave's sockets.
2014-10-29 14:33:49 +01:00
antirez 1e633f21c5 RDB file creation refactored to target non-disk target. 2014-10-29 14:33:49 +01:00
antirez ff8a3baaf7 Replication: better way to send a preamble before RDB payload.
During the replication full resynchronization process, the RDB file is
transfered from the master to the slave. However there is a short
preamble to send, that is currently just the bulk payload length of the
file in the usual Redis form $..length..<CR><LF>.

This preamble used to be sent with a direct write call, assuming that
there was alway room in the socket output buffer to hold the few bytes
needed, however this does not scale in case we'll need to send more
stuff, and is not very robust code in general.

This commit introduces a more general mechanism to send a preamble up to
2GB in size (the max length of an sds string) in a non blocking way.
2014-10-29 14:33:30 +01:00
Jonathan Pickett 29fa2f09a4 Replaced WIN32_IOCP guard around QueryPerformnaceCounter code with _WIN32. Updating binary package. 2014-10-28 22:01:00 -07:00
Jonathan Pickett 063be1b6be Merge pull request #186 from deepakverma/2.8
Using QueryPerformancecounter to measure latency in redis-benchmark.exe
2014-10-28 21:03:53 -07:00
deepakv 7c6644442b Using QueryPerformancecounter to measure latency in redis-benchmark.exe
Redis-benchmark on windows seems to be not able to calculate the time granularity in micro seconds.
     Came across this article http://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx and updated the benchmark for latency measurements accordingly.

     Windows:
     Following is output from windows for micro seconds taken for each request. Where for any request taking less than 1 ms is being calculated as 0
     redis-benchmark.exe -h <azurerediscache> -a pwd -c 1 -d 1024 -t get -n 10
     0,0,0,0,0,0,0,0

     Linux:
     src/redis-benchmark -h <azurerediscache> -a pwd -c 1 -d 1024 -t get -n 10
     792,800,808,820,837,845,888,891,971,2498

     After the change on windows now it shows following:
     796,809,887,890,893,943,944,974
2014-10-23 12:10:18 -07:00
antirez b6203138d3 Linenoise README updated to match source code. 2014-10-06 10:02:08 +02:00
Miguel Parramon 85b15acb44 redis.conf small grammar fix
😄

Closes #2034
2014-10-06 10:02:08 +02:00
Ezequiel Lovelle 09fc0fbbe4 Fix typo
Closes #2029
2014-10-06 10:02:08 +02:00
Gregory Petrosyan 03b36eef72 Fix typos in comments
Closes #2002
2014-10-06 10:01:36 +02:00
Matt Stancliff e1ccd7243f Add missing 'by' 2014-10-06 10:01:36 +02:00
Juarez Bochi 364aeed96d Fix typo in scripting.c comment
Closes #1960
2014-10-06 10:01:36 +02:00
T.J. Schuck a7a2f69bdb Fix typo radis -> redis
Closes #1938
2014-10-06 10:01:36 +02:00
Matt Stancliff 1adc4a7888 Cleanup wording of dictScan() comment
Some language in the comment was difficult
to understand, so this commit: clarifies wording, removes
unnecessary words, and relocates some dependent clauses
closer to what they actually describe.

I also tried to break up longer chains of thought
(if X, then Y, and Q, and also F, so obviously M)
into more manageable chunks for ease of understanding.
2014-10-06 10:01:36 +02:00
Matt Stancliff c3375fbdff Remove trailing spaces from tests 2014-10-06 10:01:27 +02:00
Matt Stancliff c4d32c03d0 Fix spelling in some test cases 2014-10-06 10:01:05 +02:00
Jan-Erik Rediger 919a4c3126 Fix sentinel.conf typo
Closes #1739
2014-10-06 10:00:48 +02:00
Xiaojie Zhang 8a1d16fe5c Fix comment inconsistencies in ziplist.c
Closes #1523
2014-10-06 10:00:48 +02:00
Matt Stancliff e0ffc863c6 Clean up text throughout project
- Remove trailing newlines from redis.conf
  - Fix comment misspelling
  - Clarifies zipEncodeLength usage and a C API mention (#1243, #1242)
  - Fix cluster typos (inspired by @papanikge #1507)
  - Fix rewite -> rewrite in a few places (inspired by #682)

Closes #1243, #1242, #1507
2014-10-06 10:00:43 +02:00
Matt Stancliff 22e6f434f8 Spell software correctly 2014-10-06 09:59:52 +02:00
Aaron Rutkovsky 3101760937 Fix typos
Closes #1513
2014-10-06 09:59:02 +02:00
Ben d3005539c5 Grammar and typo fixes in redis.conf
Closes #1441
2014-10-06 09:58:56 +02:00
xuxiang 3c99e429cf Fix typo in redis.h
Closes #1386
2014-10-06 09:58:18 +02:00
Ted Nyman 55597bbd67 Fix on-place -> in-place
Closes #1373
2014-10-06 09:58:18 +02:00
Michael Parker a5044c254d Fix hash table size in comment for dictScan
Closes #1351
2014-10-06 09:58:18 +02:00
Jan-Erik Rediger 33daf8e9a9 Fix many small typos
Closes #1871
2014-10-06 09:58:11 +02:00
zionwu b72422e100 Fix incorrect comments
error != success; and 0 != number of bytes written

Closes #1806
2014-10-06 09:57:01 +02:00
Jan-Erik Rediger 6cdd38f947 Fix typo in redis.conf
Closes #1713
2014-10-06 09:57:01 +02:00
Juarez Bochi 6b64fa49f8 Fix typo
Closes #1682
2014-10-06 09:57:01 +02:00
Agis Anastasopoulos fc9bce45c5 Fix typo
Closes #1544
2014-10-06 09:57:01 +02:00
Jan-Erik Rediger 575e293ddd Fix typo: ad -> and
Closes #1537
2014-10-06 09:57:01 +02:00
Matt Stancliff d05fcaffa0 Update linenoise accessory files
The core linenoise code was being backported, but not
the README or example.  It's less confusing for users
if everything matches across directories.

Fix inspired by @thrig

Closes #1872
2014-10-06 09:57:01 +02:00
Manuel Meurer a99d187bc4 Improve disable save comment in redis.conf
Closes #1897
2014-10-06 09:57:01 +02:00
Lynn 904bd0400c Remove surplus double quotes
Closes #1877
2014-10-06 09:57:01 +02:00
jonathan pickett 18d1138e75 redis-server not being built in debug because of project configuration manager setting 2014-10-01 15:46:58 -07:00
jonathan pickett 450fd83a9a I found a case where the temp-rewriteaof-old-xxxx.aof files were not being deleted. Added the _O_TEMPORARY flag to the open() call to guarantee that the underlying CreateFile call is being called with the FILE_FLAG_DELETE_ON_CLOSE. 2014-10-01 15:43:31 -07:00
jonathan pickett bd27d3bd9b Restoring the ability to compile without IOCP. To do so remove the WIN32_IOCP definition in the C/C++\Preporcessor\Preprocessor Definitions in all projects. Performance is 30-40% better with IOCP. 2014-09-23 15:28:38 -07:00
antirez 04b6945ebc Linenoise lib updated. 2014-09-22 14:56:01 +02:00
jonathan pickett a9e3429538 issue 169: missed adding app.config 2014-09-21 13:04:33 -07:00
jonathan pickett 51cac40c73 Added a project to take current redis version number in src\version.h and propagate this number into the release documentation and the name of the release zip file. This replaces the powershell script used previously to build the binary release package zip. 2014-09-19 17:12:12 -07:00
jonathan pickett 96898fa51c Merge branch '2.8antirez' into 2.8 2014-09-19 12:09:05 -07:00
jonathan pickett c7b6d311df finishing 2.8.15-->2.8.16 version update 2014-09-16 18:53:49 -07:00
jonathan pickett 18534064c9 merge antirez changes 2.8.15-->2.8.16 2014-09-16 17:05:36 -07:00
jonathan pickett 915c0dd656 Merge changes from Posix Redis through 2.8.15 into MSOpenTech branch 2014-09-15 18:10:10 -07:00
jonathan pickett 874c21d801 issue 166: master/slave sync with RDB > 2G. cause: off_t defined as long. longs are 4-bytes on x64 Windows. Redefined impacted vars as int64_t. 2014-09-09 19:30:36 -07:00
jonathan pickett 763d7b7c6a updated release notes for persistence-available flag 2014-09-06 14:46:26 -07:00
jonathan pickett 69a5ea090a 2.8.14 binaries with persistence-available flag 2014-09-06 14:38:11 -07:00
jonathan pickett b001508333 Merge branch '2.8' of https://github.com/MSOpenTech/redis into 2.8 2014-09-06 14:23:46 -07:00
jonathan pickett 0c3a93b8a2 adding persistence-available flag 2014-09-06 14:23:36 -07:00
jonathan pickett c9c6ac2056 updated release package, nuspecs, and docs 2014-09-06 14:14:04 -07:00
jonathan pickett 1688851b13 Merge antirez 2.8.14 into MSOPENTech 2.8 branch
Conflicts:
	src/ae.c
	src/bitops.c
	src/dict.c
	src/fmacros.h
	src/hyperloglog.c
	src/networking.c
	src/redis-check-dump.c
	src/redis.c
	src/sds.c
	src/t_string.c
	src/t_zset.c
	src/util.c
2014-09-06 13:44:19 -07:00
Kirk Shoop a2119ce3a5 appveyor config 2014-09-04 00:22:25 -07:00
jonathan pickett 8bea36f67b forgot to add the 2.8.13 binary to the last commit 2014-09-03 16:06:00 -07:00
Kirk Shoop e5328c06b4 add nuget and chocolatey badges 2014-09-03 07:55:46 -07:00
jonathan pickett 0e03891633 updated release notes for 2.8.13 and updated name of pre-compiled binaries zip package 2014-09-02 20:06:06 -07:00
jonathan pickett 92e96ad66b Merge branch '2.8' of https://github.com/MSOpenTech/Redis into 2.8 2014-09-02 19:54:05 -07:00
Kirk Shoop (MS OPEN TECH) 95f845b691 add script to push nupkgs 2014-08-29 10:45:54 -07:00
jonathan pickett ff6aee6fa3 merge for 2.8.13 2014-08-19 17:46:27 -07:00
jonathan pickett 79afb8e15e Merge branch '2.8' of https://github.com/MSOpenTech/Redis into 2.8
Conflicts:
	src/aof.c
2014-08-19 17:45:29 -07:00
jonathan pickett 6f4ce3f83e documenting problem discovered in issue 157 2014-08-19 13:27:16 -07:00
jonathan pickett c3358cc869 Merge branch '2.8' of https://github.com/MSOpenTech/Redis into 2.8 2014-08-19 12:38:13 -07:00
jonathan pickett 36f30412b5 issue 161: Memory allocator not compiled to be thread safe. Background AOF fsync code (bio.c) was allocating memory. This caused heap corruption. 2014-08-14 19:40:56 -07:00
jonathan pickett 16cefcf0b5 reworked COW join for Win8+ 2014-08-12 12:20:35 -07:00
Jonathan Pickett 6d364f41ce Merge pull request #156 from kenny-evitt/service-doc-minor-fixes
Minor fixes to 'service' document
2014-08-04 15:58:37 -07:00
jonathan pickett 31e9621f06 code review feedback on 432a38e53d7844a7bcf8131ddaa4c86d: moved heap memory mapped file into Redis sub directory under local app data folder 2014-07-31 17:23:13 -07:00
jonathan pickett 8d28cf7542 issue 155: temp-rewriteaof-old-xxxxx.aof files not being cleaned up 2014-07-31 15:53:00 -07:00
Kenny Evitt 33018d61a5 Fix text for "Starting the Service" section. 2014-07-30 15:26:03 -04:00
Kenny Evitt 96f3fc015a Remove blank heading lines. 2014-07-30 15:24:53 -04:00
jonathan pickett f52ce3c2c7 added heapdir directive to allow for configuration of where QFork memory mapped file lives 2014-07-29 15:41:41 -07:00
jonathan pickett 94e40d1034 Merge branch '2.8' of https://github.com/MSOpenTech/Redis into 2.8 2014-07-28 18:11:09 -07:00
jonathan pickett 8cb1d65616 Merge branch '2.8antirez' into 2.8: raise version from 2.8.12 to 2.8.13
Conflicts:
	src/Makefile.dep
	src/aof.c
	src/redis-cli.c
	tests/instances.tcl
	tests/integration/replication.tcl
2014-07-28 18:10:57 -07:00
jonathan pickett c6c93699cc Service install with a full path to the conf file was failing. Part of this was due to not passing quotes along with arguments with spaces. The other part was not adding access allowed ACEs on all accessed paths. 2014-07-28 15:15:09 -07:00
jonathan pickett fb12b5738d issue 154: [save ""] not working after fix for issue 153 2014-07-23 10:34:32 -07:00
jonathan pickett 9e191b4b58 setup changes in preparation for official Windows 2.8.12 release 2014-07-22 17:07:42 -07:00
jonathan pickett dbc7669fff issue 152: master DNS alias not resolving 2014-07-22 16:54:51 -07:00
jonathan pickett 5e05dad83a issue 153: command line parsing dying on imbalanced quotes in comments 2014-07-22 15:58:40 -07:00
jonathan pickett 192b285b14 corrected the TCP keepalive code for WinSock 2014-07-21 17:35:00 -07:00
jonathan pickett d47adb19ac improved path parsing for included conf files 2014-07-21 17:33:12 -07:00
jonathan pickett b7a045d747 Creation of QFork memory mapped file now respects the 'dir' .conf file directive. This allows for the QFork file to live in separate directory from the main executable. 2014-07-16 15:48:40 -07:00
jonathan pickett 4e71fc1c6f issue 145: there were a few places where our fwrite implementation was not used because of include file ordering 2014-07-15 13:13:04 -07:00
jonathan pickett 4df3af4e6e issue 146: changes to network layer between 2.8.9 and 2.8.12 broke IOCP async connect code 2014-07-14 19:57:21 -07:00
jonathan pickett 128f5b53de issue 148: post build step fails when current directory is not in path 2014-07-09 20:54:10 -07:00
jonathan pickett 88a62862d3 issue 144: spaces in path breaking QFork child launch 2014-07-07 15:22:26 -07:00
jonathan pickett deb9d5cb66 formatting changes 2014-07-03 20:01:08 -07:00
jonathan pickett 2f2985275b Updating readme.md for the latest build. Also tweaking the heap size requirement in the unit test configuration so that I can run more instances without running out of disk space. 2014-07-03 19:53:24 -07:00
jonathan pickett 52c98f5cb8 issue 126: fwrite() failure with buffers straddling page boundaries during background AOF save 2014-07-03 18:47:10 -07:00
jonathan pickett 9613f9a2a6 issue 143: Added more detailed error messages for ERROR_COMMITMENT_LIMIT and ERROR_DISK_FULL errors in QFork code. 2014-07-03 15:30:56 -07:00
jonathan pickett 96e0be50bb Merge branch '2.8antirez' into 2.8. Updates version from 2.8.9 to 2.8.12.
Conflicts:
	deps/hiredis/async.c
	deps/hiredis/examples/example-ae.c
	deps/hiredis/hiredis.c
	deps/hiredis/hiredis.h
	deps/hiredis/net.c
	deps/hiredis/net.h
	deps/jemalloc/COPYING
	deps/jemalloc/INSTALL
	deps/jemalloc/README
	deps/jemalloc/bin/pprof
	deps/jemalloc/config.guess
	deps/jemalloc/config.sub
	deps/jemalloc/include/jemalloc/internal/ckh.h
	deps/jemalloc/include/jemalloc/internal/hash.h
	deps/jemalloc/include/jemalloc/internal/prng.h
	deps/jemalloc/include/jemalloc/internal/ql.h
	deps/jemalloc/include/jemalloc/internal/qr.h
	deps/jemalloc/include/jemalloc/internal/quarantine.h
	deps/jemalloc/include/jemalloc/internal/rb.h
	deps/jemalloc/include/jemalloc/internal/tcache.h
	deps/jemalloc/include/jemalloc/internal/tsd.h
	deps/jemalloc/include/jemalloc/internal/util.h
	deps/jemalloc/src/bitmap.c
	deps/jemalloc/src/ckh.c
	deps/jemalloc/src/quarantine.c
	deps/jemalloc/src/tsd.c
	deps/jemalloc/test/integration/aligned_alloc.c
	deps/jemalloc/test/unit/bitmap.c
	src/aof.c
	src/redis-cli.c
	src/redis.h
	src/util.c
2014-07-01 22:54:48 -07:00
Kirk Shoop (MS OPEN TECH) a4d22bfa8c updated license urls 2014-06-25 15:37:44 -07:00
Kirk Shoop (MS OPEN TECH) 8b9aa92123 added nuget release notes 2014-06-25 15:16:27 -07:00
Kirk Shoop (MS OPEN TECH) 084073fced Update package script and release notes 2014-06-25 12:09:56 -07:00
jonathan pickett 4600a06960 issue 136: --serviceName argument not recognized in config.c. 2014-06-24 17:39:47 -07:00
jonathan pickett b6e7f2d45e updated release notes for 2.8.9 nuget and chocolatey packages 2014-06-23 20:08:16 -07:00
jonathan pickett a14400a858 issue 134: command line parsing of [save ""] broken 2014-06-23 18:55:42 -07:00
jonathan pickett 411b6e9119 issue 129: correct name of file 2014-06-19 17:59:44 -07:00
jonathan pickett 56f504cb48 if "redis-server --service-install config.conf" and the .conf file had an include statement, then "redis-server --service-start" would fail because the current directory was set to %systemdir% on startup. Changed the current directory to the executable directory when --service-run is encountered 2014-06-16 16:17:37 -07:00
jonathan pickett e5de315940 fix for issue 130: recursive .conf file includes not working 2014-06-16 12:43:44 -07:00
jonathan pickett 721a9a2467 issue 125: sentinel command line argument not being recognized 2014-06-15 08:18:38 -07:00
jonathan pickett 0713fce727 issue 123: changed error output in Win32_service and Win32_QFork to use redisLog. Also fixed a few compiler warnings. 2014-06-11 19:22:19 -07:00
jonathan pickett c83b639b45 issue 119: error reported in sentinel.tcl testing. Error expected. Moved output to loglevel verbose. 2014-06-09 13:51:14 -07:00
jonathan pickett 0df1ab8c74 issue 121: restore redis-cli command history 2014-06-09 13:34:16 -07:00
jonathan pickett ca941f6c0b chose wrong option for binaries in last merge 2014-06-05 15:36:18 -07:00
jonathan pickett 15a236015f Merge branch '2.8' of https://github.com/MSOpenTech/Redis into 2.8
Conflicts:
	bin/release/redis-2.8.9.zip
2014-06-05 15:20:08 -07:00
jonathan pickett d0c274bbf3 Issue 120: sentinel reporting error writing to config file. open(O_RDONLY) followed by fsync() would result in access denied error in windows. In the context of the code changed, ifdefing out fsync on Windows was the safest thing to do. 2014-06-05 15:18:25 -07:00
jonathan pickett d623ca7e56 code review changes for commit 3ee3c4bdaf 2014-06-01 18:12:34 -07:00
jonathan pickett 228bf0350e resolving merge conflict from another local branch 2014-06-01 14:32:32 -07:00
jonathan pickett 803462c2c9 Merge branch '2.8' of https://github.com/MSOpenTech/Redis into 2.8 2014-06-01 14:31:33 -07:00
jonathan pickett 21fafdc620 issue 111: ANSI escape sequences not rendering on Windows terminal 2014-06-01 14:30:13 -07:00
jonathan pickett d4051d4c38 issue 105: 32-bit version not running on server 2003. Adjusted project settings and selected APIs in use via runtime version checks and windows version macro. 2014-05-29 22:33:19 -07:00
jonathan pickett 88606c1277 Merge branch '2.8' of https://github.com/MSOpenTech/redis into 2.8 2014-05-27 18:14:17 -07:00
jonathan pickett 4f0e17fb35 issue #93: cleaning up memory mapped files left over in cases where FILE_FLAG_DELETE_ON_CLOSE will not clean up file 2014-05-27 17:37:10 -07:00
jonathan pickett a4dd5cba88 issue #108: removing post build script from 32-bit release target. Script is 64-bit only. 2014-05-23 12:54:15 -07:00
jonathan pickett e97604ce63 issue #112: Adding permission for NETWORK_SERVICE on the folder redis-server.exe is in during --service-install. This allows for RDB files to be written and for .conf files to open in RW mode. Fixed a documentation typo. 2014-05-22 14:36:35 -07:00
jonathan pickett 1c3b70c971 Finishing merge of branch '2.8.4_msopen' of https://github.com/MSOpenTech/redis into 2.8.4_msopen
Conflicts:
	bin/release/redis-2.8.4.zip
	src/Win32_Interop/Win32_QFork.cpp
	src/sds.c
2014-05-16 12:49:22 -07:00
jonathan pickett 3ee3c4bdaf Merge branch 'antirez_2.8' into 2.8.4_msopen. Bumps version from 2.8.4 to 2.8.9
Conflicts:
	00-RELEASENOTES
	deps/linenoise/linenoise.c
	src/anet.c
	src/debug.c
	src/redis-cli.c
	src/redis.c
	src/sentinel.c
	src/t_zset.c
2014-05-15 19:18:26 -07:00
jonathan pickett f441b8d0f2 Issue 108: Added 32-bit support back in. QFork code requires a contiguous memory allocation for heap. Due to this requirement and 32-bit memory model limitations, maxheap is limited to about 512MB in 32-bit executable. 32-bit version appears to be about 30% slower than 64-bit version on 64-bit OS. 2014-05-15 18:24:59 -07:00
jonathan pickett ed1e8ac956 directory rename 2014-05-08 20:56:17 -07:00
jonathan pickett 991653211b directory rename 2014-05-08 20:55:08 -07:00
jonathan pickett 1fd9047397 issue 99: adding sample to demonstrate config of master + 3 slaves + 3 sentinels on one box. Discovered along the way that maxheap would not propagate through .conf include statements. It does now. 2014-05-08 20:07:39 -07:00
jonathan pickett 01eaf183b3 fix for issue #106: K32QueryWorkingSetEx not in kernel32.dll on Vista/Server 2008 2014-05-07 16:44:06 -07:00
jonathan pickett 176d1cd04b added comment for code changed in commit feb6c2884a 2014-05-07 16:41:49 -07:00
jonathan pickett feb6c2884a fix for issue #97: Added a modified sample to demonstrate large async GET operation. Also discovered that reply reading in async.c would stop if the reply data exceeded the buffer allocated for the read. redisAeAddRead() would not reschedule a read if already in read mode. To fix this is added redisAeForceAddRead(). 2014-05-01 15:19:18 -07:00
jonathan pickett 9f871c4ec5 Issue #95: Adding ability to specify custom service name/have multiple Redis service instances running.(Forgive the whitespace changes in Win32_Service.cpp. My editor was set to keep tabs when I wrote the code originally. Tabs are gone now.) 2014-04-30 14:34:01 -07:00
jonathan pickett de0a37aa76 Forgot to add custom build step for EventLog.mc to release target. Fixes issue 101. 2014-04-24 19:05:00 -07:00
jonathan pickett a2ef6a4fdc Added support for SIO_LOOPBACK_FAST_PATH (http://msdn.microsoft.com/en-us/library/windows/desktop/jj841212%28v=vs.85%29.aspx) . This speeds up localhost performance on Win8/Server2012+ significantly. In order to take advantage of this clients will have to enable socket fast loopback before connect(). 2014-04-23 11:53:13 -07:00
jonathan pickett cbd76db6a3 fixes for issue #94: service install will now self elevate 2014-04-18 18:55:19 -07:00
jonathan pickett e674609fcb adding working hiredis async example to solution based off of example-ae.c source. For issues 18 + 86 2014-04-16 17:16:27 -07:00
jonathan pickett ff367b50e5 fdapi not properly mapping fstat in config.c, so we ended up invoking CRT version without the rfd->fd translation resulting in the CRT calling exit(). Fixes issue 43. 2014-04-16 15:25:21 -07:00
jonathan pickett a7f2df706e Removing install project since we have NuGet and Chocolatey installs. Removing RedisWAInst since Azure fork will handle their own installation. 2014-04-15 19:01:55 -07:00
jonathan pickett 884dd54bbc since redis now has built-in service support, and Sentinel should be used for monitoring, this project is no longer needed 2014-04-15 18:05:51 -07:00
jonathan pickett 3cd77a5cb5 fox for issue 84. now recognizing "stdout" as as stdout. Also added docs to binary zip generation script and modified redis.windows.conf to remove references to unsupported daemonize flag 2014-04-15 16:21:39 -07:00
jonathan pickett bcfdbf7bcc fox for issue #90. info.rdb_changes_since_last_save not being properly updated. Also dealt with the exit code from a failed fork not making it back to the parent. 2014-04-15 14:21:25 -07:00
jonathan pickett 765cdbe670 fix for issue #39 2014-04-14 19:10:33 -07:00
jonathan pickett 631e8e1afb Bringing forward a fix from 2.6.14 (commit 99e01c7e6b). Replaces the fork/execv construction with CreateProcess. 2014-04-11 20:03:15 -07:00
jonathan pickett 959c9d3469 Added preshutdown notification support to service to deal with Issue 87. Also improved message filter support for eventlog. 2014-04-11 19:31:05 -07:00
jonathan pickett 2d29a8f207 Added support for redirecting Redis logging to the Windows Application log. Repurposed --syslog flags for this. See redis.windows.conf for information about the repurposed flags. When redis is running as a service it will use the Windows EventLog by default. 2014-04-08 18:16:09 -07:00
jonathan pickett 34250336c1 Release build still had link dependency on DLL versions of CRT. Also updated release documentation 2014-04-07 19:00:35 -07:00
jonathan pickett 9651d90354 sprintf argument change to fix a compiler warning caused forked process to fail to map control structure unexpectedly. Fixing in a different manner. 2014-04-07 18:37:25 -07:00
jonathan pickett 6eb1ec2217 added Windows Service support to Redis 2014-04-03 16:39:02 -07:00
jonathan pickett e2a48cd715 PS scripts to automate NuGet/Chocolatey package generation. Also eliminated VC redist dependency in Chocolatey spec 2014-04-02 16:48:17 -07:00
jonathan pickett 0df3c6b4b4 Updated the README.md for the current build. Removed APIBridge.dll from the powershell script that builds the zip file containing the binaries. Updated the zip file. 2014-04-01 17:11:17 -07:00
jonathan pickett 8b9a8a0a41 In linenoise.c in linenoiseRaw() isatty() is called on stdin in order to determine where to send the redis-cli prompt. The FDAPI implementation of isatty was not handling this case, so the prompt was not showing up. 2014-04-01 16:04:14 -07:00
jonathan pickett c3c91f5ab0 Moved projects to VS2013. Removed dependency on CRT runtime DLLs. Removed APIBridge.DLL. Added MSOpenTech copyright notices. 2014-03-31 17:01:21 -07:00
jonathan pickett f5b410a52e package description update 2014-03-21 20:41:15 -07:00
jonathan pickett 4c0e75ed8b updating binaries for last change 2014-03-21 18:55:19 -07:00
jonathan pickett 8d0309eebf Bringing over fix from azure fork that fixes partial synchronization (https://github.com/WindowsAzure/redis/commit/f5be20b0201d9c492506e20254d38053223201c5 ). I added '#ifdef win32' blocks around the changes so we could rebase this forward. 2014-03-21 18:45:33 -07:00
jonathan pickett 16ca1634ae adding nuget and chocolatey packaging specifications 2014-03-20 17:23:38 -07:00
jonathan pickett decf224e85 With sufficiently large allocations dlcalloc was not clearing allocated memory because of a compilation flag. This was causing a unit test to fail. 2014-03-14 15:46:49 -07:00
jonathan pickett 53f0c8f6e2 using memtoull instead of _atoi64 while parsing maxmemory and maxheap flags. 'redis-server --maxmem 500m --maxheap 2g' works 2014-03-10 16:19:49 -07:00
jonathan pickett 0080e0fc70 Added --maxheap flag to control size of memory mapped file created. Heap can now exceed size of physical memory. See long comment in Win32_qfork.cpp about implications of using --maxheap flag. 2014-03-07 19:51:02 -08:00
jonathan pickett 411ef3f609 Cleaned up duplicate WIN32_IOCP flag in projects. Also added compressOutputToReleaseFolder.ps1 script to release build of Redis. 2014-02-25 18:03:23 -08:00
jonathan pickett 30a26d36ab added --bypass-system-reserve flag for Azure team to test maximum heap allocation 2014-02-25 18:01:26 -08:00
jonathan pickett f5245a44e4 sdshdr definition in deps/hiredis/sds.h must match the definition in src/sds.h. Specifically, sizeof (C struct with a char* member) calculates the char* as a pointer. sizeof(C-struct with char[] member) calculates char[] as empty character array. BTW, the parent struct from member pointer dereference is an abomination. 2014-02-24 15:59:52 -08:00
jonathan pickett 208eb29003 Fixed 1-off bug allocating last block of MMF. Added additional heap allocation with maxmemory flag to allow for fragmentation. 2014-02-19 18:10:05 -08:00
jonathan pickett bdd9804c42 modified binaries after maxmemory change 2014-02-17 18:21:13 -08:00
jonathan pickett 92258f87ba Removing maxheapgb flag in favor of utilizing existing maxmemory flag. Now honoring maxmemory flag in .conf files. Slightly modified default MMF startup requirements to [phys - min(0.2*phys, 3GB)] 2014-02-17 18:11:17 -08:00
jonathan pickett 8d9e238a20 /tmp is not guaranteed to be available on Windows. Substituting directory in TEMP environment variable. Unit test still fails for other reasons. 2014-02-14 10:56:20 -08:00
jonathan pickett a695b4e4a4 updating binaries 2014-02-14 10:53:13 -08:00
jonathan pickett 8c87102147 Not updating slave acknowledgement time when IOCP operation completes. breaks integration/replication-4 unit test. 2014-02-11 18:51:21 -08:00
jonathan pickett 4e45ebf5a1 unit tests not working in 2.6.14 on windows still not working in 2.8.4 2014-02-11 18:49:40 -08:00
jonathan pickett e4ac644fc1 Changing heap size calculation to be 80% of physical ram. This allow the server to start on Azure S and XS machines. 2014-02-11 15:01:23 -08:00
Jonathan Pickett 4bbb8e6bce fixed rebase error that caused redis to panic with BLPOP 2014-02-05 17:28:05 -08:00
Jonathan Pickett 2959371b3f adding --maxheapgb flag to startup to control size of memory mapped file created 2014-02-05 11:05:54 -08:00
Jonathan Pickett 2277ed0ea8 Merge branch '2_6_14_rebase' into 2.8.4 2014-02-03 17:10:36 -08:00
Jonathan Pickett 62cc0e320d Merge branch '2_6_14_rebase' into 2.8.4
Conflicts:
	00-RELEASENOTES
	deps/hiredis/hiredis.c
	deps/hiredis/sds.c
	deps/jemalloc/ChangeLog
	deps/jemalloc/Makefile.in
	deps/jemalloc/VERSION
	deps/jemalloc/configure
	deps/jemalloc/configure.ac
	deps/jemalloc/doc/jemalloc.3
	deps/jemalloc/doc/jemalloc.html
	deps/jemalloc/doc/jemalloc.xml.in
	deps/jemalloc/include/jemalloc/internal/arena.h
	deps/jemalloc/include/jemalloc/internal/chunk.h
	deps/jemalloc/include/jemalloc/internal/chunk_dss.h
	deps/jemalloc/include/jemalloc/internal/chunk_mmap.h
	deps/jemalloc/include/jemalloc/internal/ctl.h
	deps/jemalloc/include/jemalloc/internal/extent.h
	deps/jemalloc/include/jemalloc/internal/huge.h
	deps/jemalloc/include/jemalloc/internal/jemalloc_internal.h.in
	deps/jemalloc/include/jemalloc/internal/private_namespace.h
	deps/jemalloc/include/jemalloc/internal/prof.h
	deps/jemalloc/include/jemalloc/internal/rtree.h
	deps/jemalloc/include/jemalloc/jemalloc.h.in
	deps/jemalloc/include/jemalloc/jemalloc_defs.h.in
	deps/jemalloc/src/arena.c
	deps/jemalloc/src/base.c
	deps/jemalloc/src/chunk.c
	deps/jemalloc/src/chunk_dss.c
	deps/jemalloc/src/chunk_mmap.c
	deps/jemalloc/src/ctl.c
	deps/jemalloc/src/huge.c
	deps/jemalloc/src/jemalloc.c
	deps/jemalloc/src/mutex.c
	deps/jemalloc/src/prof.c
	deps/jemalloc/src/rtree.c
	deps/jemalloc/src/stats.c
	deps/jemalloc/src/tcache.c
	deps/jemalloc/src/util.c
	deps/jemalloc/src/zone.c
	deps/jemalloc/test/thread_arena.c
	deps/linenoise/linenoise.c
	redis.conf
	src/Makefile.dep
	src/ae.c
	src/anet.c
	src/anet.h
	src/aof.c
	src/bitops.c
	src/config.c
	src/config.h
	src/db.c
	src/debug.c
	src/dict.c
	src/memtest.c
	src/mkreleasehdr.sh
	src/networking.c
	src/object.c
	src/rdb.c
	src/redis-benchmark.c
	src/redis-cli.c
	src/redis.c
	src/redis.h
	src/release.c
	src/replication.c
	src/rio.c
	src/rio.h
	src/scripting.c
	src/sds.c
	src/sentinel.c
	src/t_list.c
	src/t_string.c
	src/t_zset.c
	src/version.h
	src/zmalloc.c
	tests/assets/default.conf
	tests/integration/rdb.tcl
	tests/test_helper.tcl
	tests/unit/basic.tcl
	tests/unit/expire.tcl
	tests/unit/obuf-limits.tcl
	tests/unit/pubsub.tcl
	tests/unit/scripting.tcl

Still having problems with BLPOP
2014-02-03 17:06:54 -08:00
Jonathan Pickett 4440406bb5 Using project reference rather than linker library input. This fixes the annoying 'do you want to rebuild the universe just because you pressed F5' problem. Built is now built. 2014-01-28 18:08:38 -08:00
Jonathan Pickett 8812fe61bd added lua and hiredis libs as project references 2014-01-28 11:58:14 -08:00
Jonathan Pickett 66b7f8a044 working through issues regarding sentinal not working 2014-01-28 11:49:20 -08:00
Jonathan Pickett e1f312e547 redis log not working with anything ofther than stdout 2014-01-27 21:12:31 -08:00
Jonathan Pickett e35841ce76 --loglevel command line argument was not working 2014-01-27 19:26:47 -08:00
Jonathan Pickett 6daa29da46 added failure error messages back in to QFork MasterInit 2014-01-22 17:03:44 -08:00
Jonathan Pickett ce6c1f08b0 continuing code cleanup by moving win32 specific code into Win32_Interop directory 2014-01-17 18:24:31 -08:00
Jonathan Pickett f00034a438 fixed _MSC_VER version check 2014-01-17 14:41:53 -08:00
Jonathan Pickett 60a82ae058 Header file changes for compiling under vs2013. Solution files will remain at VS2012 for awhile. To build under VS2013 all that is required is to converting the solution files. 2014-01-17 12:40:51 -08:00
Jonathan Pickett 8b3daf2bb8 compile/link cleanup 2014-01-16 14:13:51 -08:00
Jonathan Pickett 93581da537 race condition for resetting completed event causing hard to reproduce AOF load errors 2014-01-16 14:12:36 -08:00
Jonathan Pickett d30d0c6a31 moving win32 specific code into a static lib so that it compiles only once, also some minor code tidying 2014-01-15 16:32:38 -08:00
Jonathan Pickett 0d7366c329 workaround for deadlocking on RDB file copy during multiple master/slave synchronizations 2014-01-09 19:42:44 -08:00
Jonathan Pickett 8a47dc3ca5 more useful error message 2014-01-08 18:08:38 -08:00
Jonathan Pickett e12c4cdf15 Sync socket write would return WSAEWOULDBLOCK when send buffer full. Detecting this and adding a small delay then retrying so that migrate tests can finish. 2014-01-08 17:07:58 -08:00
Jonathan Pickett c32ccaa868 added early break to test if protocol error detected. went back to provious windows version of test. 2014-01-08 15:39:47 -08:00
Jonathan Pickett 4d88ec9886 improving error reporting when fork fails for testing 2014-01-07 18:04:03 -08:00
Jonathan Pickett 663850ea73 Added dictionary master hash to global state being copied into qforked process. This fixes the fork/expire problems. 2014-01-07 17:04:52 -08:00
Jonathan Pickett f5a1b485c3 getting unit tests back to antirez verbatim 2014-01-06 17:31:47 -08:00
Jonathan Pickett 78b051a8be cleaning up unit tests. leaving in win32 checks around failing tests in aof, bgsave and scripting. 2014-01-03 19:45:45 -08:00
Jonathan Pickett 1849e30c7a adding delay to test because debug loadaof is taking too long for test to pass 2014-01-03 18:43:18 -08:00
Jonathan Pickett bddf4ac4da with recent changes these tests are working on windows 2014-01-03 18:22:49 -08:00
Jonathan Pickett 5decabc2c7 failing to erase from socket/fd backmaps caused confusion in multi.tcl 2014-01-03 18:00:59 -08:00
Jonathan Pickett c53e73573c FILE*->fd not handled well in ftruncate. Fix allows broken tests in aof.tcl to work. 2014-01-03 17:20:11 -08:00
Jonathan Pickett 449d6623ab a fix to get the integration tests working again, and added warnings about tests bypassed for Win32 2014-01-03 15:58:28 -08:00
Jonathan Pickett bf22d5646d replacing win32_cow implementation with win32_qfork. replication currently broken, but all other unit tests are working. 2014-01-02 12:06:06 -08:00
Jonathan Pickett 5e2bb3e678 Removed x86 and non-IOCP targets in preparation for new qfork implementation. Only supported build henceforth will be x64 with IOCP. 2013-12-23 19:29:38 -08:00
Jonathan Pickett 7da645073b removing if{} block used for testing 2013-11-26 17:43:29 -08:00
Jonathan Pickett 926e5283c6 Isolating the socket differences beween Linux and Windows in Win32_FDAPI and APIBridge code. 2013-11-26 17:19:22 -08:00
Jonathan Pickett 14e809d0f7 adjusting unit test timing and forcing double evaluation rather than string evaluation 2013-11-12 18:36:17 -08:00
Jonathan Pickett e0f78cd084 eliminating COW dependent tests to verify that IOCP is not responsible for crashes and other strange behavior being seen 2013-11-11 16:17:23 -08:00
Jonathan Pickett 59cdeb4e89 Disabling the COW replacement for fork() temporarily. This appears to fix crashing issues with redis. Also commenting out related unit tests. Replication is broken until COW (or a better fork replacement) is put back in. 2013-11-06 11:46:27 -08:00
Jonathan Pickett 6710555bc8 moved logging for hiredis and rediccli usage 2013-10-31 18:16:24 -07:00
Jonathan Pickett 3032831099 2nd unit test needs to be investigated because it is frequently hanging unit test pass 2013-10-30 19:15:50 -07:00
Jonathan Pickett e2162fc107 "r client list" returning information on 3 connections. Fixed loop logic to check for omem in all connections. 2013-10-29 19:21:02 -07:00
Jonathan Pickett 07f2edf5e3 upping timeout for AOF rewrite on windows 2013-10-28 17:07:39 -07:00
Jonathan Pickett 37e9d78774 for non-IOCP build: fixes breakage in integration/replicationxx, unit/dump, and unit/instrospection unit tests 2013-10-25 16:02:00 -07:00
Jonathan Pickett 8dc2d3096d Fixing non-IOCP networking issues. Remapping WSAEWOULDBLOCK==>EAGAIN, and non-blocking send() can return 0 without having client disconnect. 2013-10-23 19:11:47 -07:00
Jonathan Pickett 5fbc129b4e Work in progress. Temporary move towards separate IOCP/non-IOCP builds because of thread state issues. Neither build set is particularily stable at the moment. 2013-10-18 13:34:16 -07:00
Jonathan Pickett e1f6d21cdf stability fixes 2013-10-09 15:12:57 -07:00
Jonathan Pickett 7071e9d599 Fix for issue #59. Generated FDs are used everywhere until a SOCKET handle is used by the Winsock APIs. The win32_socketmap code generates the simulated FDs and handles the mapping from these to socket handles. 2013-10-03 16:12:54 -07:00
Jonathan Pickett de48871570 converting main solution to vs2012 2013-09-20 14:16:30 -07:00
Jonathan Pickett 3561ada2db upgraded tool chain to vs2012 2013-09-20 13:05:30 -07:00
Henry Rawas 3339a22399 Install MSI for Redis 2013-07-21 12:45:59 -07:00
Henry Rawas aa392e3fb7 Issue #51. Path to zip files changed 2013-07-21 12:45:58 -07:00
Henry Rawas 2d92308f38 Issue #43 - Fix async connect and write for sentinel. 2013-07-21 12:45:58 -07:00
Henry Rawas eff7cdfad0 Issue #46 - file length calculation overflow. Switch to 64bit values. 2013-07-21 12:45:35 -07:00
Henry Rawas b4554da5fd #41 aeWinReceiveDone not initialized 2013-07-21 12:45:16 -07:00
Henry Rawas aedf3bfcd1 #43 Redis-sentinel async communication fixes for windows 2013-07-21 12:45:16 -07:00
Henry Rawas fe7c28cc50 remove app.config from proj 2013-07-21 12:44:24 -07:00
Henry Rawas e4b13e5eb0 more small typos 2013-07-21 12:44:24 -07:00
Henry Rawas 17dd06cc97 Fixed typo in executable name 2013-07-21 12:44:23 -07:00
Henry Rawas 0929eec2f7 Fix some bad hyphen and quote chras in readme 2013-07-21 12:44:22 -07:00
Henry Rawas 1e6147fada Add missing exe files, quote for subscription, x64 switch, name conflict
Conflicts:

	.gitignore
2013-07-21 12:44:22 -07:00
Henry Rawas 5180055384 Fix Azure Installer README formatting 2013-07-21 12:44:21 -07:00
Henry Rawas b1f0b92f2d adding Windows Azure Installer 2013-07-21 12:44:20 -07:00
Henry Rawas c84e5ba84d update readme, disable permission test 2013-07-21 12:42:45 -07:00
Henry Rawas 3a5ee522b5 move release bin directory 2013-07-21 12:42:44 -07:00
Henry Rawas 8f77c71751 Avoid using closed handle and double free memory after replication failure 2013-07-21 12:42:40 -07:00
Henry Rawas 22c2b323da Issue #33 inconsistency for float rounding 2013-07-21 12:42:36 -07:00
Henry Rawas 96418fd48e Issue #32 - showing 32/64 bit in logo and version 2013-07-21 12:42:32 -07:00
Henry Rawas 1f42527c58 Modify and enable protocol desync test for windows 2013-07-21 12:42:29 -07:00
Henry Rawas 89cae3d62e Improve non blocking opening and closing of sockets 2013-07-21 12:42:09 -07:00
Henry Rawas cb85f493cb 2.6 windows binaries (not signed) 2013-07-21 12:41:14 -07:00
Henry Rawas 896c1e659f Redis 2.6 for Windows 2013-07-21 12:39:55 -07:00
Henry Rawas 19c476f4ce Updated Readme for 2.6.8 2013-07-21 12:26:08 -07:00
Henry Rawas 239f5233d5 move release bin directory 2013-07-21 12:26:07 -07:00
Henry Rawas 097dd94bb4 add license 2013-07-21 12:26:05 -07:00
Henry Rawas 07b031839a Avoid using closed handle and double free memory after replication failure 2013-07-21 12:26:05 -07:00
Henry Rawas c179bcfd66 Issue #33 inconsistency for float rounding 2013-07-21 12:26:02 -07:00
Henry Rawas a6a8aebec9 Issue #32 - showing 32/64 bit in logo and version 2013-07-21 12:25:58 -07:00
Henry Rawas 81eed0db38 Modify and enable protocol desync test for windows 2013-07-21 12:25:55 -07:00
Henry Rawas e955536015 Improve non blocking opening and closing of sockets 2013-07-21 12:25:55 -07:00
Henry Rawas 47bbccf9be 2.6 windows binaries (not signed) 2013-07-21 11:55:26 -07:00
Henry Rawas 11d870bd55 Redis 2.6 for Windows 2013-07-21 11:54:30 -07:00
antirez f2f2b4eb9d Redis 2.6.14 2013-06-20 10:36:40 +02:00
antirez 252f0b6556 Sentinel: parse new INFO replication output correctly.
Sentinel was not able to detect slaves when connected to a very recent
version of Redis master since a previos non-backward compatible change
to INFO broken the parsing of the slaves ip:port INFO output.

This fixes issue #1164
2013-06-20 10:24:43 +02:00
antirez ee92c043fc Test: regression test for #1163. 2013-06-19 18:53:17 +02:00
antirez 8e63fd0734 Allow writes from scripts called by AOF loading in read-only slaves.
This fixes issue #1163
2013-06-19 18:29:10 +02:00
antirez a73da27853 Binary safe dump of object content in redisLogObjectDebugInfo(). 2013-06-04 15:56:26 +02:00
antirez feffd5635b redis-cli: help.h updated. 2013-05-14 11:22:50 +02:00
antirez 2c93d34bde Test: various issues with the replication-4.tcl test fixed.
The test actually worked, but vars for master and slave were inverted
and sometimes used incorrectly.
2013-05-08 11:59:47 +02:00
Jiahao Huang 6251c3e66e in 32bit machine, popcount don't work with a input string length up to 512 MB,
bitcount commant may return negtive integer with string length more than 256 MB
2013-05-08 09:59:35 +02:00
antirez 71b442276f Added more info about 32 bit builds into README. 2013-05-08 09:48:49 +02:00
antirez 6a947b1d54 CONFIG SET server.masterauth aesthetic change.
This is just to make the code exactly like the above instance used for
requirepass. No actual change nor the original code violated the Redis
coding style.
2013-05-02 17:22:42 +02:00
Michel Martens 736220b86f Reset masterauth if an empty string is configured. 2013-05-02 17:22:38 +02:00
charsyam b37512a28f Fix AOF bug: expire could be removed from key on AOF rewrite.
There was a race condition in the AOF rewrite code that, with bad enough
timing, could cause a volatile key just about to expire to be turned
into a non-volatile key. The bug was never reported to cause actualy
issues, but was found analytically by an user in the Redis mailing list:

https://groups.google.com/forum/?fromgroups=#!topic/redis-db/Kvh2FAGK4Uk

This commit fixes issue #1079.
2013-05-02 15:46:59 +02:00
antirez d96497961c Redis 2.6.13 2013-04-30 15:15:56 +02:00
antirez 4f38d03254 Sentinel: changes to tilt mode.
Tilt mode was too aggressive (not processing INFO output), this
resulted in a few problems:

1) Redirections were not followed when in tilt mode. This opened a
   window to misinform clients about the current master when a Sentinel
   was in tilt mode and a fail over happened during the time it was not
   able to update the state.

2) It was possible for a Sentinel exiting tilt mode to detect a false
   fail over start, if a slave rebooted with a wrong configuration
   about at the same time. This used to happen since in tilt mode we
   lose the information that the runid changed (reboot).

   Now instead the Sentinel in tilt mode will still remove the instance
   from the list of slaves if it changes state AND runid at the same
   time.

Both are edge conditions but the changes should overall improve the
reliability of Sentinel.
2013-04-30 15:09:34 +02:00
antirez 59ff2fe9a4 Sentinel: more sensible delay in master demote after tilt. 2013-04-30 15:09:31 +02:00
antirez fb0d08e35f Sentinel: only demote old master into slave under certain conditions.
We used to always turn a master into a slave if the DEMOTE flag was set,
as this was a resurrecting master instance.

However the following race condition is possible for a Sentinel that
got partitioned or internal issues (tilt mode), and was not able to
refresh the state in the meantime:

1) Sentinel X is running, master is instance "A".
3) "A" fails, sentinels will promote slave "B" as master.
2) Sentinel X goes down because of a network partition.
4) "A" returns available, Sentinels will demote it as a slave.
5) "B" fails, other Sentinels will promote slave "A" as master.
6) At this point Sentinel X comes back.

When "X" comes back he thinks that:

"B" is the master.
"A" is the slave to demote.

We want to avoid that Sentinel "X" will demote "A" into a slave.
We also want that Sentinel "X" will detect that the conditions changed
and will reconfigure itself to monitor the right master.

There are two main ways for the Sentinel to reconfigure itself after
this event:

1) If "B" is reachable and already configured as a slave by other
sentinels, "X" will perform a redirection to "A".
2) If there are not the conditions to demote "A", the fact that "A"
reports to be a master will trigger a failover detection in "X", that
will end into a reconfiguraiton to monitor "A".

However if the Sentinel was not reachable, its state may not be updated,
so in case it titled, or was partiitoned from the master instance of the
slave to demote, the new implementation waits some time (enough to
guarantee we can detect the new INFO, and new DOWN conditions).

If after some time still there are not the right condiitons to demote
the instance, the DEMOTE flag is cleared.
2013-04-30 15:09:27 +02:00
antirez 395e6a5872 Lua updated to version 5.1.5. 2013-04-29 12:02:04 +02:00
antirez 34a57a5b52 Sentinel: always redirect on master->slave transition.
Sentinel redirected to the master if the instance changed runid or it
was the first time we got INFO, and a role change was detected from
master to slave.

While this is a good idea in case of slave->master, since otherwise we
could detect a failover without good reasons just after a reboot with a
slave with a wrong configuration, in the case of master->slave
transition is much better to always perform the redirection for the
following reasons:

1) A Sentinel may go down for some time. When it is back online there is
no other way to understand there was a failover.
2) Pointing clients to a slave seems to be always the wrong thing to do.
3) There is no good rationale about handling things differently once an
instance is rebooted (runid change) in that case.
2013-04-24 11:34:05 +02:00
antirez 967ae8ca67 Config option to turn AOF rewrite incremental fsync on/off. 2013-04-24 10:57:38 +02:00
antirez c735116c87 AOF: sync data on disk every 32MB when rewriting.
This prevents the kernel from putting too much stuff in the output
buffers, doing too heavy I/O all at once. So the goal of this commit is
to split the disk pressure due to the AOF rewrite process into smaller
spikes.

Please see issue #1019 for more information.
2013-04-24 10:28:43 +02:00
antirez 8b41e19e47 rio.c: added ability to fdatasync() from time to time while writing. 2013-04-24 10:27:55 +02:00
antirez cf7b2c329b Test: fix RDB test checking file permissions.
When the test is executed using the root account, setting the permission
to 222 does not work as expected, as root can read files with 222
permission.

Now we skip the test if root is detected.

This fixes issue #1034 and the duplicated #1040 issue.

Thanks to Jan-Erik Rediger (@badboy on Github) for finding a way to reproduce the issue.
2013-04-23 14:16:58 +02:00
antirez bac29c8b7c Sentinel: turn old master into a slave when it comes back. 2013-04-22 11:26:33 +02:00
antirez 4848af1b9e Test: split conceptually unrelated comments in RDB test. 2013-04-22 11:25:59 +02:00
antirez 172eac504a More explicit panic message on out of memory. 2013-04-19 15:11:59 +02:00
antirez 5bf9b53a83 Redis/Jemalloc Gitignore were too aggressive.
Redis gitignore was too aggressive since simply broken.

Jemalloc gitignore was too agressive because it is conceived to just
keep the files that allow to generate all the rest in development
environments (so for instance the "configure" file is excluded).
2013-04-18 16:21:32 +02:00
antirez 40861516ac redis-cli: raise error on bad command line switch.
Previously redis-cli never tried to raise an error when an unrecognized
switch was encountered, as everything after the initial options is to be
transmitted to the server.

However this is too liberal, as there are no commands starting with "-".
So the new behavior is to produce an error if there is an unrecognized
switch starting with "-". This should not break past redis-cli usages
but should prevent broken options to be silently discarded.

As far the first token not starting with "-" is encountered, all the
rest is considered to be part of the command, so you cna still use
strings starting with "-" as values, like in:

    redis-cli --port 6380 set foo --my-value
2013-04-11 13:19:39 +02:00
antirez 92a7b0102c redis-cli: --latency-history mode implemented. 2013-04-11 13:19:33 +02:00
antirez 9f2e6ac0ed Test: remove useless statements and comments from test default config. 2013-04-04 14:32:17 +02:00
antirez 63978d338d Make rio.c comment 80-columns friendly. 2013-04-03 12:41:31 +02:00
antirez ed2d988192 Throttle BGSAVE attempt on saving error.
When a BGSAVE fails, Redis used to flood itself trying to BGSAVE at
every next cron call, that is either 10 or 100 times per second
depending on configuration and server version.

This commit does not allow a new automatic BGSAVE attempt to be
performed before a few seconds delay (currently 5).

This avoids both the auto-flood problem and filling the disk with
logs at a serious rate.

The five seconds limit, considering a log entry of 200 bytes, will use
less than 4 MB of disk space per day that is reasonable, the sysadmin
should notice before of catastrofic events especially since by default
Redis will stop serving write queries after the first failed BGSAVE.

This fixes issue #849
2013-04-02 14:13:03 +02:00
antirez 7da5980848 Redis 2.6.12 2013-03-29 17:42:39 +01:00
charsyam 062f60a36e Support for case unsensitive SET options. 2013-03-29 10:37:33 +01:00
antirez 4243483d3e Test: Extended SET tests. 2013-03-28 16:45:45 +01:00
antirez d785413d86 Extended SET command implemented (issue #931). 2013-03-28 16:45:37 +01:00
antirez e8a1a169dd EXPIRE should not resurrect keys. Issue #1026. 2013-03-28 12:49:03 +01:00
antirez dc0f13774b Test: regression test for issue #1026. 2013-03-28 12:48:59 +01:00
antirez 47911b8630 Better DEBUG error message when num of arguments is wrong. 2013-03-28 12:48:55 +01:00
antirez 7ff729e192 Test: verify that lazy-expire works. 2013-03-28 12:48:51 +01:00
antirez 02b9a72bae DEBUG set-active-expire added.
We need the ability to disable the activeExpireCycle() (active
expired key collection) call for testing purposes.
2013-03-28 12:48:47 +01:00
antirez 1862239136 Test: read_from_replication_stream, workaround for 2.6 2013-03-27 12:03:46 +01:00
antirez f8791a158b Test: test replication of MULTI/EXEC. 2013-03-27 11:57:32 +01:00
antirez 26319d08b5 Test: Restore DB back to 9 after testing MULTI/EXEC with DB 5. 2013-03-27 11:57:28 +01:00
antirez fc78d978de Test: new functions to capture and analyze the replication stream. 2013-03-27 11:57:23 +01:00
antirez 6cb7860658 Flag PUBLISH as read-only in the command table. 2013-03-27 09:07:43 +01:00
antirez 611dcb56ee Transactions: propagate MULTI/EXEC only when needed.
MULTI/EXEC is now propagated to the AOF / Slaves only once we encounter
the first command that is not a read-only one inside the transaction.

The old behavior was to always propagate an empty MULTI/EXEC block when
the transaction was composed just of read only commands, or even
completely empty. This created two problems:

1) It's a bandwidth waste in the replication link and a space waste
   inside the AOF file.

2) We used to always increment server.dirty to force the propagation of
   the EXEC command, resulting into triggering RDB saves more often
   than needed.

Note: even read-only commands may also trigger writes that will be
propagated, when we access a key that is found expired and Redis will
synthesize a DEL operation. However there is no need for this to stay
inside the transaction itself, but only to be ordered.

So for instance something like:

    MULTI
    GET foo
    SET key zap
    EXEC

May be propagated into:

    DEL foo
    MULTI
    SET key zap
    EXEC

While the DEL is outside the transaction, the commands are delivered in
the right order and it is not possible for other commands to be inserted
between DEL and MULTI.
2013-03-27 09:07:23 +01:00
antirez 889b017403 Transactions: use discardTransaction() in EXEC implementation. 2013-03-27 09:07:18 +01:00
antirez d1369c3d9f Transactions: use the propagate() API to propagate MULTI.
The behavior is the same, but the code is now cleaner and uses the
proper interface instead of dealing directly with AOF/replication
functions.
2013-03-27 09:06:59 +01:00
antirez 6818905406 Allow SELECT while loading the DB.
Fixes issue #1024.
2013-03-26 13:59:00 +01:00
NanXiao ef1cf15c14 Update config.c
Fix bug in configGetCommand function: get correct masterauth value.
2013-03-25 19:32:24 +01:00
antirez dee8d84270 Test: obuf-limits test false positive removed.
Fixes #621.
2013-03-25 11:56:08 +01:00
antirez 5576a28977 redis-cli --stat, stolen from redis-tools.
Redis-tools is a connection of tools no longer mantained that was
intented as a way to economically make sense of Redis in the pre-vmware
sponsorship era. However there was a nice redis-stat utility, this
commit imports one of the functionalities of this tool here in redis-cli
as it seems to be pretty useful.

Usage: redis-cli --stat

The output is similar to vmstat in the format, but with Redis specific
stuff of course.

From the point of view of the monitored instance, only INFO is used in
order to grab data.
2013-03-25 11:52:32 +01:00
antirez 4f8b18f3dd Replication: master_link_down_since_seconds initial value should be huge.
server.repl_down_since used to be initialized to the current time at
startup. This is wrong since the replication never started. Clients
testing this filed to check if data is uptodate should never believe
data is recent if we never ever connected to our master.
2013-03-13 12:55:06 +01:00
antirez c64255990e Test: make sure broken RDB checksum is detected. 2013-03-13 11:15:33 +01:00
antirez ba3c5494d8 Test: more RDB loading checks.
A test for issue #1001 is included.
2013-03-13 10:09:21 +01:00
antirez 684b61505a Test: check that Redis starts empty without an RDB file. 2013-03-13 10:09:16 +01:00
antirez 189e865c51 rdbLoad(): rework code to save vertical space. 2013-03-13 10:09:09 +01:00
Damian Janowski b9f8c2a5b0 Abort when opening the RDB file results in an error other than ENOENT.
This fixes cases where the RDB file does exist but can't be accessed for
any reason. For instance, when the Redis process doesn't have enough
permissions on the file.
2013-03-13 10:08:47 +01:00
antirez 18d16f8592 Set default for stop_writes_on_bgsave_err in initServerConfig().
It was placed for error in initServer() that's called after the
configuation is already loaded, causing issue #1000.
2013-03-12 18:36:07 +01:00
antirez 3a00520e5f Add a missing bugfix entry in 2.6.11 release notes. 2013-03-12 17:55:23 +01:00
antirez f93d9929d8 redis-cli --bigkeys: don't crash with empty DBs. 2013-03-12 09:57:49 +01:00
antirez 6589821035 Redis 2.6.11 2013-03-11 19:51:10 +01:00
antirez 48f4f77189 activeExpireCycle() smarter with many DBs and under expire pressure.
activeExpireCycle() tries to test just a few DBs per iteration so that
it scales if there are many configured DBs in the Redis instance.
However this commit makes it a bit smarter when one a few of those DBs
are under expiration pressure and there are many many keys to expire.

What we do is to remember if in the last iteration had to return because
we ran out of time. In that case the next iteration we'll test all the
configured DBs so that we are sure we'll test again the DB under
pressure.

Before of this commit after some mass-expire in a given DB the function
tested just a few of the next DBs, possibly empty, a few per iteration,
so it took a long time for the function to reach again the DB under
pressure. This resulted in a lot of memory being used by already expired
keys and never accessed by clients.
2013-03-11 11:34:49 +01:00
antirez b3281e93c3 In databasesCron() never test more DBs than we have. 2013-03-11 11:34:45 +01:00
antirez 2677c97d39 Make comment name match var name in activeExpireCycle(). 2013-03-11 11:34:34 +01:00
antirez 1d426bf53b Optimize inner loop of activeExpireCycle() for no-expires case. 2013-03-11 11:34:18 +01:00
antirez da2dd8991b REDIS_DBCRON_DBS_PER_SEC -> REDIS_DBCRON_DBS_PER_CALL 2013-03-11 11:34:14 +01:00
antirez 13f84841b5 activeExpireCycle(): process only a small number of DBs per iteration.
This small number of DBs is set to 16 so actually in the default
configuraiton Redis should behave exactly like in the past.
However the difference is that when the user configures a very large
number of DBs we don't do an O(N) operation, consuming a non trivial
amount of CPU per serverCron() iteration.
2013-03-11 11:34:10 +01:00
antirez ef3a95fa6f Use unsigned integers for DB ids, for defined wrap-to-zero. 2013-03-11 11:34:05 +01:00
antirez 665b819eb4 Only resize/rehash a few databases per cron iteration.
This is the first step to lower the CPU usage when many databases are
configured. The other is to also process a limited number of DBs per
call in the active expire cycle.
2013-03-11 11:33:59 +01:00
antirez bb562a6414 Actually call databasesCron() inside serverCron(). 2013-03-11 11:30:26 +01:00
antirez e166abad10 Move Redis databases background processing to databasesCron(). 2013-03-11 11:30:21 +01:00
antirez aec5ea5d07 serverCron() frequency is now a runtime parameter (was REDIS_HZ).
REDIS_HZ is the frequency our serverCron() function is called with.
A more frequent call to this function results into less latency when the
server is trying to handle very expansive background operations like
mass expires of a lot of keys at the same time.

Redis 2.4 used to have an HZ of 10. This was good enough with almost
every setup, but the incremental key expiration algorithm was working a
bit better under *extreme* pressure when HZ was set to 100 for Redis
2.6.

However for most users a latency spike of 30 milliseconds when million
of keys are expiring at the same time is acceptable, on the other hand a
default HZ of 100 in Redis 2.6 was causing idle instances to use some
CPU time compared to Redis 2.4. The CPU usage was in the order of 0.3%
for an idle instance, however this is a shame as more energy is consumed
by the server, if not important resources.

This commit introduces HZ as a runtime parameter, that can be queried by
INFO or CONFIG GET, and can be modified with CONFIG SET. At the same
time the default frequency is set back to 10.

In this way we default to a sane value of 10, but allows users to
easily switch to values up to 500 for near real-time applications if
needed and if they are willing to pay this small CPU usage penalty.
2013-03-11 11:28:55 +01:00
Gengliang Wang 2d24bf2f94 Removed useless "return" statements in pubsub.c
(original commit message edited)
2013-03-06 16:50:56 +01:00
antirez e7a61d287e API to lookup commands with their original name.
A new server.orig_commands table was added to the server structure, this
contains a copy of the commant table unaffected by rename-command
statements in redis.conf.

A new API lookupCommandOrOriginal() was added that checks both tables,
new first, old later, so that rewriteClientCommandVector() and friends
can lookup commands with their new or original name in order to fix the
client->cmd pointer when the argument vector is renamed.

This fixes the segfault of issue #986, but does not fix a wider range of
problems resulting from renaming commands that actually operate on data
and are registered into the AOF file or propagated to slaves... That is
command renaming should be handled with care.
2013-03-06 16:36:52 +01:00
antirez 78bae8b078 Add a warning about command renaming in redis.conf. 2013-03-06 16:36:52 +01:00
antirez bf6c5d960d Handle a non-impossible empty argv in loadServerConfigFromString().
Usually this does not happens since we trim for " \t\r\n", but if there
are other chars that return true with isspace(), we may end with an
empty argv. Better to handle the condition in an explicit way.
2013-03-06 12:44:28 +01:00
antirez 95fc9cc0a6 redis-cli: use sdsfreesplitres() instead of hand-coding it. 2013-03-06 12:44:23 +01:00
antirez 5de5efa364 sds.c: sdssplitargs_free() removed as it was a duplicate. 2013-03-06 12:44:19 +01:00
antirez 1f2d5941a1 More specific error message in loadServerConfigFromString(). 2013-03-06 12:44:16 +01:00
antirez 60aa3a67e8 sdssplitargs(): on error set *argc to 0.
This makes programs not checking the return value for NULL much safer
since with this change:

1) It is still possible to iterate the zero-length result without
crashes.
2) sdssplitargs_free will work against NULL and 0 count.
2013-03-06 12:44:10 +01:00
antirez 921aec17b6 sdssplitargs(): now returns NULL only on error.
An empty input string also resulted into the function returning NULL
making it harder for the caller to distinguish between error and empty
string without checking the original input string length.
2013-03-06 12:44:06 +01:00
charsyam e174290307 Don't segfault on unbalanced quotes. 2013-03-06 12:44:02 +01:00
antirez a3273dbfa6 Allow AUTH while loading the DB in memory.
While Redis is loading the AOF or RDB file in memory only a subset of
commands are allowed. This commit adds AUTH to this subset.
2013-03-06 11:51:26 +01:00
antirez e9318d92db redis-cli: use keepalive socket option.
This should improve things in two ways:

1) Prevent timeouts caused by the execution of long commands.
2) Improve detection of real connection errors.

This is mostly effective only on Linux because of the bogus default
keepalive settings. In Linux we have OS-specific calls to set the
keepalive interval to reasonable values.
2013-03-04 11:16:24 +01:00
0x20h 803c5b140d suppress external diff program when using git diff. 2013-03-04 10:59:22 +01:00
Stam He 74373cd930 add a check for aeCreateTimeEvent
1) Add a check for aeCreateTimeEvent in function initServer.
2013-03-04 10:52:53 +01:00
Stam He b5047d9b2f point 2 of slave-serve-stale-data miss '-' between 'stale' and 'data' 2013-03-04 10:49:30 +01:00
antirez 34b420dbf3 Replication: more strict error checking for master PING reply. 2013-02-12 16:59:38 +01:00
antirez 02ac84ddbd Test: avoid false positives in CLIENT SETNAME closed connection test. 2013-02-12 13:27:32 +01:00
Steven Penny 45bfab8596 Format to fit 80 columns
This makes it readable on GitHub and editors without auto wrapping.
2013-02-12 13:11:47 +01:00
antirez 948fdb5f7d Redis 2.6.10 2013-02-11 13:24:39 +01:00
antirez fe97d7b1db Makefile: valgrind target added (forces -O0 and libc malloc). 2013-02-11 12:11:21 +01:00
antirez e88517ac30 TCP keep-alive. Better documentation in redis.conf. 2013-02-11 11:47:35 +01:00
antirez 2d89c53d0d Tcp keep-alive: send three probes before detectin an error.
Otherwise we end with less reliable connections because it's too easy
that a single packet gets lost.
2013-02-11 11:47:31 +01:00
antirez 0fe052efaa tcp-keepalive option documented in redis.conf. 2013-02-11 11:47:28 +01:00
antirez e1e8b1cd29 Set SO_KEEPALIVE on client sockets if configured to do so. 2013-02-11 11:47:23 +01:00
antirez 609a3ec1be Add SO_KEEPALIVE support to anet.c. 2013-02-11 11:47:20 +01:00
antirez 0b50d1ce9a Sentinel: advertise the promoted slave address only after successful setup. 2013-02-11 11:47:16 +01:00
Pierre Chapuis c7b9a57fb2 fix comments forgotten in #285 (zipmap -> ziplist) 2013-02-11 11:47:10 +01:00
antirez 63ad0e8867 Make all WATCHers dirty when the slave reloads the DB. 2013-02-08 10:27:26 +01:00
antirez d5d0b467db LASTSAVE is a "random" command. 2013-02-07 19:13:09 +01:00
antirez cf0191dc3c TCP_NODELAY after SYNC: changes to the implementation. 2013-02-05 12:05:04 +01:00
charsyam 45b1b2f7ad Turn off TCP_NODELAY on the slave socket after SYNC.
Further details from @antirez:

It was reported by @StopForumSpam on Twitter that the Redis replication
link was strangely using multiple TCP packets for multiple commands.
This wastes a lot of bandwidth and is due to the TCP_NODELAY option we
enable on the socket after accepting a new connection.

However the master -> slave channel is a one-way channel since Redis
replication is asynchronous, so there is no point in trying to reduce
the latency, we should aim to reduce the bandwidth. For this reason this
commit introduces the ability to disable the nagle algorithm on the
socket after a successful SYNC.

This feature is off by default because the delay can be up to 40
milliseconds with normally configured Linux kernels.
2013-02-05 12:05:01 +01:00
antirez eb07793b59 Test: No clients timeout while testing. 2013-02-05 12:02:36 +01:00
Johan Bergström 22ccc6db0f Use info nameofexectuable to find current executable 2013-02-05 11:45:11 +01:00
Johan Bergström f9a8b0eced Enforce tcl 8.5 or newer 2013-02-05 11:45:08 +01:00
Johan Bergström 6da090e916 Check available tcl versions 2013-02-05 11:45:05 +01:00
Rock Li 8c0b9f778e retval doesn't initalized
If each if conditions are all fail, variable retval will under uninitlized
2013-02-05 10:49:20 +01:00
David Celis 63dc34bd01 Fix a few typos and improve grammar of redis.conf
Make several edits to the example redis.conf configuration file for
improved flow and grammar.

Signed-off-by: David Celis <me@davidcel.is>
2013-02-04 10:36:24 +01:00
Gengliang Wang 9ddd0f7796 Fix a bug in srandmemberWithCountCommand()
In CASE 2, the call sunionDiffGenericCommand will involve the string "srandmember"
> sadd foo one
(integer 1)
> sadd srandmember two
(integer 2)
> srandmember foo 3
1)"one"
2)"two"
2013-02-04 10:33:24 +01:00
antirez c17a7f6fbc Lua struct library updated to version 0.2.
There was a bug in the previous version of this library that caused a
crash under the circumstances described in issue #901.

The newer version of the library appears to be fixed (I tested it
manually with valgrind and everything seems fine now).

For more information about this library please visit this web site:

    http://www.inf.puc-rio.br/~roberto/struct/
2013-01-23 10:53:28 +01:00
antirez bfad381f57 redis-cli --bigkeys output is now simpler to understand. 2013-01-21 19:16:14 +01:00
antirez 742e580f40 UNSUBSCRIBE and PUNSUBSCRIBE: always provide a reply.
UNSUBSCRIBE and PUNSUBSCRIBE commands are designed to mass-unsubscribe
the client respectively all the channels and patters if called without
arguments.

However when these functions are called without arguments, but there are
no channels or patters we are subscribed to, the old behavior was to
don't reply at all.

This behavior is broken, as every command should always reply.
Also it is possible that we are no longer subscribed to a channels but we
are subscribed to patters or the other way around, and the client should
be notified with the correct number of subscriptions.

Also it is not pretty that sometimes we did not receive a reply at all
in a redis-cli session from these commands, blocking redis-cli trying
to read the reply.

This fixes issue #714.
2013-01-21 18:59:52 +01:00
antirez 1b0f244509 Fixed a bug in memtest progress bar, that had no actual effects.
This closes issue #859, thanks to @erbenmo.
2013-01-21 12:38:43 +01:00
antirez 580f65a50b Not every __sun has backtrace().
I don't know how to test for Open Solaris that has support for
backtrace() so for now removing the #ifdef that breaks compilation under
other Solaris flavors.
2013-01-21 12:07:44 +01:00
antirez a154908a8f Additionally two typos fixed thanks to @jodal 2013-01-19 13:46:24 +01:00
antirez da540228d8 Whitelist SIGUSR1 to avoid auto-triggering errors.
This commit fixes issue #875 that was caused by the following events:

1) There is an active child doing BGSAVE.
2) flushall is called (or any other condition that makes Redis killing
the saving child process).
3) An error is sensed by Redis as the child exited with an error (killed
by a singal), that stops accepting write commands until a BGSAVE happens
to be executed with success.

Whitelisting SIGUSR1 and making sure Redis always uses this signal in
order to kill its own children fixes the issue.
2013-01-19 13:30:41 +01:00
antirez 9e5b70162c Clear server.shutdown_asap on failed shutdown.
When a SIGTERM is received Redis schedules a shutdown. However if it
fails to perform the shutdown it must be clear the shutdown_asap flag
otehrwise it will try again and again possibly making the server
unusable.
2013-01-19 13:20:58 +01:00
antirez dbde1d85ea Slowlog: don't log EXEC but just the executed commands.
The Redis Slow Log always used to log the slow commands executed inside
a MULTI/EXEC block. However also EXEC was logged at the end, which is
perfectly useless.

Now EXEC is no longer logged and a test was added to test this behavior.

This fixes issue #759.
2013-01-19 12:55:12 +01:00
guiquanz 560e049947 Fixed many typos. 2013-01-19 11:08:43 +01:00
charsyam c2b43eac4f redis-cli prompt bug fix 2013-01-19 10:34:25 +01:00
Jan-Erik Rediger 5e2aa2cafb Always exit if connection fails.
This avoids unnecessary core dumps. Fixes antirez/redis#894
2013-01-19 10:29:51 +01:00
bitterb a732d86fe0 Fix an error reply for CLIENT command 2013-01-19 10:26:25 +01:00
Nathan Parry 0f4dbd9a11 redis-cli --rdb fails if server sends a ping
Redis pings slaves in "pre-synchronization stage" with newlines. (See
https://github.com/antirez/redis/blob/2.6.9/src/replication.c#L814)
However, redis-cli does not expect this - it sees the newline as the end
of the bulk length line, and ends up returning 0 as bulk the length.
This manifests as the following when running redis-cli:

    $ ./src/redis-cli --rdb some_file
    SYNC sent to master, writing 0 bytes to 'some_file'
    Transfer finished with success.

With this commit, we just ignore leading newlines while reading the bulk
length line.

To reproduce the problem, load enough data into Redis so that the
preparation of the RDB snapshot takes long enough for a ping to occur
while redis-cli is waiting for the data.
2013-01-18 11:49:58 +01:00
antirez 21159d53f5 Redis 2.6.9 2013-01-16 19:54:56 +01:00
antirez 52f6a1dc16 redis-cli: save an RDB dump from remote server to local file. 2013-01-16 19:48:26 +01:00
antirez f9c1263f31 Tests for CLIENT GETNAME/SETNAME. 2013-01-15 13:34:37 +01:00
antirez 1b2ac3b206 Typo fixed, ASCI -> ASCII. 2013-01-15 13:34:35 +01:00
antirez c5f23ca79b CLIENT GETNAME and CLIENT SETNAME introduced.
Sometimes it is much simpler to debug complex Redis installations if it
is possible to assign clients a name that is displayed in the CLIENT
LIST output.

This is the case, for example, for "leaked" connections. The ability to
provide a name to the client makes it quite trivial to understand what
is the part of the code implementing the client not releasing the
resources appropriately.

Behavior:

    CLIENT SETNAME: set a name for the client, or remove the current
                    name if an empty name is set.
    CLIENT GETNAME: get the current name, or a nil.
    CLIENT LIST: now displays the client name if any.

Thanks to Mark Gravell for pushing this idea forward.
2013-01-15 13:34:34 +01:00
antirez 27abaa238f Undo slave-master handshake when SLAVEOF sets a new slave.
Issue #828 shows how Redis was not correctly undoing a non-blocking
connection attempt with the previous master when the master was set to a
new address using the SLAVEOF command.

This was also a result of lack of refactoring, so now there is a
function to cancel the non blocking handshake with the master.
The new function is now used when SLAVEOF NO ONE is called or when
SLAVEOF is used to set the master to a different address.
2013-01-15 13:33:30 +01:00
antirez 78b175a241 Makefile.dep updated. 2013-01-11 23:51:00 +01:00
antirez 14cc0045dc Redis 2.6.8 2013-01-10 17:15:16 +01:00
antirez 023cbc3787 Comment in the call() function clarified a bit. 2013-01-10 12:04:52 +01:00
antirez b70b9c6027 Test: added regression for issue #872. 2013-01-10 12:04:48 +01:00
antirez 46dc3fbb53 Multiple fixes for EVAL (issue #872).
1) The event handler was no restored after a timeout condition if the
   command was eventually executed with success.
2) The command was not converted to EVAL in case of errors in the middle
   of the execution.
3) Terrible duplication of code without any apparent reason.
2013-01-10 12:04:45 +01:00
antirez c1c3e9b756 Better error reporting when fd event creation fails. 2013-01-03 14:32:11 +01:00
antirez 1f8ad7ae55 ae.c: set errno when error is not a failing syscall.
In this way the caller is able to perform better error checking or to
use strerror() without the risk of meaningless error messages being
displayed.
2013-01-03 14:32:06 +01:00
antirez 4468ba2317 Fix overflow in mstime() in redis-cli and benchmark.
The problem does not exist in the Redis server implementation of mstime()
but is only limited to redis-cli and redis-benchmark.

Thix fixes issue #839.
2012-12-20 15:21:37 +01:00
antirez d8a0fddd51 CONTRIBUTING updated with request to add BSD license. 2012-12-17 11:17:52 +01:00
antirez 886c9ecb7c Added missing license and copyright in deps/hiredis. 2012-12-17 11:11:27 +01:00
Patrick TJ McPhee 8e0a9f6027 Define _XOPEN_SOURCE appropriately on NetBSD. 2012-12-12 18:42:36 +01:00
antirez d64a9cf514 Fix config.h endianess detection to work on Linux / PPC64.
Config.h performs endianess detection including OS-specific headers to
define the endianess macros, or when this is not possible, checking the
processor type via ifdefs.

Sometimes when the OS-specific macro is included, only __BYTE_ORDER is
defined, while BYTE_ORDER remains undefined. There is code at the end of
config.h endianess detection in order to define the macros without the
underscore, but it was not working correctly.

This commit fixes endianess detection fixing Redis on Linux / PPC64 and
possibly other systems.
2012-12-11 17:19:58 +01:00
antirez d9301f05e2 Redis 2.6.7 2012-12-03 12:53:09 +01:00
Brian J. McManus 6c9897f6cf Issue 804 Add Default-Start and Default-Stop LSB tags for RedHat startup and update-rc.d compatability. 2012-12-03 12:31:10 +01:00
antirez 984f6edf0a Memory leak fixed: release client's bpop->keys dictionary.
Refactoring performed after issue #801 resolution (see commit
2f87cf8b01) introduced a memory leak that
is fixed by this commit.

I simply forgot to free the new allocated dictionary in the client
structure trusting the output of "make test" on OSX.

However due to changes in the "leaks" utility the test was no longer
testing memory leaks. This problem was also fixed.

Fortunately the CI test running at ci.redis.io spotted the bug in the
valgrind run.

The leak never ended into a stable release.
2012-12-03 12:17:56 +01:00
antirez a2b3fff235 Test: fixed osx "leaks" support in test.
Due to changes in recent releases of osx leaks utility, the osx leak
detection no longer worked. Now it is fixed in a way that should be
backward compatible.
2012-12-03 12:17:52 +01:00
antirez 54b08c86a6 Blocking POP: use a dictionary to store keys clinet side.
To store the keys we block for during a blocking pop operation, in the
case the client is blocked for more data to arrive, we used a simple
linear array of redis objects, in the blockingState structure:

    robj **keys;
    int count;

However in order to fix issue #801 we also use a dictionary in order to
avoid to end in the blocked clients queue for the same key multiple
times with the same client.

The dictionary was only temporary, just to avoid duplicates, but since
we create / destroy it there is no point in doing this duplicated work,
so this commit simply use a dictionary as the main structure to store
the keys we are blocked for. So instead of the previous fields we now
just have:

    dict *keys;

This simplifies the code and reduces the work done by the server during
a blocking POP operation.
2012-12-02 20:36:18 +01:00
antirez 6bdcd50b56 Test: regression for issue #801. 2012-12-01 23:07:09 +01:00
antirez cac49a9031 Client should not block multiple times on the same key.
Sending a command like:

BLPOP foo foo foo foo 0

Resulted into a crash before this commit since the client ended being
inserted in the waiting list for this key multiple times.
This resulted into the function handleClientsBlockedOnLists() to fail
because we have code like that:

    if (de) {
        list *clients = dictGetVal(de);
        int numclients = listLength(clients);

        while(numclients--) {
            listNode *clientnode = listFirst(clients);

            /* server clients here... */
        }
    }

The code to serve clients used to remove the served client from the
waiting list, so if a client is blocking multiple times, eventually the
call to listFirst() will return NULL or worse will access random memory
since the list may no longer exist as it is removed by the function
unblockClientWaitingData() if there are no more clients waiting for this
list.

To avoid making the rest of the implementation more complex, this commit
modifies blockForKeys() so that a client will be put just a single time
into the waiting list for a given key.

Since it is Saturday, I hope this fixes issue #801.
2012-12-01 12:26:07 +01:00
antirez ed70955510 Make an EXEC test more latency proof. 2012-11-29 16:12:26 +01:00
antirez b41f4e5a48 Redis 2.6.6 2012-11-28 18:53:09 +01:00
antirez 21b26915ce Jemalloc updated to version 3.2.0. 2012-11-28 18:42:41 +01:00
antirez 3ccfb5a4d6 Redis 2.6.5 2012-11-22 17:03:27 +01:00
antirez 9120275dc9 EVALSHA is now case insensitive.
EVALSHA used to crash if the SHA1 was not lowercase (Issue #783).
Fixed using a case insensitive dictionary type for the sha -> script
map used for replication of scripts.
2012-11-22 15:51:01 +01:00
antirez de00a5a092 Fix integer overflow in zunionInterGenericCommand().
This fixes issue #761.
2012-11-22 15:28:45 +01:00
antirez 2b45ef020c Test: MULTI state is cleared after EXECABORT error. 2012-11-22 10:36:36 +01:00
antirez 52bd3d8a39 Test: make sure EXEC fails after previous transaction errors. 2012-11-22 10:36:32 +01:00
antirez 37d978d9b4 Test: MULTI/EXEC tests moved into multi.tcl. 2012-11-22 10:36:28 +01:00
antirez 41f0f927c9 Safer handling of MULTI/EXEC on errors.
After the transcation starts with a MULIT, the previous behavior was to
return an error on problems such as maxmemory limit reached. But still
to execute the transaction with the subset of queued commands on EXEC.

While it is true that the client was able to check for errors
distinguish QUEUED by an error reply, MULTI/EXEC in most client
implementations uses pipelining for speed, so all the commands and EXEC
are sent without caring about replies.

With this change:

1) EXEC fails if at least one command was not queued because of an
error. The EXECABORT error is used.
2) A generic error is always reported on EXEC.
3) The client DISCARDs the MULTI state after a failed EXEC, otherwise
pipelining multiple transactions would be basically impossible:
After a failed EXEC the next transaction would be simply queued as
the tail of the previous transaction.
2012-11-22 10:36:20 +01:00
antirez 5ab4151d7f Children creating AOF or RDB files now report memory used by COW.
Finally Redis is able to report the amount of memory used by
copy-on-write while saving an RDB or writing an AOF file in background.

Note that this information is currently only logged (at NOTICE level)
and not shown in INFO because this is less trivial (but surely doable
with some minor form of interprocess communication).

The reason we can't capture this information on the parent before we
call wait3() is that the Linux kernel will release the child memory
ASAP, and only retain the minimal state for the process that is useful
to report the child termination to the parent.

The COW size is obtained by summing all the Private_Dirty fields found
in the "smap" file inside the proc filesystem for the process.

All this is Linux specific and is not available on other systems.
2012-11-20 12:32:19 +01:00
antirez e95ca66320 zmalloc_get_private_dirty() function added (Linux only).
For non Linux systmes it just returns 0.

This function is useful to estimate copy-on-write because of childs
saving stuff on disk.
2012-11-20 12:32:14 +01:00
antirez 681c191006 zmalloc: kill unused __size parameter in update_zmalloc_stat_alloc() macro. 2012-11-14 13:07:48 +01:00
antirez d85a09dfc6 MIGRATE: fix default timeout to 1000 milliseconds.
When a timeout <= 0 is provided we set a default timeout of 1 second.
It was set to 1 millisecond for an error resulting from a recent change.
2012-11-12 18:58:23 +01:00
antirez 26a48504cb MIGRATE timeout should be in milliseconds.
While it is documented that the MIGRATE timeout is in milliseconds, it
was in seconds instead. This commit fixes the problem.
2012-11-12 18:57:55 +01:00
antirez ae3aeca828 MIGRATE: fix fd leak due to missing close on error. 2012-11-12 18:56:29 +01:00
antirez 5a8234d2c9 Copyright date fixed in COPYING file. 2012-11-08 19:14:29 +01:00
antirez 2861cd84f9 Redis 2.6.4 2012-11-08 18:47:58 +01:00
antirez 8e30092f06 Make clear that contributing code to the Redis project means to release it under the terms of the BSD license. 2012-11-08 18:43:37 +01:00
antirez d288ee655f BSD license added to every C source and header file. 2012-11-08 18:33:13 +01:00
antirez 89514f80e9 Redis 2.6.3 2012-11-06 22:07:51 +01:00
Runzhen Wang 3f006679b1 fix a typo in redis.h line 595 comment 2012-11-02 12:12:01 +01:00
antirez 36f026a3a0 More robust handling of AOF rewrite child.
After the wait3() syscall we used to do something like that:

    if (pid == server.rdb_child_pid) {
        backgroundSaveDoneHandler(exitcode,bysignal);
    } else {
        ....
    }

So the AOF rewrite was handled in the else branch without actually
checking if the pid really matches. This commit makes the check explicit
and logs at WARNING level if the pid returned by wait3() does not match
neither the RDB or AOF rewrite child.
2012-11-01 22:41:57 +01:00
Salvatore Sanfilippo cc017c5839 Merge pull request #743 from Cofyc/fixtypo
fix typo in comments (redis.c, networking.c)
2012-11-01 14:26:01 -07:00
antirez b6ffa85f11 Unix socket clients properly displayed in MONITOR and CLIENT LIST.
This also fixes issue #745.
2012-11-01 22:12:45 +01:00
antirez 4917a6a8b3 32 bit build fixed on Linux.
It failed because of the way jemalloc was compiled (without passing the
right flags to make, but just to configure). Now the same set of flags
are also passed to the make command, fixing the issue.

This fixes issue #744
2012-11-01 15:37:38 +01:00
Yecheng Fu ed44a74e72 fix typo in comments (redis.c, networking.c) 2012-11-01 18:14:55 +08:00
YAMAMOTO Takashi 47ff443b53 fix a typo in a comment 2012-10-31 09:29:56 +01:00
antirez 4d9bd53530 Invert two sides of if expression in SET to avoid a lookup.
Because of the short circuit behavior of && inverting the two sides of
the if expression avoids an hash table lookup if the non-EX variant of
SET is called.

Thanks to Weibin Yao (@yaoweibin on github) for spotting this.
2012-10-31 09:27:48 +01:00
antirez 5bf0997ff8 No longer used macro rdbIsOpcode() removed. 2012-10-30 19:10:56 +01:00
antirez ec0f483de2 help.h update (adds bitop, bitcount, evalsha...) 2012-10-30 18:57:28 +01:00
antirez 0dd6241314 Redis 2.6.2 2012-10-26 16:20:24 +02:00
antirez 3b1a41b172 Ctrl+w support in linenoise. 2012-10-26 16:06:36 +02:00
antirez 9b3b110004 Marginally more robust glibc version test for sync_file_range detection. 2012-10-26 15:55:10 +02:00
charsyam b25b0dc5f4 patch config.h for sync_file_range 2012-10-26 09:30:35 +02:00
antirez 2b5fc529a4 Redis 2.6.1 2012-10-25 22:07:27 +02:00
antirez be407c015c Fix compilation on Linux kernels or glibc versions lacking sync_file_range().
This fixes issue #667.

Many thanks to Didier Spezia for the fix.
2012-10-25 22:01:07 +02:00
antirez 1eb9145089 Update memory peak stats while loading RDB / AOF. 2012-10-24 12:21:34 +02:00
273 changed files with 34375 additions and 4671 deletions
+18
View File
@@ -10,6 +10,11 @@ redis-sentinel
redis-server
doc-tools
release
bin/
obj/
Debug/
Release/
x64/
misc/*
src/release.h
appendonly.aof
@@ -25,3 +30,16 @@ deps/lua/src/liblua.a
.make-*
.prerequisites
*.dSYM
*.user
*.exe
*.sdf
*.suo
msvs/ReleasePackagingT
msvs/ipch
msvs/RedisServer.opensdf
!msvs/RedisWaInst/bin/*
!msvs/RedisWaInst/bin/Inst4WA/*
!msvs/RedisWaInst/bin/RedisPkgBin/*
msvs/RedisWAInst/src/RedisInstBin/
msvs/RedisWAInst/src/RedisInstWA/app.config
+95
View File
@@ -14,6 +14,101 @@ HIGH: There is a critical bug that may affect a subset of users. Upgrade!
CRITICAL: There is a critical bug affecting MOST USERS. Upgrade ASAP.
--------------------------------------------------------------------------------
--[ Redis 2.8.21 ] Release date: 4 Jun 2015
Upgrade urgency: HIGH for Redis because of a security issue.
LOW for Sentinel.
* [FIX] Critical security issue fix by Ben Murphy: http://t.co/LpGTyZmfS7
* [FIX] SMOVE reply fixed when src and dst keys are the same. (Glenn Nethercutt)
* [FIX] Lua cmsgpack lib updated to support str8 type. (Sebastian Waisbrot)
* [NEW] Senitnel: CKQUORUM and FLUSHCONFIG commands back ported.
(Salvatore Sanfilippo and Bill Anderson)
--[ Redis 2.8.20 ] Release date: 5 May 2015
Upgrade urgency: LOW for Redis, MODERATE for Sentinel.
* [FIX] Sentinel memory leak due to hiredis fixed. (Salvatore Sanfilippo)
* [FIX] Sentinel memory leak on duplicated instance. (Charsyam)
* [FIX] Redis crash on Lua reaching output buffer limits. (Yossi Gottlieb)
* [FIX] Sentinel flushes config on +slave events. (Bill Anderson)
* [FIX] Fixes to diskless replication. (Oran Agra)
* [FIX] Redis (non clustered & clustered) replication bug involving blocking
operations: see issue #2473. (Salvatore Sanfilippo)
* [FIX] Config: missing activerehashing option support in CONFIG SET added.
(Salvatore Sanfilippo, thx to Bill Anderson)
* [FIX] AOF bug unlikely to happen in practice and mostly harmless: child
process segfaults when parent is not reachable via pipe. (Sun He)
* [FIX] Scripting engine now reports an error when misused with Lua debug
hooks, instead of crashing. (Salvatore Sanfilippo)
* [FIX] INFO loading stats: three fixes.
* [FIX] Fixed memory leaks in rdbSaveToSlavesSockets(). (Alon Diamant)
* [NEW] Redis-cli --latency-dist backported from unstable.
(Salvatore Sanfilippo)
--[ Redis 2.8.19 ] Release date: 16 Dec 2014
# UPGRADE URGENCY: LOW for both Redis and Sentinel. This release mostly
fixes small issues.
02d465c Don't log admin commands in MONITOR. (antirez)
4d8f426 List of commands flagged as admin commands modified. (antirez)
e47e460 Lua cmsgpack lib updated to latest version. (antirez)
5509c14 Add symlink to redis-sentinel during make install (Rhommel Lamas)
7de1ef7 SORT: Don't sort Set elements if not needed. (antirez)
e945a54 Fix zero-ordering SORT when called against lists (Matt Stancliff)
d81c383 Update redis_init_script.tpl (Ben Dowling)
dba57ea FIXED redis-benchmark's idle mode.With idle mode shouldn't create write event (zhanghailei)
888ea17 zipmap.c: update comments above (Sun He)
86ebc13 replaced // comments #2150 (Deepak Verma)
3d73f08 redis-benchmark AUTH command to be discarded after the first send #2150 (azure provisioned user)
76d53a6 sds.c: Correct two spelling mistakes in comments (Sun He)
4848cf9 sds.c/sdscatvprintf: set va_end to finish va_list cpy (Sun He)
d2f584f sds.c: Correct some comments (Sun He)
2ed3f09 Update whatisdoing.sh (Serghei Iakovlev)
77b997d Include stropts only if __sun is defined. (antirez)
d409371 Fix implicit declaration of ioctl on Solaris (Jan-Erik Rediger)
23b96c0 Silence _BSD_SOURCE warnings in glibc 2.20 and forward (Johan Bergström)
a47a042 Mark whatisdoing.sh as deprecated in top-comment. (antirez)
b5737d2 getting pid fixes (Serghei Iakovlev)
a598e08 sparkline.c: AddSample skip Empty label (Sun He)
7d480ab sparkline.c: mov label-ini into the AddSample Function (Sun He)
2f3c860 Only ignore sigpipe in interactive mode (Jan-Erik Rediger)
0c211a1 Simplify lua_cmsgpack macro and fix build on old Linux distros. (antirez)
--[ Redis 2.8.18 ] Release date: 4 Dec 2014
# UPGRADE URGENCY: LOW for both Redis and Sentinel. This release mostly
adds new features to Redis, and contains non critical
fixes.
* [FIX] Linenoise updated to be more VT100 compatible. (Salvatore Sanfilippo)
* [FIX] A number of typos fixed inside comments. (Various authors)
* [FIX] redis-cli no longer quits after long timeouts. (Matt Stancliff)
* [FIX] Test framework improved to detect never terminating scripts, cleanup
instances on crashes. (Salvatore Sanfilippo)
* [FIX] PFCOUNT can be used on slaves now. (Salvatore Sanfilippo)
* [FIX] ZSCAN no longer report very small scores as 0. (Matt Stancliff,
Michael Grunder, Salvatore Sanfilippo)
* [FIX] Don't show the ASCII logo if syslog is enabled. Redis is now
an Enterprise Grade product. (Salvatore Sanfilippo)
* [NEW] EXPERIMENTAL: Diskless replication, for more info check the doc at
http://redis.io/topics/replication. (Salvatore Sanfilippo).
* [NEW] Transparent Huge Pages detection and reporting in logs and
LATENCY DOCTOR output. (Salvatore Sanfilippo)
* [NEW] Many Lua scripting enhancements: Bitops API, cjson upgrade and tests,
cmsgpack upgrade. (Matt Stancliff)
* [NEW] Total and instantaneous Network bandwidth tracking in INFO.
* [NEW] DEBUG POPULATE two args form implemented (old form still works).
The second argument is the key prefix. Default is "key:" (Salvatore
Sanfilippo)
* [NEW] Check that tcp-backlog is matched by /proc/sys/net/core/somaxconn, and
warn about it if not. (Salvatore Sanfilippo)
--[ Redis 2.8.17 ] Release date: 19 Sep 2014
# UPGRADE URGENCY: HIGH for Redis Sentinel.
+1 -1
View File
@@ -1 +1 @@
Plese check https://github.com/antirez/redis/issues
Please check https://github.com/antirez/redis/issues
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2006-2014, Salvatore Sanfilippo
Copyright (c) 2006-2015, Salvatore Sanfilippo
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-154
View File
@@ -1,154 +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 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!
+59
View File
@@ -0,0 +1,59 @@
[![Windows Status](http://img.shields.io/appveyor/ci/MSOpenTech-lab/redis.svg?style=flat-square)](https://ci.appveyor.com/project/MSOpenTech-lab/redis)
[![NuGet version](http://img.shields.io/nuget/v/redis-64.svg?style=flat-square)](http://www.nuget.org/packages/redis-64/)
[![NuGet downloads](http://img.shields.io/nuget/dt/redis-64.svg?style=flat-square)](http://www.nuget.org/packages/redis-64/)
[![Chocolatey version](http://img.shields.io/chocolatey/v/redis-64.svg?style=flat-square)](http://www.chocolatey.org/packages/redis-64/)
[![Chocolatey downloads](http://img.shields.io/chocolatey/dt/redis-64.svg?style=flat-square)](http://www.chocolatey.org/packages/redis-64/)
Redis on Windows
===
## Redis 2.8 Branch
- This is a port for Windows based on Redis 2.8.
- There is support for the 64-bit version. We have dropped official support for the 32-bit version, though you can build it from source if desired.
- You can download the latest binaries (unsigned) from [http://github.com/MSOpenTech/redis/releases](http://github.com/MSOpenTech/redis/releases "Release page"). For releases prior to 2.8.17.1, the binaries can found in a zip file inside the source archive, under the bin/release folder.
- 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.
- Redis can be installed as a Windows Service.
## Redis 2.8 release notes
- 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)
## How to configure and deploy 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 (x64) then build.
This should create the following executables in the msvs\$(Target)\$(Configuration) folder:
- redis-server.exe
- redis-benchmark.exe
- redis-cli.exe
- redis-check-dump.exe
- redis-check-aof.exe
## Unit Testing
To run the Redis test suite requires some manual work:
- The tests assume that the binaries are in the src folder. Use mklink to create a symbolic link to the files in the msvs\x64\Debug|Release folders. You will
need symbolic links for src\redis-server, src\redis-benchmark, src\redis-check-aof, src\redis-check-dump, src\redis-cli, and src\redis-sentinel.
- The tests make use of TCL. This must be installed separately.
- 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, but some of the tests may fail when the number of clients is greater than 2.
+106
View File
@@ -0,0 +1,106 @@
MSOpenTech Redis on Windows 2.8 Release Notes
=============================================
--[ Redis on Windows 2.8.2101 ] Release date: Jul 15 215
- [Fix] deleting char** correctly (@zeliard)
- [Fix] Fork code for background processing 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.
- [Setup] Updated the scripts to create/push the NuGet/Chocolatey packages.
- [Setup] EventLog.dll excluded from NuGet package.
- [Fix] The stack trace was not logged when Redis is running as a service.
- [Setup] Move ReleasePackagingTool to its own solution.
- [WinPort] Explicit cast.
- [Cleanup] Removed non-existent file from hiredis project.
- [Cleanup] Minor change to method signature.
- [Cleanup] Changed variable type to match function return value.
- [Cleanup] Removed useless platform definition from RedisServer.sln
- [Cleanup] Removed unused include.
- [Fix] UnhandledExceptiontHandler internal exception handling.
- [Fix] RFDMap was not thread safe.
- [Change] Removed extra space allocated at the end of the mmap file.
- [Cleanup] Tabs->spaces, formatting.
- [Fix] aeWinQueueAccept wrong return value.
- [Change] Removed the forkedProcessReady event.
- [Change] Rolled back "Workaround for getpeername() issue".
- [Cleanup] Code cleanup: variables initialization and validation.
- [Fix] Socket blocking state.
- [Fix] Memory corruption. Merged fix from Azure fork (by Mike Montwill).
- [Fix] Added API mapping for fclose() and fileno().
- [Setup] Updated the release number and the release notes (2.8.2101).
- [Fix] Bug report fixes.
- [Setup] Nuget/Chocolatey packages update.
- [Fix] Memory was not properly released at the end of the memory test.
- [Change] Hard-coded memory test loops changed from 50 to 5.
--[ Redis on Windows 2.8.21 ] Release date: Jun 24 2015
- 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 on Windows 2.8.19.1 ] Release date: May 04 2015
- Added an MSI installer, in addition to the .zip distribution
- Various bug fixes, including:
#167
#228
--[ Redis on Windows 2.8.19 ] Release date: Feb 25 2015
- Workaround for getpeername() issue, which affected sentinel failover over ipv6.
- Miscellaneous bug fixes.
--[ Redis on Windows 2.8.17.4 ] Release date: Feb 02 2015
- Fix AV in AllocHeapBlock.
--[ Redis on Windows 2.8.17.3 ] Release date: Dec 26 2014
- Fix redis-cli pipe mode.
--[ Redis on Windows 2.8.17.2 ] Release date: Dec 23 2014
- Moved binaries out of the repository, to the Releases page.
- Miscellaneous bug fixes.
--[ Redis on Windows 2.8.17.1 ] Release date: Dec 16 2014
- 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
+114
View File
@@ -0,0 +1,114 @@
MSOpenTechs 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?
====================================
Redis is a C code base that compiles under Visual Studio. Most of the code compiles with only minor changes to the code due to syntactical differences between compilers and low level API differences on Windows. There are a few areas where there are significant differences in how efficient Windows programs operate relative to POSIX programs. We have encapsulated most these differences in a platform specific library. The areas where there are significant differences are:
- Networking APIs
- POSIX File Descriptors
- POSIX fork()
- Logging
- Windows Services API
Networking Differences
----------------------
The Windows networking stack is split between user mode code and kernel mode code. Transitions between user and kernel mode are expensive operations. The POSIX networking APIs on Windows utilize a programming model that incurs significant performance loss due to the kernel/user mode transitions. Efficient Windows networking code instead uses the IO Completion Port model to reduce the impact of this behavior. The APIs used and the programming model for IO Completion is different enough that we were forced to implement a new networking layer in in Redis.
File Descriptors
----------------
In a POSIX operating system all data sources (files, pipes, sockets, mail slots, etc.) are referenced in code with a handle called a file descriptor. These are low value integers that increment by one with each successive file descriptor created in a given program. All POSIX APIs that work with file descriptors will function without the programmer having to know what kind of data source a file descriptor represents. On Windows generally each kind of data source has a separate kind of HANDLE. APIs that work with one HANDLE type will not work with another kind of HANDLE. In order to make Redis operate with its assumptions about file descriptor values and data source agnosticism, we implemented a Redis File Descriptor API layer.
fork()
------
The POSIX version of Redis uses the fork() API. There is no equivalent in Windows, and it is an exceedingly difficult API to completely simulate. For most of the uses of fork() we have used Windows specific programming idioms to bypass the need to use a fork()-like API. The one case where we could not do so was with the point-in-time heap snapshot behavior that the Redis persistence model is based on. We tried several different approaches to work around the need for a fork()-like API, but always ran into significant performance penalties and stability issues.
Our current approach is to simulate the point-in-time snapshot behavior aspect of fork() without doing a complete simulation of fork(). We do this with a memory mapped file that contains the Redis heap. When a fork() operation is required we do the following:
- Mark every page in the memory mapped file with the Copy on Write page protection
- Start a child process and pass it the handle to the memory mapped file
- Signal the child to start the AOF or RDB persistence process on the memory shared via the memory mapped file
- Wait (asynchronously) for the child process to finish
- Map the changes in the Redis heap that occurred during the fork() operation back into the memory mapped file.
The upside with this implementation is that our performance and stability is now on par with the POSIX version of Redis. The down side is that we have a runtime disk space requirement for Redis equal to the size of the Redis memory mapped heap. The disk space requirement defaults to:
- The size specified by the maxheap flag if present, otherwise
- 50% more than the --maxmemory setting if present, otherwise
- The size of physical RAM
We also have a runtime page file commit requirement that varies depending on the amount data in the Redis heap during the quasi-fork operation. The maximum for this is about 3 times the size of the memory mapped file. This is usually not a problem because the default configuration of Windows allows the page file to grow to 3.5 times the size of physical memory. There are scenarios where 3<sup>rd</sup> party programs also compete for system swap space at runtime.
Logging
-------
In addition to file based logging, the POSIX version of Redis supports logging via the syslog facility. The equivalent in Windows is the Event Log. With the recent addition of the Windows Service code we have added support for logging to the Event Log. We have mapped the syslogxxxx flags for this purpose.
Windows Service
---------------
In version 2.8.9 we are adding support to make Redis operate as a service. See the RedisService.docx file included with the GitHub binary distribution for a description of the service commands available.
Redis on Windows Best Practices
===============================
Binary Distributions
--------------------
The GitHub repository should be considered a work in progress until we release the NuGet and Chocolatey packages and tag the repository at that released version.
For instance, the Windows Service feature has taken many iterations with community input to get right. The initial Windows service code was checked in on April 3. Since that time we have added the following to the service based on community input:
- Preshutdown notification in order to clean up the memory mapped file consistently.
- Code to identify and clean up orphaned memory mapped files left behind when a machine running Redis as a service crashes or loses power.
- Self elevation of the Redis executable so that service commands would work from a non-elevated command prompt.
- Service naming so that multiple instances of the Redis service could be installed on one machine.
- Automatically adjusting folder permissions so that when Redis is run under the NETWORK SERVICE account it could modify the files in the installation directory.
- Moved all of the pre-main() error reporting code (service and quasi-fork code) that could write errors to stdout to use the Redis logging code. This allows service initialization errors to reach the Event Log. This required intercepting all of the command line and conf file arguments before main() in order to properly initialize the logging engine. There were several fixes related to the intricacies of how to interpret the arguments passed to Redis.
The final service code has been released as of June 25 in the 2.8.9 Redis-64 packages.
Heap Sizing
-----------
Native heaps are prone to fragmentation. If we are not able to allocate more heap space due to fragmentation Redis will flag the problem and exit. Unlike the POSIX version of Redis, our heap size is constrained by both by disk space and by swap file space. It is important to consider the how much data you are expecting to put into Redis, and how much fragmentation you are likely to see in the Redis heap. With very high levels of fragmentation the 50% overhead that maxmemory imposes may not be enough to prevent running out of heap space. In this case, the use of maxheap will supersede the maxmemory default heap setting.
Installation and Maintenance
----------------------------
Since Redis uses system swap space, the most stable configurations will only have Redis running on essentially a virgin operating system install.
Redis is xcopy deployable. There should be no problem upgrading versions by simply copying new binaries over old ones (assuming they are not currently in use).
Service Account
---------------
When using Redis as a Windows service, the default installation configures Redis to run under the systems 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>.
+95
View File
@@ -0,0 +1,95 @@
Running Redis as a Service
==========================
If you installed Redis using the MSI package, then Redis was already installed as a Windows service. Nothing further to do. If you would like to change its settings, you can update the *redis.windows.conf* file and then restart the Redis service (Run -\> services.msc -\> Redis -\> Restart).
During installation of the MSI you can either use the installers user interface to update the port that Redis listens at and the firewall exception or run it silently without a UI. The following examples show how to install from the command line:
**default install (port 6379 and firewall exception ON):**
*msiexec /i Redis-x64.msi *
**set port and turn OFF firewall exception:**
*msiexec /i Redis-x64.msi PORT=1234 FIREWALL\_ON=""*
**set port and turn ON firewall exception:**
*msiexec /i Redis-x64.msi PORT=1234 FIREWALL\_ON=1*
**install with no user interface:**
*msiexec /quiet /i Redis-x64.msi*
If you did *not* install Redis using the MSI package, then you still run Redis as a Windows service by following these instructions:
In order to better integrate with the Windows Services model, new command line arguments have been introduced to Redis. These service arguments require an elevated user context in order to connect to the service control manager. If these commands are invoked from a non-elevated context, Redis will attempt to create an elevated context in which to execute these commands. This will cause a User Account Control dialog to be displayed by Windows and may require Administrative user credentials in order to proceed.
Installing the Service
----------------------
*--service-install*
This must be the first argument on the redis-server command line. Arguments after this are passed in the order they occur to Redis when the service is launched. The service will be configured as Autostart and will be launched as "NT AUTHORITY\\NetworkService". Upon successful installation a success message will be displayed and Redis will exit.
This command does not start the service.
For instance:
redis-server --service-install redis.windows.conf --loglevel verbose
Uninstalling the Service
------------------------
*--service-uninstall*
This will remove the Redis service configuration information from the registry. Upon successful uninstallation a success message will be displayed and Redis will exit.
This does command not stop the service.
For instance:
redis-server --service-uninstall
Starting the Service
--------------------
*--service-start*
This will start the Redis service. Upon successful start, a success message will be displayed and Redis will begin running.
For instance:
redis-server --service-start
Stopping the Service
--------------------
*--service-stop*
This will stop the Redis service. Upon successful termination a success message will be displayed and Redis will exit.
For instance:
redis-server --service-stop
Naming the Service
------------------
*--service-name **name***
This optional argument may be used with any of the preceding commands to set the name of the installed service. This argument should follow the service-install, service-start, service-stop or service-uninstall commands, and precede any arguments to be passed to Redis via the service-install command.
The following would install and start three separate instances of Redis as a service:
redis-server --service-install service-name redisService1 port 10001
redis-server --service-start service-name redisService1
redis-server --service-install service-name redisService2 port 10002
redis-server --service-start service-name redisService2
redis-server --service-install service-name redisService3 port 10003
redis-server --service-start service-name redisService3
+13
View File
@@ -0,0 +1,13 @@
version: 2.8.2101.{build}
branches:
# whitelist
only:
- '2.8'
- appveyor
install:
- git submodule -q update --init
build:
project: msvs\RedisServer.sln
+2
View File
@@ -0,0 +1,2 @@
release/
debug/
+1 -1
View File
@@ -58,7 +58,7 @@ ifeq ($(uname_S),SunOS)
LUA_CFLAGS= -D__C99FEATURES__=1
endif
LUA_CFLAGS+= -O2 -Wall -DLUA_ANSI $(CFLAGS)
LUA_CFLAGS+= -O2 -Wall -DLUA_ANSI -DENABLE_CJSON_GLOBAL $(CFLAGS)
LUA_LDFLAGS+= $(LDFLAGS)
# lua's Makefile defines AR="ar rcu", which is unusual, and makes it more
# challenging to cross-compile lua (and redis). These defines make it easier
+16
View File
@@ -31,7 +31,11 @@
#ifndef __HIREDIS_AE_H__
#define __HIREDIS_AE_H__
#include <sys/types.h>
#ifdef _WIN32
#include "..\..\src\ae.h"
#else
#include <ae.h>
#endif
#include "../hiredis.h"
#include "../async.h"
@@ -65,6 +69,15 @@ static void redisAeAddRead(void *privdata) {
}
}
#ifdef _WIN32
static void redisAeForceAddRead(void *privdata) {
redisAeEvents *e = (redisAeEvents*)privdata;
aeEventLoop *loop = e->loop;
e->reading = 1;
aeCreateFileEvent(loop, e->fd, AE_READABLE, redisAeReadEvent, e);
}
#endif
static void redisAeDelRead(void *privdata) {
redisAeEvents *e = (redisAeEvents*)privdata;
aeEventLoop *loop = e->loop;
@@ -116,6 +129,9 @@ static int redisAeAttach(aeEventLoop *loop, redisAsyncContext *ac) {
/* Register functions to start/stop listening for events */
ac->ev.addRead = redisAeAddRead;
#ifdef _WIN32
ac->ev.forceAddRead = redisAeForceAddRead;
#endif
ac->ev.delRead = redisAeDelRead;
ac->ev.addWrite = redisAeAddWrite;
ac->ev.delWrite = redisAeDelWrite;
+97 -4
View File
@@ -32,7 +32,9 @@
#include "fmacros.h"
#include <stdlib.h>
#include <string.h>
#ifndef _WIN32
#include <strings.h>
#endif
#include <assert.h>
#include <ctype.h>
#include <errno.h>
@@ -40,10 +42,18 @@
#include "net.h"
#include "dict.c"
#include "sds.h"
#ifdef _WIN32
#include "../../src/win32_Interop/win32fixes.h"
#endif
#define _EL_ADD_READ(ctx) do { \
if ((ctx)->ev.addRead) (ctx)->ev.addRead((ctx)->ev.data); \
} while(0)
#ifdef _WIN32
#define _EL_FORCE_ADD_READ(ctx) do { \
if ((ctx)->ev.forceAddRead) (ctx)->ev.forceAddRead((ctx)->ev.data); \
} while (0)
#endif
#define _EL_DEL_READ(ctx) do { \
if ((ctx)->ev.delRead) (ctx)->ev.delRead((ctx)->ev.data); \
} while(0)
@@ -57,24 +67,29 @@
if ((ctx)->ev.cleanup) (ctx)->ev.cleanup((ctx)->ev.data); \
} while(0);
#ifdef _WIN32
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#endif
/* Forward declaration of function in hiredis.c */
void __redisAppendCommand(redisContext *c, char *cmd, size_t len);
/* Functions managing dictionary of callbacks for pub/sub. */
static unsigned int callbackHash(const void *key) {
return dictGenHashFunction((const unsigned char *)key,
sdslen((const sds)key));
(int)sdslen((const sds)key));
}
static void *callbackValDup(void *privdata, const void *src) {
((void) privdata);
redisCallback *dup = malloc(sizeof(*dup));
((void) privdata);
memcpy(dup,src,sizeof(*dup));
return dup;
}
static int callbackKeyCompare(void *privdata, const void *key1, const void *key2) {
int l1, l2;
size_t l1, l2;
((void) privdata);
l1 = sdslen((const sds)key1);
@@ -122,6 +137,9 @@ static redisAsyncContext *redisAsyncInitialize(redisContext *c) {
ac->ev.data = NULL;
ac->ev.addRead = NULL;
#ifdef _WIN32
ac->ev.forceAddRead = NULL;
#endif
ac->ev.delRead = NULL;
ac->ev.addWrite = NULL;
ac->ev.delWrite = NULL;
@@ -147,6 +165,31 @@ static void __redisAsyncCopyError(redisAsyncContext *ac) {
ac->errstr = c->errstr;
}
#ifdef WIN32_IOCP
redisAsyncContext *redisAsyncConnect(const char *ip, int port) {
SOCKADDR_STORAGE ss;
redisContext *c = redisPreConnectNonBlock(ip, port, &ss);
redisAsyncContext *ac = redisAsyncInitialize(c);
if (aeWinSocketConnect(ac->c.fd, &ss) != 0) {
ac->c.err = errno;
strerror_r(errno, ac->c.errstr, sizeof(ac->c.errstr));
}
__redisAsyncCopyError(ac);
return ac;
}
redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, const char *source_addr) {
SOCKADDR_STORAGE ss;
redisContext *c = redisPreConnectNonBlock(ip, port, &ss);
redisAsyncContext *ac = redisAsyncInitialize(c);
if (aeWinSocketConnectBind(ac->c.fd, &ss, source_addr) != 0) {
ac->c.err = errno;
strerror_r(errno, ac->c.errstr, sizeof(ac->c.errstr));
}
__redisAsyncCopyError(ac);
return ac;
}
#else
redisAsyncContext *redisAsyncConnect(const char *ip, int port) {
redisContext *c;
redisAsyncContext *ac;
@@ -166,12 +209,13 @@ redisAsyncContext *redisAsyncConnect(const char *ip, int port) {
}
redisAsyncContext *redisAsyncConnectBind(const char *ip, int port,
const char *source_addr) {
const char *source_addr) {
redisContext *c = redisConnectBindNonBlock(ip,port,source_addr);
redisAsyncContext *ac = redisAsyncInitialize(c);
__redisAsyncCopyError(ac);
return ac;
}
#endif
redisAsyncContext *redisAsyncConnectUnix(const char *path) {
redisContext *c;
@@ -443,6 +487,7 @@ void redisProcessCallbacks(redisAsyncContext *ac) {
if (((redisReply*)reply)->type == REDIS_REPLY_ERROR) {
c->err = REDIS_ERR_OTHER;
snprintf(c->errstr,sizeof(c->errstr),"%s",((redisReply*)reply)->str);
c->reader->fn->freeObject(reply);
__redisAsyncDisconnect(ac);
return;
}
@@ -516,7 +561,15 @@ void redisAsyncHandleRead(redisAsyncContext *ac) {
__redisAsyncDisconnect(ac);
} else {
/* Always re-schedule reads */
#ifdef _WIN32
// There appears to be a bug in the Linux version of _EL_ADD_READ which will not reschedule
// the read if already reading. This is a problem if there is a large number of async GET
// operations. If the receive buffer is exhausted with the data returned, the read would
// not be rescheduled, and the async operations would cease. This forces the read to recur.
_EL_FORCE_ADD_READ(ac);
#else
_EL_ADD_READ(ac);
#endif
redisProcessCallbacks(ac);
}
}
@@ -548,6 +601,46 @@ void redisAsyncHandleWrite(redisAsyncContext *ac) {
}
}
#ifdef _WIN32
/* The redisAsyncHandleWrite is split into a Prep and Complete routines
To allow using a write routine suitable for async behavior.
For Windows this will use IOCP on write. */
int redisAsyncHandleWritePrep(redisAsyncContext *ac) {
redisContext *c = &(ac->c);
if (!(c->flags & REDIS_CONNECTED)) {
/* Abort connect was not successful. */
if (__redisAsyncHandleConnect(ac) != REDIS_OK)
return REDIS_ERR;
/* Try again later when the context is still not connected. */
if (!(c->flags & REDIS_CONNECTED))
return REDIS_ERR;
}
return REDIS_OK;
}
int redisAsyncHandleWriteComplete(redisAsyncContext *ac, int written) {
redisContext *c = &(ac->c);
int done = 0;
int rc;
rc = redisBufferWriteDone(c, written, &done);
if (rc == REDIS_ERR) {
__redisAsyncDisconnect(ac);
} else {
/* Continue writing when not done, stop writing otherwise */
if (!done)
_EL_ADD_WRITE(ac);
else
_EL_DEL_WRITE(ac);
/* Always schedule reads after writes */
_EL_ADD_READ(ac);
}
return REDIS_OK;
}
#endif
/* Sets a pointer to the first argument and its length starting at p. Returns
* the number of bytes to skip to get to the following argument. */
static char *nextArgument(char *start, char **str, size_t *len) {
+7
View File
@@ -76,6 +76,9 @@ typedef struct redisAsyncContext {
/* Hooks that are called when the library expects to start
* reading/writing. These functions should be idempotent. */
void (*addRead)(void *privdata);
#ifdef _WIN32
void (*forceAddRead)(void *privdata);
#endif
void (*delRead)(void *privdata);
void (*addWrite)(void *privdata);
void (*delWrite)(void *privdata);
@@ -112,6 +115,10 @@ void redisAsyncFree(redisAsyncContext *ac);
/* Handle read/write events */
void redisAsyncHandleRead(redisAsyncContext *ac);
void redisAsyncHandleWrite(redisAsyncContext *ac);
#ifdef _WIN32
int redisAsyncHandleWritePrep(redisAsyncContext *ac);
int redisAsyncHandleWriteComplete(redisAsyncContext *ac, int written);
#endif
/* Command functions for an async context. Write the command to the
* output buffer and register the provided callback. */
+10 -7
View File
@@ -32,6 +32,9 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef _WIN32
#include "../../src/win32_Interop/win32_types.h"
#endif
#include "fmacros.h"
#include <stdlib.h>
@@ -42,7 +45,7 @@
/* -------------------------- private prototypes ---------------------------- */
static int _dictExpandIfNeeded(dict *ht);
static unsigned long _dictNextPower(unsigned long size);
static PORT_ULONG _dictNextPower(PORT_ULONG);
static int _dictKeyIndex(dict *ht, const void *key);
static int _dictInit(dict *ht, dictType *type, void *privDataPtr);
@@ -85,9 +88,9 @@ static int _dictInit(dict *ht, dictType *type, void *privDataPtr) {
}
/* Expand or create the hashtable */
static int dictExpand(dict *ht, unsigned long size) {
static int dictExpand(dict *ht, PORT_ULONG size) {
dict n; /* the new hashtable */
unsigned long realsize = _dictNextPower(size), i;
PORT_ULONG realsize = _dictNextPower(size), i;
/* the size is invalid if it is smaller than the number of
* elements already inside the hashtable */
@@ -211,7 +214,7 @@ static int dictDelete(dict *ht, const void *key) {
/* Destroy an entire hash table */
static int _dictClear(dict *ht) {
unsigned long i;
PORT_ULONG i;
/* Free all the elements */
for (i = 0; i < ht->size && ht->used > 0; i++) {
@@ -303,10 +306,10 @@ static int _dictExpandIfNeeded(dict *ht) {
}
/* Our hash table capability is a power of two */
static unsigned long _dictNextPower(unsigned long size) {
unsigned long i = DICT_HT_INITIAL_SIZE;
static PORT_ULONG _dictNextPower(PORT_ULONG size) {
PORT_ULONG i = DICT_HT_INITIAL_SIZE;
if (size >= LONG_MAX) return LONG_MAX;
if (size >= PORT_LONG_MAX) return PORT_LONG_MAX;
while(1) {
if (i >= size)
return i;
+4 -4
View File
@@ -60,9 +60,9 @@ typedef struct dictType {
typedef struct dict {
dictEntry **table;
dictType *type;
unsigned long size;
unsigned long sizemask;
unsigned long used;
PORT_ULONG size;
PORT_ULONG sizemask;
PORT_ULONG used;
void *privdata;
} dict;
@@ -113,7 +113,7 @@ typedef struct dictIterator {
/* API */
static unsigned int dictGenHashFunction(const unsigned char *buf, int len);
static dict *dictCreate(dictType *type, void *privDataPtr);
static int dictExpand(dict *ht, unsigned long size);
static int dictExpand(dict *ht, PORT_ULONG size);
static int dictAdd(dict *ht, void *key, void *val);
static int dictReplace(dict *ht, void *key, void *val);
static int dictDelete(dict *ht, const void *key);
+15 -3
View File
@@ -1,3 +1,7 @@
#ifdef _WIN32
#include "..\..\src\Win32_Interop\win32fixes.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -5,7 +9,7 @@
#include <hiredis.h>
#include <async.h>
#include <adapters/ae.h>
#include <adapters\ae.h>
/* Put event loop in the global scope, so it can be explicitly stopped */
static aeEventLoop *loop;
@@ -37,11 +41,17 @@ void disconnectCallback(const redisAsyncContext *c, int status) {
}
printf("Disconnected...\n");
aeStop(loop);
}
int main (int argc, char **argv) {
signal(SIGPIPE, SIG_IGN);
#ifndef _WIN32
signal(SIGPIPE, SIG_IGN);
#endif
#ifdef _WIN32
/* For Win32_IOCP the event loop must be created before the async connect */
loop = aeCreateEventLoop(1024 * 10);
#endif
redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
if (c->err) {
@@ -50,7 +60,9 @@ int main (int argc, char **argv) {
return 1;
}
#ifndef _WIN32
loop = aeCreateEventLoop(64);
#endif
redisAeAttach(loop, c);
redisAsyncSetConnectCallback(c,connectCallback);
redisAsyncSetDisconnectCallback(c,disconnectCallback);
+94 -33
View File
@@ -32,7 +32,9 @@
#include "fmacros.h"
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#include <assert.h>
#include <errno.h>
#include <ctype.h>
@@ -40,11 +42,15 @@
#include "hiredis.h"
#include "net.h"
#include "sds.h"
#ifdef _WIN32
#include "../../src/win32_Interop/win32_util.h"
#include "../../src/win32_Interop/win32fixes.h"
#endif
static redisReply *createReplyObject(int type);
static void *createStringObject(const redisReadTask *task, char *str, size_t len);
static void *createArrayObject(const redisReadTask *task, int elements);
static void *createIntegerObject(const redisReadTask *task, long long value);
static void *createIntegerObject(const redisReadTask *task, PORT_LONGLONG value);
static void *createNilObject(const redisReadTask *task);
/* Default set of functions to build the reply. Keep in mind that such a
@@ -116,7 +122,7 @@ static void *createStringObject(const redisReadTask *task, char *str, size_t len
memcpy(buf,str,len);
buf[len] = '\0';
r->str = buf;
r->len = len;
r->len = (int)len;
if (task->parent) {
parent = task->parent->obj;
@@ -151,7 +157,7 @@ static void *createArrayObject(const redisReadTask *task, int elements) {
return r;
}
static void *createIntegerObject(const redisReadTask *task, long long value) {
static void *createIntegerObject(const redisReadTask *task, PORT_LONGLONG value) {
redisReply *r, *parent;
r = createReplyObject(REDIS_REPLY_INTEGER);
@@ -259,7 +265,7 @@ static char *readBytes(redisReader *r, unsigned int bytes) {
/* Find pointer to \r\n. */
static char *seekNewline(char *s, size_t len) {
int pos = 0;
int _len = len-1;
int _len = (int)(len-1);
/* Position should be < len-1 because the character at "pos" should be
* followed by a \n. Note that strchr cannot be used because it doesn't
@@ -283,10 +289,10 @@ static char *seekNewline(char *s, size_t len) {
return NULL;
}
/* Read a long long value starting at *s, under the assumption that it will be
/* Read a PORT_LONGLONG value starting at *s, under the assumption that it will be
* terminated by \r\n. Ambiguously returns -1 for unexpected input. */
static long long readLongLong(char *s) {
long long v = 0;
static PORT_LONGLONG readLongLong(char *s) {
PORT_LONGLONG v = 0;
int dec, mult = 1;
char c;
@@ -319,7 +325,7 @@ static char *readLine(redisReader *r, int *_len) {
p = r->buf+r->pos;
s = seekNewline(p,(r->len-r->pos));
if (s != NULL) {
len = s-(r->buf+r->pos);
len = (int)(s-(r->buf+r->pos));
r->pos += len+2; /* skip \r\n */
if (_len) *_len = len;
return p;
@@ -390,15 +396,15 @@ static int processBulkItem(redisReader *r) {
redisReadTask *cur = &(r->rstack[r->ridx]);
void *obj = NULL;
char *p, *s;
long len;
unsigned long bytelen;
PORT_LONG len;
PORT_ULONG bytelen;
int success = 0;
p = r->buf+r->pos;
s = seekNewline(p,r->len-r->pos);
if (s != NULL) {
p = r->buf+r->pos;
bytelen = s-(r->buf+r->pos)+2; /* include \r\n */
bytelen = (int)(s-(r->buf+r->pos)+2); /* include \r\n */
len = readLongLong(p);
if (len < 0) {
@@ -410,10 +416,10 @@ static int processBulkItem(redisReader *r) {
success = 1;
} else {
/* Only continue when the buffer contains the entire bulk item. */
bytelen += len+2; /* include \r\n */
bytelen += (PORT_ULONG) len + 2; /* include \r\n */
if (r->pos+bytelen <= r->len) {
if (r->fn && r->fn->createString)
obj = r->fn->createString(cur,s+2,len);
obj = r->fn->createString(cur,s+2,(size_t)len);
else
obj = (void*)REDIS_REPLY_STRING;
success = 1;
@@ -443,7 +449,7 @@ static int processMultiBulkItem(redisReader *r) {
redisReadTask *cur = &(r->rstack[r->ridx]);
void *obj;
char *p;
long elements;
PORT_LONG elements;
int root = 0;
/* Set error for nested multi bulks with depth > 7 */
@@ -471,7 +477,7 @@ static int processMultiBulkItem(redisReader *r) {
moveToNextTask(r);
} else {
if (r->fn && r->fn->createArray)
obj = r->fn->createArray(cur,elements);
obj = r->fn->createArray(cur,(int)elements);
else
obj = (void*)REDIS_REPLY_ARRAY;
@@ -482,7 +488,7 @@ static int processMultiBulkItem(redisReader *r) {
/* Modify task stack when there are more than 0 elements. */
if (elements > 0) {
cur->elements = elements;
cur->elements = (int)elements;
cur->obj = obj;
r->ridx++;
r->rstack[r->ridx].type = -1;
@@ -650,7 +656,7 @@ int redisReaderGetReply(redisReader *r, void **reply) {
/* Discard part of the buffer when we've consumed at least 1k, to avoid
* doing unnecessary calls to memmove() in sds.c. */
if (r->pos >= 1024) {
sdsrange(r->buf,r->pos,-1);
sdsrange(r->buf,(int)(r->pos),-1);
r->pos = 0;
r->len = sdslen(r->buf);
}
@@ -680,7 +686,7 @@ static int intlen(int i) {
/* Helper that calculates the bulk length given a certain string length. */
static size_t bulklen(size_t len) {
return 1+intlen(len)+2+len+2;
return (size_t)(1+intlen((int)len)+2+(int)len+2);
}
int redisvFormatCommand(char **target, const char *format, va_list ap) {
@@ -711,7 +717,7 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
if (newargv == NULL) goto err;
curargv = newargv;
curargv[argc++] = curarg;
totlen += bulklen(sdslen(curarg));
totlen += (int)bulklen(sdslen(curarg));
/* curarg is put in argv so it can be overwritten. */
curarg = sdsempty();
@@ -807,11 +813,11 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
goto fmt_invalid;
}
/* Size: long long */
/* Size: PORT_LONGLONG */
if (_p[0] == 'l' && _p[1] == 'l') {
_p += 2;
if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
va_arg(ap,long long);
va_arg(ap,PORT_LONGLONG);
goto fmt_valid;
}
goto fmt_invalid;
@@ -821,7 +827,7 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
if (_p[0] == 'l') {
_p += 1;
if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
va_arg(ap,long);
va_arg(ap, PORT_LONG);
goto fmt_valid;
}
goto fmt_invalid;
@@ -863,7 +869,7 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
if (newargv == NULL) goto err;
curargv = newargv;
curargv[argc++] = curarg;
totlen += bulklen(sdslen(curarg));
totlen += (int)bulklen(sdslen(curarg));
} else {
sdsfree(curarg);
}
@@ -875,14 +881,14 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
totlen += 1+intlen(argc)+2;
/* Build the command at protocol level */
cmd = malloc(totlen+1);
cmd = (char *)malloc(totlen+1);
if (cmd == NULL) goto err;
pos = sprintf(cmd,"*%d\r\n",argc);
for (j = 0; j < argc; j++) {
pos += sprintf(cmd+pos,"$%zu\r\n",sdslen(curargv[j]));
pos += sprintf(cmd+pos,"$%Iu\r\n",sdslen(curargv[j])); WIN_PORT_FIX /* %zu -> %Iu */
memcpy(cmd+pos,curargv[j],sdslen(curargv[j]));
pos += sdslen(curargv[j]);
pos += (int)sdslen(curargv[j]);
sdsfree(curargv[j]);
cmd[pos++] = '\r';
cmd[pos++] = '\n';
@@ -946,7 +952,7 @@ int redisFormatCommandArgv(char **target, int argc, const char **argv, const siz
totlen = 1+intlen(argc)+2;
for (j = 0; j < argc; j++) {
len = argvlen ? argvlen[j] : strlen(argv[j]);
totlen += bulklen(len);
totlen += (int)bulklen(len);
}
/* Build the command at protocol level */
@@ -957,9 +963,9 @@ int redisFormatCommandArgv(char **target, int argc, const char **argv, const siz
pos = sprintf(cmd,"*%d\r\n",argc);
for (j = 0; j < argc; j++) {
len = argvlen ? argvlen[j] : strlen(argv[j]);
pos += sprintf(cmd+pos,"$%zu\r\n",len);
pos += sprintf(cmd+pos,"$%Iu\r\n",len); WIN_PORT_FIX /* %zu -> %Iu */
memcpy(cmd+pos,argv[j],len);
pos += len;
pos += (int)len;
cmd[pos++] = '\r';
cmd[pos++] = '\n';
}
@@ -1001,8 +1007,9 @@ static redisContext *redisContextInit(void) {
}
void redisFree(redisContext *c) {
if (c->fd > 0)
if (c->fd > 0) {
close(c->fd);
}
if (c->obuf != NULL)
sdsfree(c->obuf);
if (c->reader != NULL)
@@ -1112,6 +1119,16 @@ redisContext *redisConnectFd(int fd) {
return c;
}
#ifdef _WIN32
redisContext *redisPreConnectNonBlock(const char *ip, int port, SOCKADDR_STORAGE *ss) {
redisContext *c = redisContextInit();
c->fd = -1;
c->flags &= ~REDIS_BLOCK;
redisContextPreConnectTcp(c, ip, port, NULL, ss);
return c;
}
#endif
/* Set read/write timeout on a blocking socket. */
int redisSetTimeout(redisContext *c, const struct timeval tv) {
if (c->flags & REDIS_BLOCK)
@@ -1139,7 +1156,7 @@ int redisBufferRead(redisContext *c) {
if (c->err)
return REDIS_ERR;
nread = read(c->fd,buf,sizeof(buf));
nread = (int)read(c->fd,buf,sizeof(buf)); /* UPSTREAM_ISSUE: missing (int) cast */
if (nread == -1) {
if ((errno == EAGAIN && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) {
/* Try again later */
@@ -1159,6 +1176,33 @@ int redisBufferRead(redisContext *c) {
return REDIS_OK;
}
#ifdef _WIN32
/* Use this function if the caller has already read the data. It will
* feed bytes to the reply parser.
*
* After this function is called, you may use redisContextReadReply to
* see if there is a reply available. */
int redisBufferReadDone(redisContext *c, char *buf, ssize_t nread) {
if (nread == -1) {
if (errno == EAGAIN && !(c->flags & REDIS_BLOCK)) {
/* Try again later */
} else {
__redisSetError(c,REDIS_ERR_IO,NULL);
return REDIS_ERR;
}
} else if (nread == 0) {
__redisSetError(c,REDIS_ERR_EOF, sdsnew("Server closed the connection"));
return REDIS_ERR;
} else {
if (redisReaderFeed(c->reader,buf,nread) != REDIS_OK) {
__redisSetError(c,c->reader->err,c->reader->errstr);
return REDIS_ERR;
}
}
return REDIS_OK;
}
#endif
/* Write the output buffer to the socket.
*
* Returns REDIS_OK when the buffer is empty, or (a part of) the buffer was
@@ -1176,7 +1220,7 @@ int redisBufferWrite(redisContext *c, int *done) {
return REDIS_ERR;
if (sdslen(c->obuf) > 0) {
nwritten = write(c->fd,c->obuf,sdslen(c->obuf));
nwritten = (int)write(c->fd,c->obuf,sdslen(c->obuf)); /* UPSTREAM_ISSUE: missing (int) cast */
if (nwritten == -1) {
if ((errno == EAGAIN && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) {
/* Try again later */
@@ -1197,6 +1241,23 @@ int redisBufferWrite(redisContext *c, int *done) {
return REDIS_OK;
}
#ifdef _WIN32
/* Use this function if the caller has already written the data.
*/
int redisBufferWriteDone(redisContext *c, int nwritten, int *done) {
if (nwritten > 0) {
if (nwritten == (signed)sdslen(c->obuf)) {
sdsfree(c->obuf);
c->obuf = sdsempty();
} else {
sdsrange(c->obuf, nwritten, -1);
}
}
if (done != NULL) *done = (sdslen(c->obuf) == 0);
return REDIS_OK;
}
#endif
/* Internal helper function to try and get a reply from the reader,
* or set an error in the context otherwise. */
int redisGetReplyFromReader(redisContext *c, void **reply) {
+17 -2
View File
@@ -33,7 +33,17 @@
#define __HIREDIS_H
#include <stdio.h> /* for size_t */
#include <stdarg.h> /* for va_list */
#ifndef _WIN32
#include <sys/time.h> /* for struct timeval */
#endif
#ifdef _WIN32
#include "..\..\src\win32_Interop\Win32_FDAPI.h"
#include <windows.h>
#ifndef va_copy
#define va_copy(d,s) d = (s)
#endif
#endif
#define HIREDIS_MAJOR 0
#define HIREDIS_MINOR 11
@@ -97,7 +107,7 @@ extern "C" {
/* This is the reply object returned by redisCommand() */
typedef struct redisReply {
int type; /* REDIS_REPLY_* */
long long integer; /* The integer when type is REDIS_REPLY_INTEGER */
PORT_LONGLONG integer; /* The integer when type is REDIS_REPLY_INTEGER */
int len; /* Length of string */
char *str; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */
size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */
@@ -116,7 +126,7 @@ typedef struct redisReadTask {
typedef struct redisReplyObjectFunctions {
void *(*createString)(const redisReadTask*, char*, size_t);
void *(*createArray)(const redisReadTask*, int);
void *(*createInteger)(const redisReadTask*, long long);
void *(*createInteger)(const redisReadTask*, PORT_LONGLONG);
void *(*createNil)(const redisReadTask*);
void (*freeObject)(void*);
} redisReplyObjectFunctions;
@@ -186,6 +196,11 @@ void redisFree(redisContext *c);
int redisFreeKeepFd(redisContext *c);
int redisBufferRead(redisContext *c);
int redisBufferWrite(redisContext *c, int *done);
#ifdef _WIN32
redisContext *redisPreConnectNonBlock(const char *ip, int port, SOCKADDR_STORAGE *sa);
int redisBufferReadDone(redisContext *c, char *buf, ssize_t nread);
int redisBufferWriteDone(redisContext *c, int nwritten, int *done);
#endif
/* In a blocking context, this function first checks if there are unconsumed
* replies to return and returns one if so. Otherwise, it flushes the output
+78 -4
View File
@@ -32,6 +32,7 @@
#include "fmacros.h"
#include <sys/types.h>
#ifndef _WIN32
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/un.h>
@@ -39,17 +40,28 @@
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#endif
#include <fcntl.h>
#include <string.h>
#ifndef _WIN32
#include <netdb.h>
#endif
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#ifndef _WIN32
#include <poll.h>
#endif
#include <limits.h>
#include "net.h"
#include "sds.h"
#ifdef _WIN32
#include "../../src/win32_Interop/win32_util.h"
#include "../../src/win32_Interop/win32fixes.h"
#include "mstcpip.h"
#endif
/* Defined in hiredis.c */
void __redisSetError(redisContext *c, int type, const char *str);
@@ -102,7 +114,7 @@ static int redisSetBlocking(redisContext *c, int blocking) {
/* Set the socket nonblocking.
* Note that fcntl(2) for F_GETFL and F_SETFL can't be
* interrupted by a signal. */
if ((flags = fcntl(c->fd, F_GETFL)) == -1) {
if ((flags = fcntl(c->fd, F_GETFL,0)) == -1) {
__redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_GETFL)");
redisContextCloseFd(c);
return REDIS_ERR;
@@ -139,6 +151,27 @@ int redisKeepAlive(redisContext *c, int interval) {
}
#else
#ifndef __sun
#ifdef _WIN32
{
struct tcp_keepalive settings;
DWORD bytesReturned;
WSAOVERLAPPED overlapped;
settings.onoff = 1;
settings.keepalivetime = interval*1000;
settings.keepaliveinterval = interval*1000/3;
overlapped.hEvent = NULL;
WSAIoctl(
fd,
SIO_KEEPALIVE_VALS,
&settings,
sizeof(struct tcp_keepalive),
NULL,
0,
&bytesReturned,
&overlapped,
NULL);
}
#else
val = interval;
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < 0) {
__redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
@@ -158,6 +191,7 @@ int redisKeepAlive(redisContext *c, int interval) {
return REDIS_ERR;
}
#endif
#endif
#endif
return REDIS_OK;
@@ -177,7 +211,7 @@ static int redisSetTcpNoDelay(redisContext *c) {
static int redisContextWaitReady(redisContext *c, const struct timeval *timeout) {
struct pollfd wfd[1];
long msec;
PORT_LONG msec;
msec = -1;
wfd[0].fd = c->fd;
@@ -201,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;
@@ -253,6 +287,36 @@ int redisContextSetTimeout(redisContext *c, const struct timeval tv) {
return REDIS_OK;
}
#ifdef _WIN32
int redisContextPreConnectTcp(
redisContext *c,
const char *addr,
int port,
struct timeval *timeout,
SOCKADDR_STORAGE* ss) {
int blocking = (c->flags & REDIS_BLOCK);
if (ParseStorageAddress(addr, port, ss) == FALSE) {
DebugBreak();
}
if (REDIS_OK != redisCreateSocket(c, ss->ss_family)) {
return REDIS_ERR;
}
if (redisSetTcpNoDelay(c) != REDIS_OK)
return REDIS_ERR;
if (blocking == 0) {
if (redisSetBlocking(c, 0) != REDIS_OK)
return REDIS_ERR;
}
return REDIS_OK;
}
#endif
static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
const struct timeval *timeout,
const char *source_addr) {
@@ -295,7 +359,7 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
goto error;
}
for (b = bservinfo; b != NULL; b = b->ai_next) {
if (bind(s,b->ai_addr,b->ai_addrlen) != -1) {
if (bind(s,b->ai_addr,(socklen_t)b->ai_addrlen) != -1) {
bound = 1;
break;
}
@@ -353,6 +417,15 @@ int redisContextConnectBindTcp(redisContext *c, const char *addr, int port,
return _redisContextConnectTcp(c, addr, port, timeout, source_addr);
}
#ifdef _WIN32
int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout) {
(void) timeout;
__redisSetError(c,REDIS_ERR_IO,
sdscatprintf(sdsempty(),"Unix sockets are not suported on Windows platform. (%s)\n", path));
return REDIS_ERR;
}
#else
int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout) {
int blocking = (c->flags & REDIS_BLOCK);
struct sockaddr_un sa;
@@ -380,3 +453,4 @@ int redisContextConnectUnix(redisContext *c, const char *path, const struct time
c->flags |= REDIS_CONNECTED;
return REDIS_OK;
}
#endif
+4
View File
@@ -48,4 +48,8 @@ int redisContextConnectBindTcp(redisContext *c, const char *addr, int port,
int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout);
int redisKeepAlive(redisContext *c, int interval);
#ifdef _WIN32
int redisContextPreConnectTcp(redisContext *c, const char *addr, int port, struct timeval *timeout, SOCKADDR_STORAGE *ss);
#endif
#endif
+35 -35
View File
@@ -57,7 +57,7 @@ sds sdsnewlen(const void *init, size_t initlen) {
sh = zcalloc(sizeof(struct sdshdr)+initlen+1);
}
if (sh == NULL) return NULL;
sh->len = initlen;
sh->len = (int)initlen;
sh->free = 0;
if (initlen && init)
memcpy(sh->buf, init, initlen);
@@ -104,7 +104,7 @@ void sdsfree(sds s) {
* remains 6 bytes. */
void sdsupdatelen(sds s) {
struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
int reallen = strlen(s);
int reallen = (int)strlen(s);
sh->free += (sh->len-reallen);
sh->len = reallen;
}
@@ -142,7 +142,7 @@ sds sdsMakeRoomFor(sds s, size_t addlen) {
newsh = zrealloc(sh, sizeof(struct sdshdr)+newlen+1);
if (newsh == NULL) return NULL;
newsh->free = newlen - len;
newsh->free = (int)(newlen - len);
return newsh->buf;
}
@@ -226,8 +226,8 @@ sds sdsgrowzero(sds s, size_t len) {
sh = (void*)(s-(sizeof(struct sdshdr)));
memset(s+curlen,0,(len-curlen+1)); /* also set trailing \0 byte */
totlen = sh->len+sh->free;
sh->len = len;
sh->free = totlen-sh->len;
sh->len = (int)len;
sh->free = (int)(totlen-sh->len);
return s;
}
@@ -244,8 +244,8 @@ sds sdscatlen(sds s, const void *t, size_t len) {
if (s == NULL) return NULL;
sh = (void*) (s-(sizeof(struct sdshdr)));
memcpy(s+curlen, t, len);
sh->len = curlen+len;
sh->free = sh->free-len;
sh->len = (int)(curlen+len);
sh->free = (int)(sh->free-len);
s[curlen+len] = '\0';
return s;
}
@@ -280,8 +280,8 @@ sds sdscpylen(sds s, const char *t, size_t len) {
}
memcpy(s, t, len);
s[len] = '\0';
sh->len = len;
sh->free = totlen-len;
sh->len = (int)len;
sh->free = (int)(totlen-len);
return s;
}
@@ -298,9 +298,9 @@ sds sdscpy(sds s, const char *t) {
* The function returns the lenght of the null-terminated string
* representation stored at 's'. */
#define SDS_LLSTR_SIZE 21
int sdsll2str(char *s, long long value) {
int sdsll2str(char *s, PORT_LONGLONG value) {
char *p, aux;
unsigned long long v;
PORT_ULONGLONG v;
size_t l;
/* Generate the string representation, this method produces
@@ -326,11 +326,11 @@ int sdsll2str(char *s, long long value) {
s++;
p--;
}
return l;
return (int)l;
}
/* Identical sdsll2str(), but for unsigned long long type. */
int sdsull2str(char *s, unsigned long long v) {
/* Identical sdsll2str(), but for PORT_ULONGLONG type. */
int sdsull2str(char *s, PORT_ULONGLONG v) {
char *p, aux;
size_t l;
@@ -355,14 +355,14 @@ int sdsull2str(char *s, unsigned long long v) {
s++;
p--;
}
return l;
return (int)l;
}
/* Create an sds string from a long long value. It is much faster than:
/* Create an sds string from a PORT_LONGLONG value. It is much faster than:
*
* sdscatprintf(sdsempty(),"%lld\n", value);
*/
sds sdsfromlonglong(long long value) {
sds sdsfromlonglong(PORT_LONGLONG value) {
char buf[SDS_LLSTR_SIZE];
int len = sdsll2str(buf,value);
@@ -443,9 +443,9 @@ sds sdscatprintf(sds s, const char *fmt, ...) {
* %s - C String
* %S - SDS string
* %i - signed int
* %I - 64 bit signed integer (long long, int64_t)
* %I - 64 bit signed integer (PORT_LONGLONG, int64_t)
* %u - unsigned int
* %U - 64 bit unsigned integer (unsigned long long, uint64_t)
* %U - 64 bit unsigned integer (PORT_ULONGLONG, uint64_t)
* %% - Verbatim "%" character.
*/
sds sdscatfmt(sds s, char const *fmt, ...) {
@@ -457,12 +457,12 @@ sds sdscatfmt(sds s, char const *fmt, ...) {
va_start(ap,fmt);
f = fmt; /* Next format specifier byte to process. */
i = initlen; /* Position of the next byte to write to dest str. */
i = (int)initlen; /* Position of the next byte to write to dest str. */
while(*f) {
char next, *str;
unsigned int l;
long long num;
unsigned long long unum;
PORT_LONGLONG num;
PORT_ULONGLONG unum;
/* Make sure there is always space for at least 1 char. */
if (sh->free == 0) {
@@ -478,7 +478,7 @@ sds sdscatfmt(sds s, char const *fmt, ...) {
case 's':
case 'S':
str = va_arg(ap,char*);
l = (next == 's') ? strlen(str) : sdslen(str);
l = (int)((next == 's') ? strlen(str) : sdslen(str));
if (sh->free < l) {
s = sdsMakeRoomFor(s,l);
sh = (void*) (s-(sizeof(struct sdshdr)));
@@ -493,7 +493,7 @@ sds sdscatfmt(sds s, char const *fmt, ...) {
if (next == 'i')
num = va_arg(ap,int);
else
num = va_arg(ap,long long);
num = va_arg(ap,PORT_LONGLONG);
{
char buf[SDS_LLSTR_SIZE];
l = sdsll2str(buf,num);
@@ -512,7 +512,7 @@ sds sdscatfmt(sds s, char const *fmt, ...) {
if (next == 'u')
unum = va_arg(ap,unsigned int);
else
unum = va_arg(ap,unsigned long long);
unum = va_arg(ap,PORT_ULONGLONG);
{
char buf[SDS_LLSTR_SIZE];
l = sdsull2str(buf,unum);
@@ -574,8 +574,8 @@ sds sdstrim(sds s, const char *cset) {
len = (sp > ep) ? 0 : ((ep-sp)+1);
if (sh->buf != sp) memmove(sh->buf, sp, len);
sh->buf[len] = '\0';
sh->free = sh->free+(sh->len-len);
sh->len = len;
sh->free = (int)(sh->free+(sh->len-len));
sh->len = (int)len;
return s;
}
@@ -601,11 +601,11 @@ void sdsrange(sds s, int start, int end) {
if (len == 0) return;
if (start < 0) {
start = len+start;
start = (int)(len+start);
if (start < 0) start = 0;
}
if (end < 0) {
end = len+end;
end = (int)(len+end);
if (end < 0) end = 0;
}
newlen = (start > end) ? 0 : (end-start)+1;
@@ -613,7 +613,7 @@ void sdsrange(sds s, int start, int end) {
if (start >= (signed)len) {
newlen = 0;
} else if (end >= (signed)len) {
end = len-1;
end = (int)(len-1);
newlen = (start > end) ? 0 : (end-start)+1;
}
} else {
@@ -621,20 +621,20 @@ void sdsrange(sds s, int start, int end) {
}
if (start && newlen) memmove(sh->buf, sh->buf+start, newlen);
sh->buf[newlen] = 0;
sh->free = sh->free+(sh->len-newlen);
sh->len = newlen;
sh->free = (int)(sh->free+(sh->len-newlen));
sh->len = (int)newlen;
}
/* Apply tolower() to every character of the sds string 's'. */
void sdstolower(sds s) {
int len = sdslen(s), j;
int len = (int)sdslen(s), j;
for (j = 0; j < len; j++) s[j] = tolower(s[j]);
}
/* Apply toupper() to every character of the sds string 's'. */
void sdstoupper(sds s) {
int len = sdslen(s), j;
int len = (int)sdslen(s), j;
for (j = 0; j < len; j++) s[j] = toupper(s[j]);
}
@@ -658,7 +658,7 @@ int sdscmp(const sds s1, const sds s2) {
l2 = sdslen(s2);
minlen = (l1 < l2) ? l1 : l2;
cmp = memcmp(s1,s2,minlen);
if (cmp == 0) return l1-l2;
if (cmp == 0) return (int)(l1-l2);
return cmp;
}
+10 -3
View File
@@ -33,9 +33,16 @@
#define SDS_MAX_PREALLOC (1024*1024)
#ifdef _WIN32
#include "../../src/win32_Interop/win32_types.h"
#endif
#include <sys/types.h>
#include <stdarg.h>
#ifdef _WIN32
#define inline __inline
#endif
typedef char *sds;
struct sdshdr {
@@ -45,12 +52,12 @@ struct sdshdr {
};
static inline size_t sdslen(const sds s) {
struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
struct sdshdr *sh = (struct sdshdr *)(s-(sizeof(struct sdshdr)));
return sh->len;
}
static inline size_t sdsavail(const sds s) {
struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
struct sdshdr *sh = (struct sdshdr *)(s-(sizeof(struct sdshdr)));
return sh->free;
}
@@ -86,7 +93,7 @@ sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count
void sdsfreesplitres(sds *tokens, int count);
void sdstolower(sds s);
void sdstoupper(sds s);
sds sdsfromlonglong(long long value);
sds sdsfromlonglong(PORT_LONGLONG value);
sds sdscatrepr(sds s, const char *p, size_t len);
sds *sdssplitargs(const char *line, int *argc);
sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen);
+1 -1
View File
@@ -51,7 +51,7 @@ static redisContext *select_database(redisContext *c) {
assert(reply != NULL);
freeReplyObject(reply);
/* Make sure the DB is emtpy */
/* Make sure the DB is empty */
reply = redisCommand(c,"DBSIZE");
assert(reply != NULL);
if (reply->type == REDIS_REPLY_INTEGER && reply->integer == 0) {
-17
View File
@@ -1,17 +0,0 @@
#!/bin/sh
for i in autoconf; do
echo "$i"
$i
if [ $? -ne 0 ]; then
echo "Error $? in $i"
exit 1
fi
done
echo "./configure --enable-autogen $@"
./configure --enable-autogen $@
if [ $? -ne 0 ]; then
echo "Error $? in ./configure"
exit 1
fi
-9
View File
@@ -1,9 +0,0 @@
#!/bin/sh
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
@LD_PRELOAD_VAR@=${libdir}/libjemalloc.@SOREV@
export @LD_PRELOAD_VAR@
exec "$@"
View File
-4
View File
@@ -1,4 +0,0 @@
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:import href="@XSLROOT@/html/docbook.xsl"/>
<xsl:import href="@abs_srcroot@doc/stylesheet.xsl"/>
</xsl:stylesheet>
-4
View File
@@ -1,4 +0,0 @@
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:import href="@XSLROOT@/manpages/docbook.xsl"/>
<xsl:import href="@abs_srcroot@doc/stylesheet.xsl"/>
</xsl:stylesheet>
-7
View File
@@ -1,7 +0,0 @@
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="funcsynopsis.style">ansi</xsl:param>
<xsl:param name="function.parens" select="1"/>
<xsl:template match="mallctl">
"<xsl:call-template name="inline.monoseq"/>"
</xsl:template>
</xsl:stylesheet>
-304
View File
@@ -1,304 +0,0 @@
/******************************************************************************/
#ifdef JEMALLOC_H_TYPES
#endif /* JEMALLOC_H_TYPES */
/******************************************************************************/
#ifdef JEMALLOC_H_STRUCTS
#endif /* JEMALLOC_H_STRUCTS */
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
#define atomic_read_uint64(p) atomic_add_uint64(p, 0)
#define atomic_read_uint32(p) atomic_add_uint32(p, 0)
#define atomic_read_z(p) atomic_add_z(p, 0)
#define atomic_read_u(p) atomic_add_u(p, 0)
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
#ifdef JEMALLOC_H_INLINES
#ifndef JEMALLOC_ENABLE_INLINE
uint64_t atomic_add_uint64(uint64_t *p, uint64_t x);
uint64_t atomic_sub_uint64(uint64_t *p, uint64_t x);
uint32_t atomic_add_uint32(uint32_t *p, uint32_t x);
uint32_t atomic_sub_uint32(uint32_t *p, uint32_t x);
size_t atomic_add_z(size_t *p, size_t x);
size_t atomic_sub_z(size_t *p, size_t x);
unsigned atomic_add_u(unsigned *p, unsigned x);
unsigned atomic_sub_u(unsigned *p, unsigned x);
#endif
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_ATOMIC_C_))
/******************************************************************************/
/* 64-bit operations. */
#if (LG_SIZEOF_PTR == 3 || LG_SIZEOF_INT == 3)
# ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
JEMALLOC_INLINE uint64_t
atomic_add_uint64(uint64_t *p, uint64_t x)
{
return (__sync_add_and_fetch(p, x));
}
JEMALLOC_INLINE uint64_t
atomic_sub_uint64(uint64_t *p, uint64_t x)
{
return (__sync_sub_and_fetch(p, x));
}
#elif (defined(_MSC_VER))
JEMALLOC_INLINE uint64_t
atomic_add_uint64(uint64_t *p, uint64_t x)
{
return (InterlockedExchangeAdd64(p, x));
}
JEMALLOC_INLINE uint64_t
atomic_sub_uint64(uint64_t *p, uint64_t x)
{
return (InterlockedExchangeAdd64(p, -((int64_t)x)));
}
#elif (defined(JEMALLOC_OSATOMIC))
JEMALLOC_INLINE uint64_t
atomic_add_uint64(uint64_t *p, uint64_t x)
{
return (OSAtomicAdd64((int64_t)x, (int64_t *)p));
}
JEMALLOC_INLINE uint64_t
atomic_sub_uint64(uint64_t *p, uint64_t x)
{
return (OSAtomicAdd64(-((int64_t)x), (int64_t *)p));
}
# elif (defined(__amd64__) || defined(__x86_64__))
JEMALLOC_INLINE uint64_t
atomic_add_uint64(uint64_t *p, uint64_t x)
{
asm volatile (
"lock; xaddq %0, %1;"
: "+r" (x), "=m" (*p) /* Outputs. */
: "m" (*p) /* Inputs. */
);
return (x);
}
JEMALLOC_INLINE uint64_t
atomic_sub_uint64(uint64_t *p, uint64_t x)
{
x = (uint64_t)(-(int64_t)x);
asm volatile (
"lock; xaddq %0, %1;"
: "+r" (x), "=m" (*p) /* Outputs. */
: "m" (*p) /* Inputs. */
);
return (x);
}
# elif (defined(JEMALLOC_ATOMIC9))
JEMALLOC_INLINE uint64_t
atomic_add_uint64(uint64_t *p, uint64_t x)
{
/*
* atomic_fetchadd_64() doesn't exist, but we only ever use this
* function on LP64 systems, so atomic_fetchadd_long() will do.
*/
assert(sizeof(uint64_t) == sizeof(unsigned long));
return (atomic_fetchadd_long(p, (unsigned long)x) + x);
}
JEMALLOC_INLINE uint64_t
atomic_sub_uint64(uint64_t *p, uint64_t x)
{
assert(sizeof(uint64_t) == sizeof(unsigned long));
return (atomic_fetchadd_long(p, (unsigned long)(-(long)x)) - x);
}
# elif (defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_8))
JEMALLOC_INLINE uint64_t
atomic_add_uint64(uint64_t *p, uint64_t x)
{
return (__sync_add_and_fetch(p, x));
}
JEMALLOC_INLINE uint64_t
atomic_sub_uint64(uint64_t *p, uint64_t x)
{
return (__sync_sub_and_fetch(p, x));
}
# else
# error "Missing implementation for 64-bit atomic operations"
# endif
#endif
/******************************************************************************/
/* 32-bit operations. */
#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
JEMALLOC_INLINE uint32_t
atomic_add_uint32(uint32_t *p, uint32_t x)
{
return (__sync_add_and_fetch(p, x));
}
JEMALLOC_INLINE uint32_t
atomic_sub_uint32(uint32_t *p, uint32_t x)
{
return (__sync_sub_and_fetch(p, x));
}
#elif (defined(_MSC_VER))
JEMALLOC_INLINE uint32_t
atomic_add_uint32(uint32_t *p, uint32_t x)
{
return (InterlockedExchangeAdd(p, x));
}
JEMALLOC_INLINE uint32_t
atomic_sub_uint32(uint32_t *p, uint32_t x)
{
return (InterlockedExchangeAdd(p, -((int32_t)x)));
}
#elif (defined(JEMALLOC_OSATOMIC))
JEMALLOC_INLINE uint32_t
atomic_add_uint32(uint32_t *p, uint32_t x)
{
return (OSAtomicAdd32((int32_t)x, (int32_t *)p));
}
JEMALLOC_INLINE uint32_t
atomic_sub_uint32(uint32_t *p, uint32_t x)
{
return (OSAtomicAdd32(-((int32_t)x), (int32_t *)p));
}
#elif (defined(__i386__) || defined(__amd64__) || defined(__x86_64__))
JEMALLOC_INLINE uint32_t
atomic_add_uint32(uint32_t *p, uint32_t x)
{
asm volatile (
"lock; xaddl %0, %1;"
: "+r" (x), "=m" (*p) /* Outputs. */
: "m" (*p) /* Inputs. */
);
return (x);
}
JEMALLOC_INLINE uint32_t
atomic_sub_uint32(uint32_t *p, uint32_t x)
{
x = (uint32_t)(-(int32_t)x);
asm volatile (
"lock; xaddl %0, %1;"
: "+r" (x), "=m" (*p) /* Outputs. */
: "m" (*p) /* Inputs. */
);
return (x);
}
#elif (defined(JEMALLOC_ATOMIC9))
JEMALLOC_INLINE uint32_t
atomic_add_uint32(uint32_t *p, uint32_t x)
{
return (atomic_fetchadd_32(p, x) + x);
}
JEMALLOC_INLINE uint32_t
atomic_sub_uint32(uint32_t *p, uint32_t x)
{
return (atomic_fetchadd_32(p, (uint32_t)(-(int32_t)x)) - x);
}
#elif (defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_4))
JEMALLOC_INLINE uint32_t
atomic_add_uint32(uint32_t *p, uint32_t x)
{
return (__sync_add_and_fetch(p, x));
}
JEMALLOC_INLINE uint32_t
atomic_sub_uint32(uint32_t *p, uint32_t x)
{
return (__sync_sub_and_fetch(p, x));
}
#else
# error "Missing implementation for 32-bit atomic operations"
#endif
/******************************************************************************/
/* size_t operations. */
JEMALLOC_INLINE size_t
atomic_add_z(size_t *p, size_t x)
{
#if (LG_SIZEOF_PTR == 3)
return ((size_t)atomic_add_uint64((uint64_t *)p, (uint64_t)x));
#elif (LG_SIZEOF_PTR == 2)
return ((size_t)atomic_add_uint32((uint32_t *)p, (uint32_t)x));
#endif
}
JEMALLOC_INLINE size_t
atomic_sub_z(size_t *p, size_t x)
{
#if (LG_SIZEOF_PTR == 3)
return ((size_t)atomic_add_uint64((uint64_t *)p,
(uint64_t)-((int64_t)x)));
#elif (LG_SIZEOF_PTR == 2)
return ((size_t)atomic_add_uint32((uint32_t *)p,
(uint32_t)-((int32_t)x)));
#endif
}
/******************************************************************************/
/* unsigned operations. */
JEMALLOC_INLINE unsigned
atomic_add_u(unsigned *p, unsigned x)
{
#if (LG_SIZEOF_INT == 3)
return ((unsigned)atomic_add_uint64((uint64_t *)p, (uint64_t)x));
#elif (LG_SIZEOF_INT == 2)
return ((unsigned)atomic_add_uint32((uint32_t *)p, (uint32_t)x));
#endif
}
JEMALLOC_INLINE unsigned
atomic_sub_u(unsigned *p, unsigned x)
{
#if (LG_SIZEOF_INT == 3)
return ((unsigned)atomic_add_uint64((uint64_t *)p,
(uint64_t)-((int64_t)x)));
#elif (LG_SIZEOF_INT == 2)
return ((unsigned)atomic_add_uint32((uint32_t *)p,
(uint32_t)-((int32_t)x)));
#endif
}
/******************************************************************************/
#endif
#endif /* JEMALLOC_H_INLINES */
/******************************************************************************/
-26
View File
@@ -1,26 +0,0 @@
/******************************************************************************/
#ifdef JEMALLOC_H_TYPES
#endif /* JEMALLOC_H_TYPES */
/******************************************************************************/
#ifdef JEMALLOC_H_STRUCTS
#endif /* JEMALLOC_H_STRUCTS */
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
void *base_alloc(size_t size);
void *base_calloc(size_t number, size_t size);
extent_node_t *base_node_alloc(void);
void base_node_dealloc(extent_node_t *node);
bool base_boot(void);
void base_prefork(void);
void base_postfork_parent(void);
void base_postfork_child(void);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
#ifdef JEMALLOC_H_INLINES
#endif /* JEMALLOC_H_INLINES */
/******************************************************************************/
-184
View File
@@ -1,184 +0,0 @@
/******************************************************************************/
#ifdef JEMALLOC_H_TYPES
/* Maximum bitmap bit count is 2^LG_BITMAP_MAXBITS. */
#define LG_BITMAP_MAXBITS LG_RUN_MAXREGS
typedef struct bitmap_level_s bitmap_level_t;
typedef struct bitmap_info_s bitmap_info_t;
typedef unsigned long bitmap_t;
#define LG_SIZEOF_BITMAP LG_SIZEOF_LONG
/* Number of bits per group. */
#define LG_BITMAP_GROUP_NBITS (LG_SIZEOF_BITMAP + 3)
#define BITMAP_GROUP_NBITS (ZU(1) << LG_BITMAP_GROUP_NBITS)
#define BITMAP_GROUP_NBITS_MASK (BITMAP_GROUP_NBITS-1)
/* Maximum number of levels possible. */
#define BITMAP_MAX_LEVELS \
(LG_BITMAP_MAXBITS / LG_SIZEOF_BITMAP) \
+ !!(LG_BITMAP_MAXBITS % LG_SIZEOF_BITMAP)
#endif /* JEMALLOC_H_TYPES */
/******************************************************************************/
#ifdef JEMALLOC_H_STRUCTS
struct bitmap_level_s {
/* Offset of this level's groups within the array of groups. */
size_t group_offset;
};
struct bitmap_info_s {
/* Logical number of bits in bitmap (stored at bottom level). */
size_t nbits;
/* Number of levels necessary for nbits. */
unsigned nlevels;
/*
* Only the first (nlevels+1) elements are used, and levels are ordered
* bottom to top (e.g. the bottom level is stored in levels[0]).
*/
bitmap_level_t levels[BITMAP_MAX_LEVELS+1];
};
#endif /* JEMALLOC_H_STRUCTS */
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
void bitmap_info_init(bitmap_info_t *binfo, size_t nbits);
size_t bitmap_info_ngroups(const bitmap_info_t *binfo);
size_t bitmap_size(size_t nbits);
void bitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
#ifdef JEMALLOC_H_INLINES
#ifndef JEMALLOC_ENABLE_INLINE
bool bitmap_full(bitmap_t *bitmap, const bitmap_info_t *binfo);
bool bitmap_get(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit);
void bitmap_set(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit);
size_t bitmap_sfu(bitmap_t *bitmap, const bitmap_info_t *binfo);
void bitmap_unset(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit);
#endif
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_BITMAP_C_))
JEMALLOC_INLINE bool
bitmap_full(bitmap_t *bitmap, const bitmap_info_t *binfo)
{
unsigned rgoff = binfo->levels[binfo->nlevels].group_offset - 1;
bitmap_t rg = bitmap[rgoff];
/* The bitmap is full iff the root group is 0. */
return (rg == 0);
}
JEMALLOC_INLINE bool
bitmap_get(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit)
{
size_t goff;
bitmap_t g;
assert(bit < binfo->nbits);
goff = bit >> LG_BITMAP_GROUP_NBITS;
g = bitmap[goff];
return (!(g & (1LU << (bit & BITMAP_GROUP_NBITS_MASK))));
}
JEMALLOC_INLINE void
bitmap_set(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit)
{
size_t goff;
bitmap_t *gp;
bitmap_t g;
assert(bit < binfo->nbits);
assert(bitmap_get(bitmap, binfo, bit) == false);
goff = bit >> LG_BITMAP_GROUP_NBITS;
gp = &bitmap[goff];
g = *gp;
assert(g & (1LU << (bit & BITMAP_GROUP_NBITS_MASK)));
g ^= 1LU << (bit & BITMAP_GROUP_NBITS_MASK);
*gp = g;
assert(bitmap_get(bitmap, binfo, bit));
/* Propagate group state transitions up the tree. */
if (g == 0) {
unsigned i;
for (i = 1; i < binfo->nlevels; i++) {
bit = goff;
goff = bit >> LG_BITMAP_GROUP_NBITS;
gp = &bitmap[binfo->levels[i].group_offset + goff];
g = *gp;
assert(g & (1LU << (bit & BITMAP_GROUP_NBITS_MASK)));
g ^= 1LU << (bit & BITMAP_GROUP_NBITS_MASK);
*gp = g;
if (g != 0)
break;
}
}
}
/* sfu: set first unset. */
JEMALLOC_INLINE size_t
bitmap_sfu(bitmap_t *bitmap, const bitmap_info_t *binfo)
{
size_t bit;
bitmap_t g;
unsigned i;
assert(bitmap_full(bitmap, binfo) == false);
i = binfo->nlevels - 1;
g = bitmap[binfo->levels[i].group_offset];
bit = ffsl(g) - 1;
while (i > 0) {
i--;
g = bitmap[binfo->levels[i].group_offset + bit];
bit = (bit << LG_BITMAP_GROUP_NBITS) + (ffsl(g) - 1);
}
bitmap_set(bitmap, binfo, bit);
return (bit);
}
JEMALLOC_INLINE void
bitmap_unset(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit)
{
size_t goff;
bitmap_t *gp;
bitmap_t g;
bool propagate;
assert(bit < binfo->nbits);
assert(bitmap_get(bitmap, binfo, bit));
goff = bit >> LG_BITMAP_GROUP_NBITS;
gp = &bitmap[goff];
g = *gp;
propagate = (g == 0);
assert((g & (1LU << (bit & BITMAP_GROUP_NBITS_MASK))) == 0);
g ^= 1LU << (bit & BITMAP_GROUP_NBITS_MASK);
*gp = g;
assert(bitmap_get(bitmap, binfo, bit) == false);
/* Propagate group state transitions up the tree. */
if (propagate) {
unsigned i;
for (i = 1; i < binfo->nlevels; i++) {
bit = goff;
goff = bit >> LG_BITMAP_GROUP_NBITS;
gp = &bitmap[binfo->levels[i].group_offset + goff];
g = *gp;
propagate = (g == 0);
assert((g & (1LU << (bit & BITMAP_GROUP_NBITS_MASK)))
== 0);
g ^= 1LU << (bit & BITMAP_GROUP_NBITS_MASK);
*gp = g;
if (propagate == false)
break;
}
}
}
#endif
#endif /* JEMALLOC_H_INLINES */
/******************************************************************************/
-115
View File
@@ -1,115 +0,0 @@
/******************************************************************************/
#ifdef JEMALLOC_H_TYPES
#endif /* JEMALLOC_H_TYPES */
/******************************************************************************/
#ifdef JEMALLOC_H_STRUCTS
#endif /* JEMALLOC_H_STRUCTS */
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
#ifdef JEMALLOC_H_INLINES
#ifndef JEMALLOC_ENABLE_INLINE
void mb_write(void);
#endif
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_MB_C_))
#ifdef __i386__
/*
* According to the Intel Architecture Software Developer's Manual, current
* processors execute instructions in order from the perspective of other
* processors in a multiprocessor system, but 1) Intel reserves the right to
* change that, and 2) the compiler's optimizer could re-order instructions if
* there weren't some form of barrier. Therefore, even if running on an
* architecture that does not need memory barriers (everything through at least
* i686), an "optimizer barrier" is necessary.
*/
JEMALLOC_INLINE void
mb_write(void)
{
# if 0
/* This is a true memory barrier. */
asm volatile ("pusha;"
"xor %%eax,%%eax;"
"cpuid;"
"popa;"
: /* Outputs. */
: /* Inputs. */
: "memory" /* Clobbers. */
);
#else
/*
* This is hopefully enough to keep the compiler from reordering
* instructions around this one.
*/
asm volatile ("nop;"
: /* Outputs. */
: /* Inputs. */
: "memory" /* Clobbers. */
);
#endif
}
#elif (defined(__amd64__) || defined(__x86_64__))
JEMALLOC_INLINE void
mb_write(void)
{
asm volatile ("sfence"
: /* Outputs. */
: /* Inputs. */
: "memory" /* Clobbers. */
);
}
#elif defined(__powerpc__)
JEMALLOC_INLINE void
mb_write(void)
{
asm volatile ("eieio"
: /* Outputs. */
: /* Inputs. */
: "memory" /* Clobbers. */
);
}
#elif defined(__sparc64__)
JEMALLOC_INLINE void
mb_write(void)
{
asm volatile ("membar #StoreStore"
: /* Outputs. */
: /* Inputs. */
: "memory" /* Clobbers. */
);
}
#elif defined(__tile__)
JEMALLOC_INLINE void
mb_write(void)
{
__sync_synchronize();
}
#else
/*
* This is much slower than a simple memory barrier, but the semantics of mutex
* unlock make this work.
*/
JEMALLOC_INLINE void
mb_write(void)
{
malloc_mutex_t mtx;
malloc_mutex_init(&mtx);
malloc_mutex_lock(&mtx);
malloc_mutex_unlock(&mtx);
}
#endif
#endif
#endif /* JEMALLOC_H_INLINES */
/******************************************************************************/
-99
View File
@@ -1,99 +0,0 @@
/******************************************************************************/
#ifdef JEMALLOC_H_TYPES
typedef struct malloc_mutex_s malloc_mutex_t;
#ifdef _WIN32
# define MALLOC_MUTEX_INITIALIZER
#elif (defined(JEMALLOC_OSSPIN))
# define MALLOC_MUTEX_INITIALIZER {0}
#elif (defined(JEMALLOC_MUTEX_INIT_CB))
# define MALLOC_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER, NULL}
#else
# if (defined(PTHREAD_MUTEX_ADAPTIVE_NP) && \
defined(PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP))
# define MALLOC_MUTEX_TYPE PTHREAD_MUTEX_ADAPTIVE_NP
# define MALLOC_MUTEX_INITIALIZER {PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP}
# else
# define MALLOC_MUTEX_TYPE PTHREAD_MUTEX_DEFAULT
# define MALLOC_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER}
# endif
#endif
#endif /* JEMALLOC_H_TYPES */
/******************************************************************************/
#ifdef JEMALLOC_H_STRUCTS
struct malloc_mutex_s {
#ifdef _WIN32
CRITICAL_SECTION lock;
#elif (defined(JEMALLOC_OSSPIN))
OSSpinLock lock;
#elif (defined(JEMALLOC_MUTEX_INIT_CB))
pthread_mutex_t lock;
malloc_mutex_t *postponed_next;
#else
pthread_mutex_t lock;
#endif
};
#endif /* JEMALLOC_H_STRUCTS */
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
#ifdef JEMALLOC_LAZY_LOCK
extern bool isthreaded;
#else
# undef isthreaded /* Undo private_namespace.h definition. */
# define isthreaded true
#endif
bool malloc_mutex_init(malloc_mutex_t *mutex);
void malloc_mutex_prefork(malloc_mutex_t *mutex);
void malloc_mutex_postfork_parent(malloc_mutex_t *mutex);
void malloc_mutex_postfork_child(malloc_mutex_t *mutex);
bool mutex_boot(void);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
#ifdef JEMALLOC_H_INLINES
#ifndef JEMALLOC_ENABLE_INLINE
void malloc_mutex_lock(malloc_mutex_t *mutex);
void malloc_mutex_unlock(malloc_mutex_t *mutex);
#endif
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_MUTEX_C_))
JEMALLOC_INLINE void
malloc_mutex_lock(malloc_mutex_t *mutex)
{
if (isthreaded) {
#ifdef _WIN32
EnterCriticalSection(&mutex->lock);
#elif (defined(JEMALLOC_OSSPIN))
OSSpinLockLock(&mutex->lock);
#else
pthread_mutex_lock(&mutex->lock);
#endif
}
}
JEMALLOC_INLINE void
malloc_mutex_unlock(malloc_mutex_t *mutex)
{
if (isthreaded) {
#ifdef _WIN32
LeaveCriticalSection(&mutex->lock);
#elif (defined(JEMALLOC_OSSPIN))
OSSpinLockUnlock(&mutex->lock);
#else
pthread_mutex_unlock(&mutex->lock);
#endif
}
}
#endif
#endif /* JEMALLOC_H_INLINES */
/******************************************************************************/
-122
View File
@@ -1,122 +0,0 @@
#!/bin/sh
# The following limits are chosen such that they cover all supported platforms.
# Range of quanta.
lg_qmin=3
lg_qmax=4
# The range of tiny size classes is [2^lg_tmin..2^(lg_q-1)].
lg_tmin=3
# Range of page sizes.
lg_pmin=12
lg_pmax=16
pow2() {
e=$1
pow2_result=1
while [ ${e} -gt 0 ] ; do
pow2_result=$((${pow2_result} + ${pow2_result}))
e=$((${e} - 1))
done
}
cat <<EOF
/* This file was automatically generated by size_classes.sh. */
/******************************************************************************/
#ifdef JEMALLOC_H_TYPES
EOF
lg_q=${lg_qmin}
while [ ${lg_q} -le ${lg_qmax} ] ; do
lg_t=${lg_tmin}
while [ ${lg_t} -le ${lg_q} ] ; do
lg_p=${lg_pmin}
while [ ${lg_p} -le ${lg_pmax} ] ; do
echo "#if (LG_TINY_MIN == ${lg_t} && LG_QUANTUM == ${lg_q} && LG_PAGE == ${lg_p})"
echo "#define SIZE_CLASSES_DEFINED"
pow2 ${lg_q}; q=${pow2_result}
pow2 ${lg_t}; t=${pow2_result}
pow2 ${lg_p}; p=${pow2_result}
bin=0
psz=0
sz=${t}
delta=$((${sz} - ${psz}))
echo "/* SIZE_CLASS(bin, delta, sz) */"
echo "#define SIZE_CLASSES \\"
# Tiny size classes.
while [ ${sz} -lt ${q} ] ; do
echo " SIZE_CLASS(${bin}, ${delta}, ${sz}) \\"
bin=$((${bin} + 1))
psz=${sz}
sz=$((${sz} + ${sz}))
delta=$((${sz} - ${psz}))
done
# Quantum-multiple size classes. For each doubling of sz, as many as 4
# size classes exist. Their spacing is the greater of:
# - q
# - sz/4, where sz is a power of 2
while [ ${sz} -lt ${p} ] ; do
if [ ${sz} -ge $((${q} * 4)) ] ; then
i=$((${sz} / 4))
else
i=${q}
fi
next_2pow=$((${sz} * 2))
while [ ${sz} -lt $next_2pow ] ; do
echo " SIZE_CLASS(${bin}, ${delta}, ${sz}) \\"
bin=$((${bin} + 1))
psz=${sz}
sz=$((${sz} + ${i}))
delta=$((${sz} - ${psz}))
done
done
echo
echo "#define NBINS ${bin}"
echo "#define SMALL_MAXCLASS ${psz}"
echo "#endif"
echo
lg_p=$((${lg_p} + 1))
done
lg_t=$((${lg_t} + 1))
done
lg_q=$((${lg_q} + 1))
done
cat <<EOF
#ifndef SIZE_CLASSES_DEFINED
# error "No size class definitions match configuration"
#endif
#undef SIZE_CLASSES_DEFINED
/*
* The small_size2bin lookup table uses uint8_t to encode each bin index, so we
* cannot support more than 256 small size classes. Further constrain NBINS to
* 255 to support prof_promote, since all small size classes, plus a "not
* small" size class must be stored in 8 bits of arena_chunk_map_t's bits
* field.
*/
#if (NBINS > 255)
# error "Too many small size classes"
#endif
#endif /* JEMALLOC_H_TYPES */
/******************************************************************************/
#ifdef JEMALLOC_H_STRUCTS
#endif /* JEMALLOC_H_STRUCTS */
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
#ifdef JEMALLOC_H_INLINES
#endif /* JEMALLOC_H_INLINES */
/******************************************************************************/
EOF
-173
View File
@@ -1,173 +0,0 @@
/******************************************************************************/
#ifdef JEMALLOC_H_TYPES
typedef struct tcache_bin_stats_s tcache_bin_stats_t;
typedef struct malloc_bin_stats_s malloc_bin_stats_t;
typedef struct malloc_large_stats_s malloc_large_stats_t;
typedef struct arena_stats_s arena_stats_t;
typedef struct chunk_stats_s chunk_stats_t;
#endif /* JEMALLOC_H_TYPES */
/******************************************************************************/
#ifdef JEMALLOC_H_STRUCTS
struct tcache_bin_stats_s {
/*
* Number of allocation requests that corresponded to the size of this
* bin.
*/
uint64_t nrequests;
};
struct malloc_bin_stats_s {
/*
* Current number of bytes allocated, including objects currently
* cached by tcache.
*/
size_t allocated;
/*
* Total number of allocation/deallocation requests served directly by
* the bin. Note that tcache may allocate an object, then recycle it
* many times, resulting many increments to nrequests, but only one
* each to nmalloc and ndalloc.
*/
uint64_t nmalloc;
uint64_t ndalloc;
/*
* Number of allocation requests that correspond to the size of this
* bin. This includes requests served by tcache, though tcache only
* periodically merges into this counter.
*/
uint64_t nrequests;
/* Number of tcache fills from this bin. */
uint64_t nfills;
/* Number of tcache flushes to this bin. */
uint64_t nflushes;
/* Total number of runs created for this bin's size class. */
uint64_t nruns;
/*
* Total number of runs reused by extracting them from the runs tree for
* this bin's size class.
*/
uint64_t reruns;
/* Current number of runs in this bin. */
size_t curruns;
};
struct malloc_large_stats_s {
/*
* Total number of allocation/deallocation requests served directly by
* the arena. Note that tcache may allocate an object, then recycle it
* many times, resulting many increments to nrequests, but only one
* each to nmalloc and ndalloc.
*/
uint64_t nmalloc;
uint64_t ndalloc;
/*
* Number of allocation requests that correspond to this size class.
* This includes requests served by tcache, though tcache only
* periodically merges into this counter.
*/
uint64_t nrequests;
/* Current number of runs of this size class. */
size_t curruns;
};
struct arena_stats_s {
/* Number of bytes currently mapped. */
size_t mapped;
/*
* Total number of purge sweeps, total number of madvise calls made,
* and total pages purged in order to keep dirty unused memory under
* control.
*/
uint64_t npurge;
uint64_t nmadvise;
uint64_t purged;
/* Per-size-category statistics. */
size_t allocated_large;
uint64_t nmalloc_large;
uint64_t ndalloc_large;
uint64_t nrequests_large;
/*
* One element for each possible size class, including sizes that
* overlap with bin size classes. This is necessary because ipalloc()
* sometimes has to use such large objects in order to assure proper
* alignment.
*/
malloc_large_stats_t *lstats;
};
struct chunk_stats_s {
/* Number of chunks that were allocated. */
uint64_t nchunks;
/* High-water mark for number of chunks allocated. */
size_t highchunks;
/*
* Current number of chunks allocated. This value isn't maintained for
* any other purpose, so keep track of it in order to be able to set
* highchunks.
*/
size_t curchunks;
};
#endif /* JEMALLOC_H_STRUCTS */
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
extern bool opt_stats_print;
extern size_t stats_cactive;
void stats_print(void (*write)(void *, const char *), void *cbopaque,
const char *opts);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
#ifdef JEMALLOC_H_INLINES
#ifndef JEMALLOC_ENABLE_INLINE
size_t stats_cactive_get(void);
void stats_cactive_add(size_t size);
void stats_cactive_sub(size_t size);
#endif
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_STATS_C_))
JEMALLOC_INLINE size_t
stats_cactive_get(void)
{
return (atomic_read_z(&stats_cactive));
}
JEMALLOC_INLINE void
stats_cactive_add(size_t size)
{
atomic_add_z(&stats_cactive, size);
}
JEMALLOC_INLINE void
stats_cactive_sub(size_t size)
{
atomic_sub_z(&stats_cactive, size);
}
#endif
#endif /* JEMALLOC_H_INLINES */
/******************************************************************************/
-313
View File
@@ -1,313 +0,0 @@
// ISO C9x compliant inttypes.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
// Copyright (c) 2006 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. The name of the author may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#ifndef _MSC_INTTYPES_H_ // [
#define _MSC_INTTYPES_H_
#if _MSC_VER > 1000
#pragma once
#endif
#include "stdint.h"
// 7.8 Format conversion of integer types
typedef struct {
intmax_t quot;
intmax_t rem;
} imaxdiv_t;
// 7.8.1 Macros for format specifiers
#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198
#ifdef _WIN64
# define __PRI64_PREFIX "l"
# define __PRIPTR_PREFIX "l"
#else
# define __PRI64_PREFIX "ll"
# define __PRIPTR_PREFIX
#endif
// The fprintf macros for signed integers are:
#define PRId8 "d"
#define PRIi8 "i"
#define PRIdLEAST8 "d"
#define PRIiLEAST8 "i"
#define PRIdFAST8 "d"
#define PRIiFAST8 "i"
#define PRId16 "hd"
#define PRIi16 "hi"
#define PRIdLEAST16 "hd"
#define PRIiLEAST16 "hi"
#define PRIdFAST16 "hd"
#define PRIiFAST16 "hi"
#define PRId32 "d"
#define PRIi32 "i"
#define PRIdLEAST32 "d"
#define PRIiLEAST32 "i"
#define PRIdFAST32 "d"
#define PRIiFAST32 "i"
#define PRId64 __PRI64_PREFIX "d"
#define PRIi64 __PRI64_PREFIX "i"
#define PRIdLEAST64 __PRI64_PREFIX "d"
#define PRIiLEAST64 __PRI64_PREFIX "i"
#define PRIdFAST64 __PRI64_PREFIX "d"
#define PRIiFAST64 __PRI64_PREFIX "i"
#define PRIdMAX __PRI64_PREFIX "d"
#define PRIiMAX __PRI64_PREFIX "i"
#define PRIdPTR __PRIPTR_PREFIX "d"
#define PRIiPTR __PRIPTR_PREFIX "i"
// The fprintf macros for unsigned integers are:
#define PRIo8 "o"
#define PRIu8 "u"
#define PRIx8 "x"
#define PRIX8 "X"
#define PRIoLEAST8 "o"
#define PRIuLEAST8 "u"
#define PRIxLEAST8 "x"
#define PRIXLEAST8 "X"
#define PRIoFAST8 "o"
#define PRIuFAST8 "u"
#define PRIxFAST8 "x"
#define PRIXFAST8 "X"
#define PRIo16 "ho"
#define PRIu16 "hu"
#define PRIx16 "hx"
#define PRIX16 "hX"
#define PRIoLEAST16 "ho"
#define PRIuLEAST16 "hu"
#define PRIxLEAST16 "hx"
#define PRIXLEAST16 "hX"
#define PRIoFAST16 "ho"
#define PRIuFAST16 "hu"
#define PRIxFAST16 "hx"
#define PRIXFAST16 "hX"
#define PRIo32 "o"
#define PRIu32 "u"
#define PRIx32 "x"
#define PRIX32 "X"
#define PRIoLEAST32 "o"
#define PRIuLEAST32 "u"
#define PRIxLEAST32 "x"
#define PRIXLEAST32 "X"
#define PRIoFAST32 "o"
#define PRIuFAST32 "u"
#define PRIxFAST32 "x"
#define PRIXFAST32 "X"
#define PRIo64 __PRI64_PREFIX "o"
#define PRIu64 __PRI64_PREFIX "u"
#define PRIx64 __PRI64_PREFIX "x"
#define PRIX64 __PRI64_PREFIX "X"
#define PRIoLEAST64 __PRI64_PREFIX "o"
#define PRIuLEAST64 __PRI64_PREFIX "u"
#define PRIxLEAST64 __PRI64_PREFIX "x"
#define PRIXLEAST64 __PRI64_PREFIX "X"
#define PRIoFAST64 __PRI64_PREFIX "o"
#define PRIuFAST64 __PRI64_PREFIX "u"
#define PRIxFAST64 __PRI64_PREFIX "x"
#define PRIXFAST64 __PRI64_PREFIX "X"
#define PRIoMAX __PRI64_PREFIX "o"
#define PRIuMAX __PRI64_PREFIX "u"
#define PRIxMAX __PRI64_PREFIX "x"
#define PRIXMAX __PRI64_PREFIX "X"
#define PRIoPTR __PRIPTR_PREFIX "o"
#define PRIuPTR __PRIPTR_PREFIX "u"
#define PRIxPTR __PRIPTR_PREFIX "x"
#define PRIXPTR __PRIPTR_PREFIX "X"
// The fscanf macros for signed integers are:
#define SCNd8 "d"
#define SCNi8 "i"
#define SCNdLEAST8 "d"
#define SCNiLEAST8 "i"
#define SCNdFAST8 "d"
#define SCNiFAST8 "i"
#define SCNd16 "hd"
#define SCNi16 "hi"
#define SCNdLEAST16 "hd"
#define SCNiLEAST16 "hi"
#define SCNdFAST16 "hd"
#define SCNiFAST16 "hi"
#define SCNd32 "ld"
#define SCNi32 "li"
#define SCNdLEAST32 "ld"
#define SCNiLEAST32 "li"
#define SCNdFAST32 "ld"
#define SCNiFAST32 "li"
#define SCNd64 "I64d"
#define SCNi64 "I64i"
#define SCNdLEAST64 "I64d"
#define SCNiLEAST64 "I64i"
#define SCNdFAST64 "I64d"
#define SCNiFAST64 "I64i"
#define SCNdMAX "I64d"
#define SCNiMAX "I64i"
#ifdef _WIN64 // [
# define SCNdPTR "I64d"
# define SCNiPTR "I64i"
#else // _WIN64 ][
# define SCNdPTR "ld"
# define SCNiPTR "li"
#endif // _WIN64 ]
// The fscanf macros for unsigned integers are:
#define SCNo8 "o"
#define SCNu8 "u"
#define SCNx8 "x"
#define SCNX8 "X"
#define SCNoLEAST8 "o"
#define SCNuLEAST8 "u"
#define SCNxLEAST8 "x"
#define SCNXLEAST8 "X"
#define SCNoFAST8 "o"
#define SCNuFAST8 "u"
#define SCNxFAST8 "x"
#define SCNXFAST8 "X"
#define SCNo16 "ho"
#define SCNu16 "hu"
#define SCNx16 "hx"
#define SCNX16 "hX"
#define SCNoLEAST16 "ho"
#define SCNuLEAST16 "hu"
#define SCNxLEAST16 "hx"
#define SCNXLEAST16 "hX"
#define SCNoFAST16 "ho"
#define SCNuFAST16 "hu"
#define SCNxFAST16 "hx"
#define SCNXFAST16 "hX"
#define SCNo32 "lo"
#define SCNu32 "lu"
#define SCNx32 "lx"
#define SCNX32 "lX"
#define SCNoLEAST32 "lo"
#define SCNuLEAST32 "lu"
#define SCNxLEAST32 "lx"
#define SCNXLEAST32 "lX"
#define SCNoFAST32 "lo"
#define SCNuFAST32 "lu"
#define SCNxFAST32 "lx"
#define SCNXFAST32 "lX"
#define SCNo64 "I64o"
#define SCNu64 "I64u"
#define SCNx64 "I64x"
#define SCNX64 "I64X"
#define SCNoLEAST64 "I64o"
#define SCNuLEAST64 "I64u"
#define SCNxLEAST64 "I64x"
#define SCNXLEAST64 "I64X"
#define SCNoFAST64 "I64o"
#define SCNuFAST64 "I64u"
#define SCNxFAST64 "I64x"
#define SCNXFAST64 "I64X"
#define SCNoMAX "I64o"
#define SCNuMAX "I64u"
#define SCNxMAX "I64x"
#define SCNXMAX "I64X"
#ifdef _WIN64 // [
# define SCNoPTR "I64o"
# define SCNuPTR "I64u"
# define SCNxPTR "I64x"
# define SCNXPTR "I64X"
#else // _WIN64 ][
# define SCNoPTR "lo"
# define SCNuPTR "lu"
# define SCNxPTR "lx"
# define SCNXPTR "lX"
#endif // _WIN64 ]
#endif // __STDC_FORMAT_MACROS ]
// 7.8.2 Functions for greatest-width integer types
// 7.8.2.1 The imaxabs function
#define imaxabs _abs64
// 7.8.2.2 The imaxdiv function
// This is modified version of div() function from Microsoft's div.c found
// in %MSVC.NET%\crt\src\div.c
#ifdef STATIC_IMAXDIV // [
static
#else // STATIC_IMAXDIV ][
_inline
#endif // STATIC_IMAXDIV ]
imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
{
imaxdiv_t result;
result.quot = numer / denom;
result.rem = numer % denom;
if (numer < 0 && result.rem > 0) {
// did division wrong; must fix up
++result.quot;
result.rem -= denom;
}
return result;
}
// 7.8.2.3 The strtoimax and strtoumax functions
#define strtoimax _strtoi64
#define strtoumax _strtoui64
// 7.8.2.4 The wcstoimax and wcstoumax functions
#define wcstoimax _wcstoi64
#define wcstoumax _wcstoui64
#endif // _MSC_INTTYPES_H_ ]
-16
View File
@@ -1,16 +0,0 @@
#ifndef stdbool_h
#define stdbool_h
#include <wtypes.h>
/* MSVC doesn't define _Bool or bool in C, but does have BOOL */
/* Note this doesn't pass autoconf's test because (bool) 0.5 != true */
typedef BOOL _Bool;
#define bool _Bool
#define true 1
#define false 0
#define __bool_true_false_are_defined 1
#endif /* stdbool_h */
-247
View File
@@ -1,247 +0,0 @@
// ISO C9x compliant stdint.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
// Copyright (c) 2006-2008 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. The name of the author may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#ifndef _MSC_STDINT_H_ // [
#define _MSC_STDINT_H_
#if _MSC_VER > 1000
#pragma once
#endif
#include <limits.h>
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
// or compiler give many errors like this:
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
#ifdef __cplusplus
extern "C" {
#endif
# include <wchar.h>
#ifdef __cplusplus
}
#endif
// Define _W64 macros to mark types changing their size, like intptr_t.
#ifndef _W64
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
# define _W64 __w64
# else
# define _W64
# endif
#endif
// 7.18.1 Integer types
// 7.18.1.1 Exact-width integer types
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
// realize that, e.g. char has the same size as __int8
// so we give up on __intX for them.
#if (_MSC_VER < 1300)
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#else
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
#endif
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
// 7.18.1.2 Minimum-width integer types
typedef int8_t int_least8_t;
typedef int16_t int_least16_t;
typedef int32_t int_least32_t;
typedef int64_t int_least64_t;
typedef uint8_t uint_least8_t;
typedef uint16_t uint_least16_t;
typedef uint32_t uint_least32_t;
typedef uint64_t uint_least64_t;
// 7.18.1.3 Fastest minimum-width integer types
typedef int8_t int_fast8_t;
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef int64_t int_fast64_t;
typedef uint8_t uint_fast8_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
typedef uint64_t uint_fast64_t;
// 7.18.1.4 Integer types capable of holding object pointers
#ifdef _WIN64 // [
typedef signed __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
#else // _WIN64 ][
typedef _W64 signed int intptr_t;
typedef _W64 unsigned int uintptr_t;
#endif // _WIN64 ]
// 7.18.1.5 Greatest-width integer types
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
// 7.18.2 Limits of specified-width integer types
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
// 7.18.2.1 Limits of exact-width integer types
#define INT8_MIN ((int8_t)_I8_MIN)
#define INT8_MAX _I8_MAX
#define INT16_MIN ((int16_t)_I16_MIN)
#define INT16_MAX _I16_MAX
#define INT32_MIN ((int32_t)_I32_MIN)
#define INT32_MAX _I32_MAX
#define INT64_MIN ((int64_t)_I64_MIN)
#define INT64_MAX _I64_MAX
#define UINT8_MAX _UI8_MAX
#define UINT16_MAX _UI16_MAX
#define UINT32_MAX _UI32_MAX
#define UINT64_MAX _UI64_MAX
// 7.18.2.2 Limits of minimum-width integer types
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
// 7.18.2.3 Limits of fastest minimum-width integer types
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
// 7.18.2.4 Limits of integer types capable of holding object pointers
#ifdef _WIN64 // [
# define INTPTR_MIN INT64_MIN
# define INTPTR_MAX INT64_MAX
# define UINTPTR_MAX UINT64_MAX
#else // _WIN64 ][
# define INTPTR_MIN INT32_MIN
# define INTPTR_MAX INT32_MAX
# define UINTPTR_MAX UINT32_MAX
#endif // _WIN64 ]
// 7.18.2.5 Limits of greatest-width integer types
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
// 7.18.3 Limits of other integer types
#ifdef _WIN64 // [
# define PTRDIFF_MIN _I64_MIN
# define PTRDIFF_MAX _I64_MAX
#else // _WIN64 ][
# define PTRDIFF_MIN _I32_MIN
# define PTRDIFF_MAX _I32_MAX
#endif // _WIN64 ]
#define SIG_ATOMIC_MIN INT_MIN
#define SIG_ATOMIC_MAX INT_MAX
#ifndef SIZE_MAX // [
# ifdef _WIN64 // [
# define SIZE_MAX _UI64_MAX
# else // _WIN64 ][
# define SIZE_MAX _UI32_MAX
# endif // _WIN64 ]
#endif // SIZE_MAX ]
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
#ifndef WCHAR_MIN // [
# define WCHAR_MIN 0
#endif // WCHAR_MIN ]
#ifndef WCHAR_MAX // [
# define WCHAR_MAX _UI16_MAX
#endif // WCHAR_MAX ]
#define WINT_MIN 0
#define WINT_MAX _UI16_MAX
#endif // __STDC_LIMIT_MACROS ]
// 7.18.4 Limits of other integer types
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
// 7.18.4.1 Macros for minimum-width integer constants
#define INT8_C(val) val##i8
#define INT16_C(val) val##i16
#define INT32_C(val) val##i32
#define INT64_C(val) val##i64
#define UINT8_C(val) val##ui8
#define UINT16_C(val) val##ui16
#define UINT32_C(val) val##ui32
#define UINT64_C(val) val##ui64
// 7.18.4.2 Macros for greatest-width integer constants
#define INTMAX_C INT64_C
#define UINTMAX_C UINT64_C
#endif // __STDC_CONSTANT_MACROS ]
#endif // _MSC_STDINT_H_ ]
-23
View File
@@ -1,23 +0,0 @@
#ifndef strings_h
#define strings_h
/* MSVC doesn't define ffs/ffsl. This dummy strings.h header is provided
* for both */
#include <intrin.h>
#pragma intrinsic(_BitScanForward)
static __forceinline int ffsl(long x)
{
unsigned long i;
if (_BitScanForward(&i, x))
return (i + 1);
return (0);
}
static __forceinline int ffs(int x)
{
return (ffsl(x));
}
#endif
-250
View File
@@ -1,250 +0,0 @@
#! /bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0
-2
View File
@@ -1,2 +0,0 @@
#define JEMALLOC_ATOMIC_C_
#include "jemalloc/internal/jemalloc_internal.h"
-39
View File
@@ -1,39 +0,0 @@
#define JEMALLOC_EXTENT_C_
#include "jemalloc/internal/jemalloc_internal.h"
/******************************************************************************/
static inline int
extent_szad_comp(extent_node_t *a, extent_node_t *b)
{
int ret;
size_t a_size = a->size;
size_t b_size = b->size;
ret = (a_size > b_size) - (a_size < b_size);
if (ret == 0) {
uintptr_t a_addr = (uintptr_t)a->addr;
uintptr_t b_addr = (uintptr_t)b->addr;
ret = (a_addr > b_addr) - (a_addr < b_addr);
}
return (ret);
}
/* Generate red-black tree functions. */
rb_gen(, extent_tree_szad_, extent_tree_t, extent_node_t, link_szad,
extent_szad_comp)
static inline int
extent_ad_comp(extent_node_t *a, extent_node_t *b)
{
uintptr_t a_addr = (uintptr_t)a->addr;
uintptr_t b_addr = (uintptr_t)b->addr;
return ((a_addr > b_addr) - (a_addr < b_addr));
}
/* Generate red-black tree functions. */
rb_gen(, extent_tree_ad_, extent_tree_t, extent_node_t, link_ad,
extent_ad_comp)
-2
View File
@@ -1,2 +0,0 @@
#define JEMALLOC_HASH_C_
#include "jemalloc/internal/jemalloc_internal.h"
-2
View File
@@ -1,2 +0,0 @@
#define JEMALLOC_MB_C_
#include "jemalloc/internal/jemalloc_internal.h"
+3 -1
View File
@@ -1 +1,3 @@
linenoise_example*
linenoise_example
*.dSYM
history.txt
+15 -8
View File
@@ -1,8 +1,13 @@
# Linenoise
A minimal, zero-config, BSD licensed, readline replacement.
A minimal, zero-config, BSD licensed, readline replacement used in Redis,
MongoDB, and Android.
News: linenoise is now part of [Android](http://android.git.kernel.org/?p=platform/system/core.git;a=tree;f=liblinenoise;h=56450eaed7f783760e5e6a5993ef75cde2e29dea;hb=HEAD Android)!
* Single and multi line editing mode with the usual key bindings implemented.
* History handling.
* Completion.
* About 1,100 lines of BSD license source code.
* Only uses a subset of VT100 escapes (ANSI.SYS compatible).
## Can a line editing library be 20k lines of code?
@@ -10,7 +15,7 @@ Line editing with some support for history is a really important feature for com
So what usually happens is either:
* Large programs with configure scripts disabling line editing if readline is not present in the system, or not supporting it at all since readline is GPL licensed and libedit (the BSD clone) is not as known and available as readline is (Readl world example of this problem: Tclsh).
* Large programs with configure scripts disabling line editing if readline is not present in the system, or not supporting it at all since readline is GPL licensed and libedit (the BSD clone) is not as known and available as readline is (Real world example of this problem: Tclsh).
* Smaller programs not using a configure script not supporting line editing at all (A problem we had with Redis-cli for instance).
The result is a pollution of binaries without line editing support.
@@ -19,27 +24,29 @@ So I spent more or less two hours doing a reality check resulting in this little
## Terminals, in 2010.
Apparently almost every terminal you can happen to use today has some kind of support for VT100 alike escape sequences. So I tried to write a lib using just very basic VT100 features. The resulting library appears to work everywhere I tried to use it.
Apparently almost every terminal you can happen to use today has some kind of support for basic VT100 escape sequences. So I tried to write a lib using just very basic VT100 features. The resulting library appears to work everywhere I tried to use it, and now can work even on ANSI.SYS compatible terminals, since no
VT220 specific sequences are used anymore.
Since it's so young I guess there are a few bugs, or the lib may not compile or work with some operating system, but it's a matter of a few weeks and eventually we'll get it right, and there will be no excuses for not shipping command line tools without built-in line editing support.
The library is currently less than 400 lines of code. In order to use it in your project just look at the *example.c* file in the source distribution, it is trivial. Linenoise is BSD code, so you can use both in free software and commercial software.
The library is currently about 1100 lines of code. In order to use it in your project just look at the *example.c* file in the source distribution, it is trivial. Linenoise is BSD code, so you can use both in free software and commercial software.
## Tested with...
* Linux text only console ($TERM = linux)
* Linux KDE terminal application ($TERM = xterm)
* Linux xterm ($TERM = xterm)
* Linux Buildroot ($TERM = vt100)
* Mac OS X iTerm ($TERM = xterm)
* Mac OS X default Terminal.app ($TERM = xterm)
* OpenBSD 4.5 through an OSX Terminal.app ($TERM = screen)
* IBM AIX 6.1
* FreeBSD xterm ($TERM = xterm)
* ANSI.SYS
Please test it everywhere you can and report back!
## Let's push this forward!
Please fork it and add something interesting and send me a pull request. What's especially interesting are fixes, new key bindings, completion.
Patches should be provided in the respect of linenoise sensibility for small
easy to understand code.
Send feedbacks to antirez at gmail
+41 -4
View File
@@ -1,5 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "linenoise.h"
@@ -10,16 +11,52 @@ void completion(const char *buf, linenoiseCompletions *lc) {
}
}
int main(void) {
int main(int argc, char **argv) {
char *line;
char *prgname = argv[0];
/* Parse options, with --multiline we enable multi line editing. */
while(argc > 1) {
argc--;
argv++;
if (!strcmp(*argv,"--multiline")) {
linenoiseSetMultiLine(1);
printf("Multi-line mode enabled.\n");
} else if (!strcmp(*argv,"--keycodes")) {
linenoisePrintKeyCodes();
exit(0);
} else {
fprintf(stderr, "Usage: %s [--multiline] [--keycodes]\n", prgname);
exit(1);
}
}
/* Set the completion callback. This will be called every time the
* user uses the <tab> key. */
linenoiseSetCompletionCallback(completion);
/* Load history from file. The history file is just a plain text file
* where entries are separated by newlines. */
linenoiseHistoryLoad("history.txt"); /* Load the history at startup */
/* Now this is the main loop of the typical linenoise-based application.
* The call to linenoise() will block as long as the user types something
* and presses enter.
*
* The typed string is returned as a malloc() allocated string by
* linenoise, so the user needs to free() it. */
while((line = linenoise("hello> ")) != NULL) {
if (line[0] != '\0') {
/* Do something with the string. */
if (line[0] != '\0' && line[0] != '/') {
printf("echo: '%s'\n", line);
linenoiseHistoryAdd(line);
linenoiseHistorySave("history.txt"); /* Save every new entry */
linenoiseHistoryAdd(line); /* Add to the history. */
linenoiseHistorySave("history.txt"); /* Save the history on disk. */
} else if (!strncmp(line,"/historylen",11)) {
/* The "/historylen" command will change the history len. */
int len = atoi(line+11);
linenoiseHistorySetMaxLen(len);
} else if (line[0] == '/') {
printf("Unreconized command: %s\n", line);
}
free(line);
}
+251 -59
View File
@@ -2,7 +2,7 @@
* line editing lib needs to be 20,000 lines of C code.
*
* You can find the latest source code at:
*
*
* http://github.com/antirez/linenoise
*
* Does a number of crazy assumptions that happen to be true in 99.9999% of
@@ -14,18 +14,18 @@
* Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com>
*
* 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
@@ -37,7 +37,7 @@
* 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.
*
*
* ------------------------------------------------------------------------
*
* References:
@@ -56,10 +56,6 @@
* flickering effect with some slow terminal, but the lesser sequences
* the more compatible.
*
* CHA (Cursor Horizontal Absolute)
* Sequence: ESC [ n G
* Effect: moves cursor to column n
*
* EL (Erase Line)
* Sequence: ESC [ n K
* Effect: if n is 0 or missing, clear from cursor to end of line
@@ -68,7 +64,19 @@
*
* CUF (CUrsor Forward)
* Sequence: ESC [ n C
* Effect: moves cursor forward of n chars
* Effect: moves cursor forward n chars
*
* CUB (CUrsor Backward)
* Sequence: ESC [ n D
* Effect: moves cursor backward n chars
*
* The following is used to get the terminal width if getting
* the width with the TIOCGWINSZ ioctl fails
*
* DSR (Device Status Report)
* Sequence: ESC [ 6 n
* Effect: reports the current cusor position as ESC [ n ; m R
* where n is the row and m is the column
*
* When multi line mode is enabled, we also use an additional escape
* sequence. However multi line editing is disabled by default.
@@ -81,21 +89,25 @@
* Sequence: ESC [ n B
* Effect: moves cursor down of n chars.
*
* The following are used to clear the screen: ESC [ H ESC [ 2 J
* This is actually composed of two sequences:
* When linenoiseClearScreen() is called, two additional escape sequences
* are used in order to clear the screen and position the cursor at home
* position.
*
* cursorhome
* CUP (Cursor position)
* Sequence: ESC [ H
* Effect: moves the cursor to upper left corner
*
* ED2 (Clear entire screen)
* ED (Erase display)
* Sequence: ESC [ 2 J
* Effect: clear the whole screen
*
*
*/
#ifndef _WIN32
#include <termios.h>
#include <unistd.h>
#include <sys/ioctl.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
@@ -103,16 +115,21 @@
#include <stdlib.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "linenoise.h"
#ifdef _WIN32
#include "../../src/win32_Interop/win32fixes.h"
#define REDIS_NOTUSED(V) ((void) V)
#include "../../src/win32_Interop/win32_ANSI.h"
#endif
#define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100
#define LINENOISE_MAX_LINE 4096
static char *unsupported_term[] = {"dumb","cons25","emacs",NULL};
static linenoiseCompletionCallback *completionCallback = NULL;
#ifndef _WIN32
static struct termios orig_termios; /* In order to restore at exit.*/
#endif
static int rawmode = 0; /* For atexit() function to check if restore is needed*/
static int mlmode = 0; /* Multi line mode. Default is single line. */
static int atexit_registered = 0; /* Register atexit just 1 time. */
@@ -164,6 +181,121 @@ static void linenoiseAtExit(void);
int linenoiseHistoryAdd(const char *line);
static void refreshLine(struct linenoiseState *l);
#ifdef _WIN32
#ifndef STDIN_FILENO
#define STDIN_FILENO (_fileno(stdin))
#endif
HANDLE hOut;
HANDLE hIn;
DWORD consolemode;
static int win32read(char *c) {
DWORD foo;
INPUT_RECORD b;
KEY_EVENT_RECORD e;
BOOL altgr;
while (1) {
if (!ReadConsoleInput(hIn, &b, 1, &foo)) return 0;
if (!foo) return 0;
if (b.EventType == KEY_EVENT && b.Event.KeyEvent.bKeyDown) {
e = b.Event.KeyEvent;
*c = b.Event.KeyEvent.uChar.AsciiChar;
altgr = e.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED);
if (e.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) && !altgr) {
/* Ctrl+Key */
switch (*c) {
case 'D':
*c = 4;
return 1;
case 'C':
*c = 3;
return 1;
case 'H':
*c = 8;
return 1;
case 'T':
*c = 20;
return 1;
case 'B': /* ctrl-b, left_arrow */
*c = 2;
return 1;
case 'F': /* ctrl-f right_arrow*/
*c = 6;
return 1;
case 'P': /* ctrl-p up_arrow*/
*c = 16;
return 1;
case 'N': /* ctrl-n down_arrow*/
*c = 14;
return 1;
case 'U': /* Ctrl+u, delete the whole line. */
*c = 21;
return 1;
case 'K': /* Ctrl+k, delete from current to end of line. */
*c = 11;
return 1;
case 'A': /* Ctrl+a, go to the start of the line */
*c = 1;
return 1;
case 'E': /* ctrl+e, go to the end of the line */
*c = 5;
return 1;
}
/* Other Ctrl+KEYs ignored */
} else {
switch (e.wVirtualKeyCode) {
case VK_ESCAPE: /* ignore - send ctrl-c, will return -1 */
*c = 3;
return 1;
case VK_RETURN: /* enter */
*c = 13;
return 1;
case VK_LEFT: /* left */
*c = 2;
return 1;
case VK_RIGHT: /* right */
*c = 6;
return 1;
case VK_UP: /* up */
*c = 16;
return 1;
case VK_DOWN: /* down */
*c = 14;
return 1;
case VK_HOME:
*c = 1;
return 1;
case VK_END:
*c = 5;
return 1;
case VK_BACK:
*c = 8;
return 1;
case VK_DELETE:
*c = 127;
return 1;
default:
if (*c) return 1;
}
}
}
}
return -1; /* Makes compiler happy */
}
#endif
/* Debugging macro. */
#if 0
FILE *lndebug_fp = NULL;
@@ -193,17 +325,20 @@ void linenoiseSetMultiLine(int ml) {
/* Return true if the terminal name is in the list of terminals we know are
* not able to understand basic escape sequences. */
static int isUnsupportedTerm(void) {
#ifndef _WIN32
char *term = getenv("TERM");
int j;
if (term == NULL) return 0;
for (j = 0; unsupported_term[j]; j++)
if (!strcasecmp(term,unsupported_term[j])) return 1;
#endif
return 0;
}
/* Raw mode: 1960 magic shit. */
static int enableRawMode(int fd) {
#ifndef _WIN32
struct termios raw;
if (!isatty(STDIN_FILENO)) goto fatal;
@@ -231,6 +366,37 @@ static int enableRawMode(int fd) {
/* put terminal in raw mode after flushing */
if (tcsetattr(fd,TCSAFLUSH,&raw) < 0) goto fatal;
rawmode = 1;
#else
REDIS_NOTUSED(fd);
if (!atexit_registered) {
/* Init windows console handles only once */
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut==INVALID_HANDLE_VALUE) goto fatal;
if (!GetConsoleMode(hOut, &consolemode)) {
CloseHandle(hOut);
errno = ENOTTY;
return -1;
};
hIn = GetStdHandle(STD_INPUT_HANDLE);
if (hIn == INVALID_HANDLE_VALUE) {
CloseHandle(hOut);
errno = ENOTTY;
return -1;
}
GetConsoleMode(hIn, &consolemode);
SetConsoleMode(hIn, ENABLE_PROCESSED_INPUT);
/* Cleanup them at exit */
atexit(linenoiseAtExit);
atexit_registered = 1;
}
rawmode = 1;
#endif
return 0;
fatal:
@@ -239,9 +405,14 @@ fatal:
}
static void disableRawMode(int fd) {
#ifdef _WIN32
REDIS_NOTUSED(fd);
rawmode = 0;
#else
/* Don't even check the return value as it's too late. */
if (rawmode && tcsetattr(fd,TCSAFLUSH,&orig_termios) != -1)
rawmode = 0;
#endif
}
/* Use the ESC [6n escape sequence to query the horizontal cursor position
@@ -272,6 +443,12 @@ static int getCursorPosition(int ifd, int ofd) {
/* Try to get the number of columns in the current terminal, or assume 80
* if it fails. */
static int getColumns(int ifd, int ofd) {
#ifdef _WIN32
CONSOLE_SCREEN_BUFFER_INFO b;
if (!GetConsoleScreenBufferInfo(hOut, &b)) return 80;
return b.srWindow.Right - b.srWindow.Left;
#else
struct winsize ws;
if (ioctl(1, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) {
@@ -302,6 +479,7 @@ static int getColumns(int ifd, int ofd) {
failed:
return 80;
#endif
}
/* Clear the screen. Used to handle ctrl+l */
@@ -332,7 +510,7 @@ static void freeCompletions(linenoiseCompletions *lc) {
/* This is an helper function for linenoiseEdit() and is called when the
* user types the <tab> key in order to complete the string currently in the
* input.
*
*
* The state of the editing is encapsulated into the pointed linenoiseState
* structure as described in the structure definition. */
static int completeLine(struct linenoiseState *ls) {
@@ -361,7 +539,7 @@ static int completeLine(struct linenoiseState *ls) {
refreshLine(ls);
}
nread = read(ls->ifd,&c,1);
nread = (int)read(ls->ifd,&c,1); /* UPSTREAM_ISSUE: missing (int) cast */
if (nread <= 0) {
freeCompletions(&lc);
return -1;
@@ -459,7 +637,7 @@ static void refreshSingleLine(struct linenoiseState *l) {
size_t len = l->len;
size_t pos = l->pos;
struct abuf ab;
while((plen+pos) >= l->cols) {
buf++;
len--;
@@ -471,17 +649,17 @@ static void refreshSingleLine(struct linenoiseState *l) {
abInit(&ab);
/* Cursor to left edge */
snprintf(seq,64,"\x1b[0G");
abAppend(&ab,seq,strlen(seq));
snprintf(seq,64,"\r");
abAppend(&ab,seq,(int)strlen(seq));
/* Write the prompt and the current buffer content */
abAppend(&ab,l->prompt,strlen(l->prompt));
abAppend(&ab,buf,len);
abAppend(&ab,l->prompt,(int)strlen(l->prompt));
abAppend(&ab,buf,(int)len);
/* Erase to right */
snprintf(seq,64,"\x1b[0K");
abAppend(&ab,seq,strlen(seq));
abAppend(&ab,seq,(int)strlen(seq));
/* Move cursor to original position. */
snprintf(seq,64,"\x1b[0G\x1b[%dC", (int)(pos+plen));
abAppend(&ab,seq,strlen(seq));
snprintf(seq,64,"\r\x1b[%dC", (int)(pos+plen));
abAppend(&ab,seq,(int)strlen(seq));
if (write(fd,ab.b,ab.len) == -1) {} /* Can't recover from write error. */
abFree(&ab);
}
@@ -492,11 +670,12 @@ static void refreshSingleLine(struct linenoiseState *l) {
* cursor position, and number of columns of the terminal. */
static void refreshMultiLine(struct linenoiseState *l) {
char seq[64];
int plen = strlen(l->prompt);
int rows = (plen+l->len+l->cols-1)/l->cols; /* rows used by current buf. */
int rpos = (plen+l->oldpos+l->cols)/l->cols; /* cursor relative row. */
int plen = (int)strlen(l->prompt);
int rows = (int)((plen+l->len+l->cols-1)/l->cols); /* rows used by current buf. */
int rpos = (int)((plen+l->oldpos+l->cols)/l->cols); /* cursor relative row. */
int rpos2; /* rpos after refresh. */
int old_rows = l->maxrows;
int col; /* colum position, zero-based. */
int old_rows = (int)l->maxrows;
int fd = l->ofd, j;
struct abuf ab;
@@ -509,24 +688,24 @@ static void refreshMultiLine(struct linenoiseState *l) {
if (old_rows-rpos > 0) {
lndebug("go down %d", old_rows-rpos);
snprintf(seq,64,"\x1b[%dB", old_rows-rpos);
abAppend(&ab,seq,strlen(seq));
abAppend(&ab,seq,(int)strlen(seq));
}
/* Now for every row clear it, go up. */
for (j = 0; j < old_rows-1; j++) {
lndebug("clear+up");
snprintf(seq,64,"\x1b[0G\x1b[0K\x1b[1A");
abAppend(&ab,seq,strlen(seq));
snprintf(seq,64,"\r\x1b[0K\x1b[1A");
abAppend(&ab,seq,(int)strlen(seq));
}
/* Clean the top line. */
lndebug("clear");
snprintf(seq,64,"\x1b[0G\x1b[0K");
abAppend(&ab,seq,strlen(seq));
snprintf(seq,64,"\r\x1b[0K");
abAppend(&ab,seq,(int)strlen(seq));
/* Write the prompt and the current buffer content */
abAppend(&ab,l->prompt,strlen(l->prompt));
abAppend(&ab,l->buf,l->len);
abAppend(&ab,l->prompt,(int)strlen(l->prompt));
abAppend(&ab,l->buf,(int)l->len);
/* If we are at the very end of the screen with our prompt, we need to
* emit a newline and move the prompt to the first column. */
@@ -536,27 +715,31 @@ static void refreshMultiLine(struct linenoiseState *l) {
{
lndebug("<newline>");
abAppend(&ab,"\n",1);
snprintf(seq,64,"\x1b[0G");
abAppend(&ab,seq,strlen(seq));
snprintf(seq,64,"\r");
abAppend(&ab,seq,(int)strlen(seq));
rows++;
if (rows > (int)l->maxrows) l->maxrows = rows;
}
/* Move cursor to right position. */
rpos2 = (plen+l->pos+l->cols)/l->cols; /* current cursor relative row. */
rpos2 = (int)((plen+l->pos+l->cols)/l->cols); /* current cursor relative row. */
lndebug("rpos2 %d", rpos2);
/* Go up till we reach the expected positon. */
if (rows-rpos2 > 0) {
lndebug("go-up %d", rows-rpos2);
snprintf(seq,64,"\x1b[%dA", rows-rpos2);
abAppend(&ab,seq,strlen(seq));
abAppend(&ab,seq,(int)strlen(seq));
}
/* Set column. */
lndebug("set col %d", 1+((plen+(int)l->pos) % (int)l->cols));
snprintf(seq,64,"\x1b[%dG", 1+((plen+(int)l->pos) % (int)l->cols));
abAppend(&ab,seq,strlen(seq));
col = (plen+(int)l->pos) % (int)l->cols;
lndebug("set col %d", 1+col);
if (col)
snprintf(seq,64,"\r\x1b[%dC", col);
else
snprintf(seq,64,"\r");
abAppend(&ab,seq,(int)strlen(seq));
lndebug("\n");
l->oldpos = l->pos;
@@ -732,15 +915,19 @@ static int linenoiseEdit(int stdin_fd, int stdout_fd, char *buf, size_t buflen,
/* The latest history entry is always our current buffer, that
* initially is just an empty string. */
linenoiseHistoryAdd("");
if (write(l.ofd,prompt,l.plen) == -1) return -1;
while(1) {
char c;
int nread;
char seq[3];
#ifdef _WIN32
nread = win32read(&c);
#else
nread = read(l.ifd,&c,1);
if (nread <= 0) return l.len;
#endif
if (nread <= 0) return (int)l.len;
/* Only autocomplete when the callback is set. It returns < 0 when
* there was an error reading from fd. Otherwise it will return the
@@ -748,7 +935,7 @@ static int linenoiseEdit(int stdin_fd, int stdout_fd, char *buf, size_t buflen,
if (c == 9 && completionCallback != NULL) {
c = completeLine(&l);
/* Return on errors */
if (c < 0) return l.len;
if (c < 0) return (int)l.len;
/* Read next character when 0 */
if (c == 0) continue;
}
@@ -757,6 +944,7 @@ static int linenoiseEdit(int stdin_fd, int stdout_fd, char *buf, size_t buflen,
case ENTER: /* enter */
history_len--;
free(history[history_len]);
if (mlmode) linenoiseEditMoveEnd(&l);
return (int)l.len;
case CTRL_C: /* ctrl-c */
errno = EAGAIN;
@@ -765,8 +953,8 @@ static int linenoiseEdit(int stdin_fd, int stdout_fd, char *buf, size_t buflen,
case 8: /* ctrl-h */
linenoiseEditBackspace(&l);
break;
case CTRL_D: /* ctrl-d, remove char at right of cursor, or of the
line is empty, act as end-of-file. */
case CTRL_D: /* ctrl-d, remove char at right of cursor, or if the
line is empty, act as end-of-file. */
if (l.len > 0) {
linenoiseEditDelete(&l);
} else {
@@ -879,7 +1067,7 @@ static int linenoiseEdit(int stdin_fd, int stdout_fd, char *buf, size_t buflen,
break;
}
}
return l.len;
return (int)l.len;
}
/* This special mode is used by linenoise in order to print scan codes
@@ -896,7 +1084,7 @@ void linenoisePrintKeyCodes(void) {
char c;
int nread;
nread = read(STDIN_FILENO,&c,1);
nread = (int)read(STDIN_FILENO,&c,1); /* UPSTREAM_ISSUE: missing (int) cast */
if (nread <= 0) continue;
memmove(quit,quit+1,sizeof(quit)-1); /* shift string to left. */
quit[sizeof(quit)-1] = c; /* Insert current char on the right. */
@@ -904,7 +1092,7 @@ void linenoisePrintKeyCodes(void) {
printf("'%c' %02x (%d) (type quit to exit)\n",
isprint(c) ? c : '?', (int)c, (int)c);
printf("\x1b[0G"); /* Go left edge manually, we are in raw mode. */
printf("\r"); /* Go left edge manually, we are in raw mode. */
fflush(stdout);
}
disableRawMode(STDIN_FILENO);
@@ -921,8 +1109,8 @@ static int linenoiseRaw(char *buf, size_t buflen, const char *prompt) {
}
if (!isatty(STDIN_FILENO)) {
/* Not a tty: read from file / pipe. */
if (fgets(buf, buflen, stdin) == NULL) return -1;
count = strlen(buf);
if (fgets(buf, (int)buflen, stdin) == NULL) return -1;
count = (int)strlen(buf);
if (count && buf[count-1] == '\n') {
count--;
buf[count] = '\0';
@@ -1056,9 +1244,13 @@ int linenoiseHistorySetMaxLen(int len) {
/* Save the history in the specified file. On success 0 is returned
* otherwise -1 is returned. */
int linenoiseHistorySave(const char *filename) {
#ifdef _WIN32
FILE *fp = fopen(filename,"wb");
#else
FILE *fp = fopen(filename,"w");
#endif
int j;
if (fp == NULL) return -1;
for (j = 0; j < history_len; j++)
fprintf(fp,"%s\n",history[j]);
@@ -1074,12 +1266,12 @@ int linenoiseHistorySave(const char *filename) {
int linenoiseHistoryLoad(const char *filename) {
FILE *fp = fopen(filename,"r");
char buf[LINENOISE_MAX_LINE];
if (fp == NULL) return -1;
while (fgets(buf,LINENOISE_MAX_LINE,fp) != NULL) {
char *p;
p = strchr(buf,'\r');
if (!p) p = strchr(buf,'\n');
if (p) *p = '\0';
+3 -3
View File
@@ -9,18 +9,18 @@
* Copyright (c) 2010, Pieter Noordhuis <pcnoordhuis at gmail dot com>
*
* 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
+3 -2
View File
@@ -25,9 +25,10 @@ PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris
LUA_A= liblua.a
CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \
lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \
lundump.o lvm.o lzio.o strbuf.o
lundump.o lvm.o lzio.o strbuf.o fpconv.o
LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \
lstrlib.o loadlib.o linit.o lua_cjson.o lua_struct.o lua_cmsgpack.o
lstrlib.o loadlib.o linit.o lua_cjson.o lua_struct.o lua_cmsgpack.o \
lua_bit.o
LUA_T= lua
LUA_O= lua.o
+210
View File
@@ -0,0 +1,210 @@
/* fpconv - Floating point conversion routines
*
* Copyright (c) 2011-2012 Mark Pulford <mark@kyne.com.au>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* JSON uses a '.' decimal separator. strtod() / sprintf() under C libraries
* with locale support will break when the decimal separator is a comma.
*
* fpconv_* will around these issues with a translation buffer if required.
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "fpconv.h"
#ifdef _WIN32
#define inline __inline
#define snprintf _snprintf
#endif
/* Lua CJSON assumes the locale is the same for all threads within a
* process and doesn't change after initialisation.
*
* This avoids the need for per thread storage or expensive checks
* for call. */
static char locale_decimal_point = '.';
/* In theory multibyte decimal_points are possible, but
* Lua CJSON only supports UTF-8 and known locales only have
* single byte decimal points ([.,]).
*
* localconv() may not be thread safe (=>crash), and nl_langinfo() is
* not supported on some platforms. Use sprintf() instead - if the
* locale does change, at least Lua CJSON won't crash. */
static void fpconv_update_locale()
{
char buf[8];
snprintf(buf, sizeof(buf), "%g", 0.5);
/* Failing this test might imply the platform has a buggy dtoa
* implementation or wide characters */
if (buf[0] != '0' || buf[2] != '5' || buf[3] != 0) {
fprintf(stderr, "Error: wide characters found or printf() bug.");
abort();
}
locale_decimal_point = buf[1];
}
/* Check for a valid number character: [-+0-9a-yA-Y.]
* Eg: -0.6e+5, infinity, 0xF0.F0pF0
*
* Used to find the probable end of a number. It doesn't matter if
* invalid characters are counted - strtod() will find the valid
* number if it exists. The risk is that slightly more memory might
* be allocated before a parse error occurs. */
static inline int valid_number_character(char ch)
{
char lower_ch;
if ('0' <= ch && ch <= '9')
return 1;
if (ch == '-' || ch == '+' || ch == '.')
return 1;
/* Hex digits, exponent (e), base (p), "infinity",.. */
lower_ch = ch | 0x20;
if ('a' <= lower_ch && lower_ch <= 'y')
return 1;
return 0;
}
/* Calculate the size of the buffer required for a strtod locale
* conversion. */
static int strtod_buffer_size(const char *s)
{
const char *p = s;
while (valid_number_character(*p))
p++;
return p - s;
}
/* Similar to strtod(), but must be passed the current locale's decimal point
* character. Guaranteed to be called at the start of any valid number in a string */
double fpconv_strtod(const char *nptr, char **endptr)
{
char localbuf[FPCONV_G_FMT_BUFSIZE];
char *buf, *endbuf, *dp;
int buflen;
double value;
/* System strtod() is fine when decimal point is '.' */
if (locale_decimal_point == '.')
return strtod(nptr, endptr);
buflen = strtod_buffer_size(nptr);
if (!buflen) {
/* No valid characters found, standard strtod() return */
*endptr = (char *)nptr;
return 0;
}
/* Duplicate number into buffer */
if (buflen >= FPCONV_G_FMT_BUFSIZE) {
/* Handle unusually large numbers */
buf = malloc(buflen + 1);
if (!buf) {
fprintf(stderr, "Out of memory");
abort();
}
} else {
/* This is the common case.. */
buf = localbuf;
}
memcpy(buf, nptr, buflen);
buf[buflen] = 0;
/* Update decimal point character if found */
dp = strchr(buf, '.');
if (dp)
*dp = locale_decimal_point;
value = strtod(buf, &endbuf);
*endptr = (char *)&nptr[endbuf - buf];
if (buflen >= FPCONV_G_FMT_BUFSIZE)
free(buf);
return value;
}
/* "fmt" must point to a buffer of at least 6 characters */
static void set_number_format(char *fmt, int precision)
{
int d1, d2, i;
assert(1 <= precision && precision <= 14);
/* Create printf format (%.14g) from precision */
d1 = precision / 10;
d2 = precision % 10;
fmt[0] = '%';
fmt[1] = '.';
i = 2;
if (d1) {
fmt[i++] = '0' + d1;
}
fmt[i++] = '0' + d2;
fmt[i++] = 'g';
fmt[i] = 0;
}
/* Assumes there is always at least 32 characters available in the target buffer */
int fpconv_g_fmt(char *str, double num, int precision)
{
char buf[FPCONV_G_FMT_BUFSIZE];
char fmt[6];
int len;
char *b;
set_number_format(fmt, precision);
/* Pass through when decimal point character is dot. */
if (locale_decimal_point == '.')
return snprintf(str, FPCONV_G_FMT_BUFSIZE, fmt, num);
/* snprintf() to a buffer then translate for other decimal point characters */
len = snprintf(buf, FPCONV_G_FMT_BUFSIZE, fmt, num);
/* Copy into target location. Translate decimal point if required */
b = buf;
do {
*str++ = (*b == locale_decimal_point ? '.' : *b);
} while(*b++);
return len;
}
void fpconv_init()
{
fpconv_update_locale();
}
/* vi:ai et sw=4 ts=4:
*/
+22
View File
@@ -0,0 +1,22 @@
/* Lua CJSON floating point conversion routines */
/* Buffer required to store the largest string representation of a double.
*
* Longest double printed with %.14g is 21 characters long:
* -1.7976931348623e+308 */
# define FPCONV_G_FMT_BUFSIZE 32
#ifdef USE_INTERNAL_FPCONV
static inline void fpconv_init()
{
/* Do nothing - not required */
}
#else
extern void fpconv_init();
#endif
extern int fpconv_g_fmt(char*, double, int);
extern double fpconv_strtod(const char*, char**);
/* vi:ai et sw=4 ts=4:
*/
+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;
+8 -1
View File
@@ -284,8 +284,15 @@ static l_mem propagatemark (global_State *g) {
g->gray = h->gclist;
if (traversetable(g, h)) /* table is weak? */
black2gray(o); /* keep it gray */
return sizeof(Table) + sizeof(TValue) * h->sizearray +
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable: 4334)
#endif
return sizeof(Table)+sizeof(TValue)* h->sizearray +
sizeof(Node) * sizenode(h);
#ifdef _WIN32
#pragma warning(pop)
#endif
}
case LUA_TFUNCTION: {
Closure *cl = gco2cl(o);
+16 -2
View File
@@ -319,8 +319,15 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
if (!ttisnil(gval(old)))
setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old));
}
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable: 4334)
#endif
if (nold != dummynode)
luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */
#ifdef _WIN32
#pragma warning(pop)
#endif
}
@@ -372,9 +379,16 @@ Table *luaH_new (lua_State *L, int narray, int nhash) {
void luaH_free (lua_State *L, Table *t) {
if (t->node != dummynode)
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable: 4334)
#endif
if (t->node != dummynode)
luaM_freearray(L, t->node, sizenode(t), Node);
luaM_freearray(L, t->array, t->sizearray, TValue);
#ifdef _WIN32
#pragma warning(pop)
#endif
luaM_freearray(L, t->array, t->sizearray, TValue);
luaM_free(L, t);
}
+189
View File
@@ -0,0 +1,189 @@
/*
** Lua BitOp -- a bit operations library for Lua 5.1/5.2.
** http://bitop.luajit.org/
**
** Copyright (C) 2008-2012 Mike Pall. All rights reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
*/
#define LUA_BITOP_VERSION "1.0.2"
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#ifdef _MSC_VER
/* MSVC is stuck in the last century and doesn't have C99's stdint.h. */
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
typedef int32_t SBits;
typedef uint32_t UBits;
typedef union {
lua_Number n;
#ifdef LUA_NUMBER_DOUBLE
uint64_t b;
#else
UBits b;
#endif
} BitNum;
/* Convert argument to bit type. */
static UBits barg(lua_State *L, int idx)
{
BitNum bn;
UBits b;
#if LUA_VERSION_NUM < 502
bn.n = lua_tonumber(L, idx);
#else
bn.n = luaL_checknumber(L, idx);
#endif
#if defined(LUA_NUMBER_DOUBLE)
bn.n += 6755399441055744.0; /* 2^52+2^51 */
#ifdef SWAPPED_DOUBLE
b = (UBits)(bn.b >> 32);
#else
b = (UBits)bn.b;
#endif
#elif defined(LUA_NUMBER_INT) || defined(LUA_NUMBER_LONG) || \
defined(LUA_NUMBER_LONGLONG) || defined(LUA_NUMBER_LONG_LONG) || \
defined(LUA_NUMBER_LLONG)
if (sizeof(UBits) == sizeof(lua_Number))
b = bn.b;
else
b = (UBits)(SBits)bn.n;
#elif defined(LUA_NUMBER_FLOAT)
#error "A 'float' lua_Number type is incompatible with this library"
#else
#error "Unknown number type, check LUA_NUMBER_* in luaconf.h"
#endif
#if LUA_VERSION_NUM < 502
if (b == 0 && !lua_isnumber(L, idx)) {
luaL_typerror(L, idx, "number");
}
#endif
return b;
}
/* Return bit type. */
#define BRET(b) lua_pushnumber(L, (lua_Number)(SBits)(b)); return 1;
static int bit_tobit(lua_State *L) { BRET(barg(L, 1)) }
static int bit_bnot(lua_State *L) { BRET(~barg(L, 1)) }
#define BIT_OP(func, opr) \
static int func(lua_State *L) { int i; UBits b = barg(L, 1); \
for (i = lua_gettop(L); i > 1; i--) b opr barg(L, i); BRET(b) }
BIT_OP(bit_band, &=)
BIT_OP(bit_bor, |=)
BIT_OP(bit_bxor, ^=)
#define bshl(b, n) (b << n)
#define bshr(b, n) (b >> n)
#define bsar(b, n) ((SBits)b >> n)
#define brol(b, n) ((b << n) | (b >> (32-n)))
#define bror(b, n) ((b << (32-n)) | (b >> n))
#define BIT_SH(func, fn) \
static int func(lua_State *L) { \
UBits b = barg(L, 1); UBits n = barg(L, 2) & 31; BRET(fn(b, n)) }
BIT_SH(bit_lshift, bshl)
BIT_SH(bit_rshift, bshr)
BIT_SH(bit_arshift, bsar)
BIT_SH(bit_rol, brol)
BIT_SH(bit_ror, bror)
static int bit_bswap(lua_State *L)
{
UBits b = barg(L, 1);
b = (b >> 24) | ((b >> 8) & 0xff00) | ((b & 0xff00) << 8) | (b << 24);
BRET(b)
}
static int bit_tohex(lua_State *L)
{
UBits b = barg(L, 1);
SBits n = lua_isnone(L, 2) ? 8 : (SBits)barg(L, 2);
const char *hexdigits = "0123456789abcdef";
char buf[8];
int i;
if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; }
if (n > 8) n = 8;
for (i = (int)n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; }
lua_pushlstring(L, buf, (size_t)n);
return 1;
}
static const struct luaL_Reg bit_funcs[] = {
{ "tobit", bit_tobit },
{ "bnot", bit_bnot },
{ "band", bit_band },
{ "bor", bit_bor },
{ "bxor", bit_bxor },
{ "lshift", bit_lshift },
{ "rshift", bit_rshift },
{ "arshift", bit_arshift },
{ "rol", bit_rol },
{ "ror", bit_ror },
{ "bswap", bit_bswap },
{ "tohex", bit_tohex },
{ NULL, NULL }
};
/* Signed right-shifts are implementation-defined per C89/C99.
** But the de facto standard are arithmetic right-shifts on two's
** complement CPUs. This behaviour is required here, so test for it.
*/
#define BAD_SAR (bsar(-8, 2) != (SBits)-2)
LUALIB_API int luaopen_bit(lua_State *L)
{
UBits b;
lua_pushnumber(L, (lua_Number)1437217655L);
b = barg(L, -1);
if (b != (UBits)1437217655L || BAD_SAR) { /* Perform a simple self-test. */
const char *msg = "compiled with incompatible luaconf.h";
#ifdef LUA_NUMBER_DOUBLE
#ifdef _WIN32
if (b == (UBits)1610612736L)
msg = "use D3DCREATE_FPU_PRESERVE with DirectX";
#endif
if (b == (UBits)1127743488L)
msg = "not compiled with SWAPPED_DOUBLE";
#endif
if (BAD_SAR)
msg = "arithmetic right-shift broken";
luaL_error(L, "bit library self-test failed (%s)", msg);
}
#if LUA_VERSION_NUM < 502
luaL_register(L, "bit", bit_funcs);
#else
luaL_newlib(L, bit_funcs);
#endif
return 1;
}
+436 -308
View File
File diff suppressed because it is too large Load Diff
+372 -131
View File
@@ -7,14 +7,38 @@
#include "lua.h"
#include "lauxlib.h"
#define LUACMSGPACK_VERSION "lua-cmsgpack 0.3.0"
#define LUACMSGPACK_NAME "cmsgpack"
#define LUACMSGPACK_SAFE_NAME "cmsgpack_safe"
#define LUACMSGPACK_VERSION "lua-cmsgpack 0.4.0"
#define LUACMSGPACK_COPYRIGHT "Copyright (C) 2012, Salvatore Sanfilippo"
#define LUACMSGPACK_DESCRIPTION "MessagePack C implementation for Lua"
#define LUACMSGPACK_MAX_NESTING 16 /* Max tables nesting. */
/* Allows a preprocessor directive to override MAX_NESTING */
#ifndef LUACMSGPACK_MAX_NESTING
#define LUACMSGPACK_MAX_NESTING 16 /* Max tables nesting. */
#endif
/* ==============================================================================
* MessagePack implementation and bindings for Lua 5.1.
/* Check if float or double can be an integer without loss of precision */
#define IS_INT_TYPE_EQUIVALENT(x, T) (!isinf(x) && (T)(x) == (x))
#define IS_INT64_EQUIVALENT(x) IS_INT_TYPE_EQUIVALENT(x, int64_t)
#define IS_INT_EQUIVALENT(x) IS_INT_TYPE_EQUIVALENT(x, int)
/* If size of pointer is equal to a 4 byte integer, we're on 32 bits. */
#if UINTPTR_MAX == UINT_MAX
#define BITS_32 1
#else
#define BITS_32 0
#endif
#if BITS_32
#define lua_pushunsigned(L, n) lua_pushnumber(L, n)
#else
#define lua_pushunsigned(L, n) lua_pushinteger(L, n)
#endif
/* =============================================================================
* MessagePack implementation and bindings for Lua 5.1/5.2.
* Copyright(C) 2012 Salvatore Sanfilippo <antirez@gmail.com>
*
* http://github.com/antirez/lua-cmsgpack
@@ -29,23 +53,27 @@
* 20-Feb-2012 (ver 0.2.0): Tables encoding improved.
* 20-Feb-2012 (ver 0.2.1): Minor bug fixing.
* 20-Feb-2012 (ver 0.3.0): Module renamed lua-cmsgpack (was lua-msgpack).
* ============================================================================ */
* 04-Apr-2014 (ver 0.3.1): Lua 5.2 support and minor bug fix.
* 07-Apr-2014 (ver 0.4.0): Multiple pack/unpack, lua allocator, efficiency.
* ========================================================================== */
/* --------------------------- Endian conversion --------------------------------
* We use it only for floats and doubles, all the other conversions are performed
/* -------------------------- Endian conversion --------------------------------
* We use it only for floats and doubles, all the other conversions performed
* in an endian independent fashion. So the only thing we need is a function
* that swaps a binary string if the arch is little endian (and left it untouched
* that swaps a binary string if arch is little endian (and left it untouched
* otherwise). */
/* Reverse memory bytes if arch is little endian. Given the conceptual
* simplicity of the Lua build system we prefer to check for endianess at runtime.
* 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) {
unsigned char *p = ptr, *e = p+len-1, aux;
void memrevifle(void *ptr, size_t len) {
unsigned char *p = (unsigned char *)ptr,
*e = (unsigned char *)p+len-1,
aux;
int test = 1;
unsigned char *testp = (unsigned char*) &test;
if (testp[0] == 0) return; /* Big endian, nothign to do. */
if (testp[0] == 0) return; /* Big endian, nothing to do. */
len /= 2;
while(len--) {
aux = *p;
@@ -56,20 +84,34 @@ static void memrevifle(void *ptr, size_t len) {
}
}
/* ----------------------------- String buffer ----------------------------------
* This is a simple implementation of string buffers. The only opereation
/* ---------------------------- String buffer ----------------------------------
* This is a simple implementation of string buffers. The only operation
* supported is creating empty buffers and appending bytes to it.
* The string buffer uses 2x preallocation on every realloc for O(N) append
* behavior. */
typedef struct mp_buf {
lua_State *L;
unsigned char *b;
size_t len, free;
} mp_buf;
static mp_buf *mp_buf_new(void) {
mp_buf *buf = malloc(sizeof(*buf));
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;
local_realloc = lua_getallocf(L, &ud);
return local_realloc(ud, target, osize, nsize);
}
mp_buf *mp_buf_new(lua_State *L) {
mp_buf *buf = NULL;
/* Old size = 0; new size = sizeof(*buf) */
buf = (mp_buf*)mp_realloc(L, NULL, 0, sizeof(*buf));
buf->L = L;
buf->b = NULL;
buf->len = buf->free = 0;
return buf;
@@ -79,7 +121,7 @@ void mp_buf_append(mp_buf *buf, const unsigned char *s, size_t len) {
if (buf->free < len) {
size_t newlen = buf->len+len;
buf->b = realloc(buf->b,newlen*2);
buf->b = (unsigned char*)mp_realloc(buf->L, buf->b, buf->len, newlen*2);
buf->free = newlen;
}
memcpy(buf->b+buf->len,s,len);
@@ -88,11 +130,11 @@ void mp_buf_append(mp_buf *buf, const unsigned char *s, size_t len) {
}
void mp_buf_free(mp_buf *buf) {
free(buf->b);
free(buf);
mp_realloc(buf->L, buf->b, buf->len, 0); /* realloc to 0 = free */
mp_realloc(buf->L, buf, sizeof(*buf), 0);
}
/* ------------------------------ String cursor ----------------------------------
/* ---------------------------- String cursor ----------------------------------
* This simple data structure is used for parsing. Basically you create a cursor
* using a string pointer and a length, then it is possible to access the
* current string position with cursor->p, check the remaining length
@@ -102,7 +144,7 @@ void mp_buf_free(mp_buf *buf) {
* be used to report errors. */
#define MP_CUR_ERROR_NONE 0
#define MP_CUR_ERROR_EOF 1 /* Not enough data to complete the opereation. */
#define MP_CUR_ERROR_EOF 1 /* Not enough data to complete operation. */
#define MP_CUR_ERROR_BADFMT 2 /* Bad data format */
typedef struct mp_cur {
@@ -111,22 +153,15 @@ typedef struct mp_cur {
int err;
} mp_cur;
static mp_cur *mp_cur_new(const unsigned char *s, size_t len) {
mp_cur *cursor = malloc(sizeof(*cursor));
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;
return cursor;
}
static void mp_cur_free(mp_cur *cursor) {
free(cursor);
}
#define mp_cur_consume(_c,_len) do { _c->p += _len; _c->left -= _len; } while(0)
/* When there is not enough room we set an error in the cursor and return, this
/* When there is not enough room we set an error in the cursor and return. This
* is very common across the code so we have a macro to make the code look
* a bit simpler. */
#define mp_cur_need(_c,_len) do { \
@@ -136,15 +171,19 @@ static void mp_cur_free(mp_cur *cursor) {
} \
} while(0)
/* --------------------------- Low level MP encoding -------------------------- */
/* ------------------------- 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;
@@ -152,10 +191,10 @@ static void mp_encode_bytes(mp_buf *buf, const unsigned char *s, size_t len) {
hdrlen = 3;
} else {
hdr[0] = 0xdb;
hdr[1] = (len&0xff000000)>>24;
hdr[2] = (len&0xff0000)>>16;
hdr[3] = (len&0xff00)>>8;
hdr[4] = len&0xff;
hdr[1] = (unsigned char)((len&0xff000000)>>24);
hdr[2] = (unsigned char)((len & 0xff0000) >> 16);
hdr[3] = (unsigned char)((len & 0xff00) >> 8);
hdr[4] = (unsigned char)(len & 0xff);
hdrlen = 5;
}
mp_buf_append(buf,hdr,hdrlen);
@@ -163,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;
@@ -181,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;
@@ -219,7 +258,7 @@ static void mp_encode_int(mp_buf *buf, int64_t n) {
}
} else {
if (n >= -32) {
b[0] = ((char)n); /* negative fixnum */
b[0] = ((signed char)n); /* negative fixnum */
enclen = 1;
} else if (n >= -128) {
b[0] = 0xd0; /* int 8 */
@@ -253,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;
@@ -276,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;
@@ -299,9 +338,9 @@ static void mp_encode_map(mp_buf *buf, int64_t n) {
mp_buf_append(buf,b,enclen);
}
/* ----------------------------- Lua types encoding --------------------------- */
/* --------------------------- 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;
@@ -309,26 +348,43 @@ 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);
}
static void mp_encode_lua_number(lua_State *L, mp_buf *buf) {
/* Lua 5.3 has a built in 64-bit integer type */
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
lua_Integer i = lua_tointeger(L,-1);
#endif
mp_encode_int(buf, (int64_t)i);
}
/* 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 */
void mp_encode_lua_number(lua_State *L, mp_buf *buf) {
lua_Number n = lua_tonumber(L,-1);
if (floor(n) != n) {
mp_encode_double(buf,(double)n);
if (IS_INT64_EQUIVALENT(n)) {
mp_encode_lua_integer(L, buf);
} else {
mp_encode_int(buf,(int64_t)n);
mp_encode_double(buf,(double)n);
}
}
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
size_t len = lua_rawlen(L,-1), j;
#endif
mp_encode_array(buf,len);
for (j = 1; j <= len; j++) {
@@ -339,13 +395,13 @@ 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
* Lua API, we need to iterate a first time. Note that an alternative
* would be to do a single run, and then hack the buffer to insert the
* map opcodes for message pack. Too hachish for this lib. */
* map opcodes for message pack. Too hackish for this lib. */
lua_pushnil(L);
while(lua_next(L,-2)) {
lua_pop(L,1); /* remove value, keep key for next iteration. */
@@ -366,80 +422,131 @@ 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) {
long count = 0, max = 0, idx = 0;
int table_is_an_array(lua_State *L) {
int count = 0, max = 0;
#if LUA_VERSION_NUM < 503
lua_Number n;
#else
lua_Integer n;
#endif
/* Stack top on function entry */
int stacktop;
stacktop = lua_gettop(L);
lua_pushnil(L);
while(lua_next(L,-2)) {
/* Stack: ... key value */
lua_pop(L,1); /* Stack: ... key */
if (lua_type(L,-1) != LUA_TNUMBER) goto not_array;
n = lua_tonumber(L,-1);
idx = n;
if (idx != n || idx < 1) goto not_array;
/* The <= 0 check is valid here because we're comparing indexes. */
#if LUA_VERSION_NUM < 503
if ((LUA_TNUMBER != lua_type(L,-1)) || (n = lua_tonumber(L, -1)) <= 0 ||
!IS_INT_EQUIVALENT(n))
#else
if (!lua_isinteger(L,-1) || (n = lua_tointeger(L, -1)) <= 0)
#endif
{
lua_settop(L, stacktop);
return 0;
}
max = (n > max ? n : max);
count++;
max = idx;
}
/* We have the total number of elements in "count". Also we have
* the max index encountered in "idx". We can't reach this code
* the max index encountered in "max". We can't reach this code
* if there are indexes <= 0. If you also note that there can not be
* repeated keys into a table, you have that if idx==count you are sure
* repeated keys into a table, you have that if max==count you are sure
* that there are all the keys form 1 to count (both included). */
return idx == count;
not_array:
lua_pop(L,1);
return 0;
lua_settop(L, stacktop);
return max == count;
}
/* 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;
b[0] = 0xc0;
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 specfiied maximum depth, so that
/* Limit the encoding of nested tables to a specified maximum depth, so that
* we survive when called against circular references in tables. */
if (t == LUA_TTABLE && level == LUACMSGPACK_MAX_NESTING) t = LUA_TNIL;
switch(t) {
case LUA_TSTRING: mp_encode_lua_string(L,buf); break;
case LUA_TBOOLEAN: mp_encode_lua_bool(L,buf); break;
case LUA_TNUMBER: mp_encode_lua_number(L,buf); break;
case LUA_TNUMBER:
#if LUA_VERSION_NUM < 503
mp_encode_lua_number(L,buf); break;
#else
if (lua_isinteger(L, -1)) {
mp_encode_lua_integer(L, buf);
} else {
mp_encode_lua_number(L, buf);
}
break;
#endif
case LUA_TTABLE: mp_encode_lua_table(L,buf,level); break;
default: mp_encode_lua_null(L,buf); break;
}
lua_pop(L,1);
}
static int mp_pack(lua_State *L) {
mp_buf *buf = mp_buf_new();
/*
* Packs all arguments as a stream for multiple upacking later.
* Returns error if no arguments provided.
*/
int mp_pack(lua_State *L) {
int nargs = lua_gettop(L);
int i;
mp_buf *buf;
mp_encode_lua_type(L,buf,0);
lua_pushlstring(L,(char*)buf->b,buf->len);
if (nargs == 0)
return luaL_argerror(L, 0, "MessagePack pack needs input.");
buf = mp_buf_new(L);
for(i = 1; i <= nargs; i++) {
/* Copy argument i to top of stack for _encode processing;
* the encode function pops it from the stack when complete. */
lua_pushvalue(L, i);
mp_encode_lua_type(L,buf,0);
lua_pushlstring(L,(char*)buf->b,buf->len);
/* Reuse the buffer for the next operation by
* setting its free count to the total buffer size
* and the current position to zero. */
buf->free += buf->len;
buf->len = 0;
}
mp_buf_free(buf);
/* Concatenate all nargs buffers together */
lua_concat(L, nargs);
return 1;
}
/* --------------------------------- Decoding --------------------------------- */
/* ------------------------------- Decoding --------------------------------- */
void mp_decode_to_lua_type(lua_State *L, mp_cur *c);
void mp_decode_to_lua_array(lua_State *L, mp_cur *c, size_t len) {
assert(len <= UINT_MAX);
int index = 1;
lua_newtable(L);
@@ -452,6 +559,7 @@ void mp_decode_to_lua_array(lua_State *L, mp_cur *c, size_t len) {
}
void mp_decode_to_lua_hash(lua_State *L, mp_cur *c, size_t len) {
assert(len <= UINT_MAX);
lua_newtable(L);
while(len--) {
mp_decode_to_lua_type(L,c); /* key */
@@ -466,34 +574,44 @@ void mp_decode_to_lua_hash(lua_State *L, mp_cur *c, size_t len) {
* a Lua type, that is left as the only result on the stack. */
void mp_decode_to_lua_type(lua_State *L, mp_cur *c) {
mp_cur_need(c,1);
/* If we return more than 18 elements, we must resize the stack to
* fit all our return values. But, there is no way to
* determine how many objects a msgpack will unpack to up front, so
* we request a +1 larger stack on each iteration (noop if stack is
* big enough, and when stack does require resize it doubles in size) */
luaL_checkstack(L, 1,
"too many return values at once; "
"use unpack_one or unpack_limit instead.");
switch(c->p[0]) {
case 0xcc: /* uint 8 */
mp_cur_need(c,2);
lua_pushnumber(L,c->p[1]);
lua_pushunsigned(L,c->p[1]);
mp_cur_consume(c,2);
break;
case 0xd0: /* int 8 */
mp_cur_need(c,2);
lua_pushnumber(L,(char)c->p[1]);
lua_pushinteger(L,(signed char)c->p[1]);
mp_cur_consume(c,2);
break;
case 0xcd: /* uint 16 */
mp_cur_need(c,3);
lua_pushnumber(L,
lua_pushunsigned(L,
(c->p[1] << 8) |
c->p[2]);
mp_cur_consume(c,3);
break;
case 0xd1: /* int 16 */
mp_cur_need(c,3);
lua_pushnumber(L,(int16_t)
lua_pushinteger(L,(int16_t)
(c->p[1] << 8) |
c->p[2]);
mp_cur_consume(c,3);
break;
case 0xce: /* uint 32 */
mp_cur_need(c,5);
lua_pushnumber(L,
lua_pushunsigned(L,
((uint32_t)c->p[1] << 24) |
((uint32_t)c->p[2] << 16) |
((uint32_t)c->p[3] << 8) |
@@ -502,7 +620,7 @@ void mp_decode_to_lua_type(lua_State *L, mp_cur *c) {
break;
case 0xd2: /* int 32 */
mp_cur_need(c,5);
lua_pushnumber(L,
lua_pushinteger(L,
((int32_t)c->p[1] << 24) |
((int32_t)c->p[2] << 16) |
((int32_t)c->p[3] << 8) |
@@ -511,7 +629,7 @@ void mp_decode_to_lua_type(lua_State *L, mp_cur *c) {
break;
case 0xcf: /* uint 64 */
mp_cur_need(c,9);
lua_pushnumber(L,
lua_pushunsigned(L,
((uint64_t)c->p[1] << 56) |
((uint64_t)c->p[2] << 48) |
((uint64_t)c->p[3] << 40) |
@@ -524,7 +642,11 @@ void mp_decode_to_lua_type(lua_State *L, mp_cur *c) {
break;
case 0xd3: /* int 64 */
mp_cur_need(c,9);
#if LUA_VERSION_NUM < 503
lua_pushnumber(L,
#else
lua_pushinteger(L,
#endif
((int64_t)c->p[1] << 56) |
((int64_t)c->p[2] << 48) |
((int64_t)c->p[3] << 40) |
@@ -569,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);
{
@@ -581,13 +712,14 @@ void mp_decode_to_lua_type(lua_State *L, mp_cur *c) {
case 0xdb: /* raw 32 */
mp_cur_need(c,5);
{
size_t l = (c->p[1] << 24) |
(c->p[2] << 16) |
(c->p[3] << 8) |
c->p[4];
mp_cur_need(c,5+l);
lua_pushlstring(L,(char*)c->p+5,l);
mp_cur_consume(c,5+l);
size_t l = ((size_t)c->p[1] << 24) |
((size_t)c->p[2] << 16) |
((size_t)c->p[3] << 8) |
(size_t)c->p[4];
mp_cur_consume(c,5);
mp_cur_need(c,l);
lua_pushlstring(L,(char*)c->p,l);
mp_cur_consume(c,l);
}
break;
case 0xdc: /* array 16 */
@@ -601,10 +733,10 @@ void mp_decode_to_lua_type(lua_State *L, mp_cur *c) {
case 0xdd: /* array 32 */
mp_cur_need(c,5);
{
size_t l = (c->p[1] << 24) |
(c->p[2] << 16) |
(c->p[3] << 8) |
c->p[4];
size_t l = ((size_t)c->p[1] << 24) |
((size_t)c->p[2] << 16) |
((size_t)c->p[3] << 8) |
(size_t)c->p[4];
mp_cur_consume(c,5);
mp_decode_to_lua_array(L,c,l);
}
@@ -620,20 +752,20 @@ void mp_decode_to_lua_type(lua_State *L, mp_cur *c) {
case 0xdf: /* map 32 */
mp_cur_need(c,5);
{
size_t l = (c->p[1] << 24) |
(c->p[2] << 16) |
(c->p[3] << 8) |
c->p[4];
size_t l = ((size_t)c->p[1] << 24) |
((size_t)c->p[2] << 16) |
((size_t)c->p[3] << 8) |
(size_t)c->p[4];
mp_cur_consume(c,5);
mp_decode_to_lua_hash(L,c,l);
}
break;
default: /* types that can't be idenitified by first byte value. */
if ((c->p[0] & 0x80) == 0) { /* positive fixnum */
lua_pushnumber(L,c->p[0]);
lua_pushunsigned(L,c->p[0]);
mp_cur_consume(c,1);
} else if ((c->p[0] & 0xe0) == 0xe0) { /* negative fixnum */
lua_pushnumber(L,(signed char)c->p[0]);
lua_pushinteger(L,(signed char)c->p[0]);
mp_cur_consume(c,1);
} else if ((c->p[0] & 0xe0) == 0xa0) { /* fix raw */
size_t l = c->p[0] & 0x1f;
@@ -654,54 +786,163 @@ void mp_decode_to_lua_type(lua_State *L, mp_cur *c) {
}
}
static int mp_unpack(lua_State *L) {
int mp_unpack_full(lua_State *L, int limit, int offset) {
size_t len;
const unsigned char *s;
mp_cur *c;
const char *s;
mp_cur c;
int cnt; /* Number of objects unpacked */
int decode_all = (!limit && !offset);
if (!lua_isstring(L,-1)) {
lua_pushstring(L,"MessagePack decoding needs a string as input.");
lua_error(L);
s = luaL_checklstring(L,1,&len); /* if no match, exits */
if (offset < 0 || limit < 0) /* requesting negative off or lim is invalid */
return luaL_error(L,
"Invalid request to unpack with offset of %d and limit of %d.",
offset, len);
else if (offset > len)
return luaL_error(L,
"Start offset %d greater than input length %d.", offset, len);
if (decode_all) limit = INT_MAX;
mp_cur_init(&c,(const unsigned char *)s+offset,len-offset);
/* We loop over the decode because this could be a stream
* of multiple top-level values serialized together */
for(cnt = 0; c.left > 0 && cnt < limit; cnt++) {
mp_decode_to_lua_type(L,&c);
if (c.err == MP_CUR_ERROR_EOF) {
return luaL_error(L,"Missing bytes in input.");
} else if (c.err == MP_CUR_ERROR_BADFMT) {
return luaL_error(L,"Bad data format in input.");
}
}
s = (const unsigned char*) lua_tolstring(L,-1,&len);
c = mp_cur_new(s,len);
mp_decode_to_lua_type(L,c);
if (c->err == MP_CUR_ERROR_EOF) {
mp_cur_free(c);
lua_pushstring(L,"Missing bytes in input.");
lua_error(L);
} else if (c->err == MP_CUR_ERROR_BADFMT) {
mp_cur_free(c);
lua_pushstring(L,"Bad data format in input.");
lua_error(L);
} else if (c->left != 0) {
mp_cur_free(c);
lua_pushstring(L,"Extra bytes in input.");
lua_error(L);
if (!decode_all) {
/* c->left is the remaining size of the input buffer.
* subtract the entire buffer size from the unprocessed size
* to get our next start offset */
int offset = (int)(len - c.left); /* UPSTREAM_ISSUE: missing (int) cast */
/* Return offset -1 when we have have processed the entire buffer. */
lua_pushinteger(L, c.left == 0 ? -1 : offset);
/* Results are returned with the arg elements still
* in place. Lua takes care of only returning
* elements above the args for us.
* In this case, we have one arg on the stack
* for this function, so we insert our first return
* value at position 2. */
lua_insert(L, 2);
cnt += 1; /* increase return count by one to make room for offset */
}
mp_cur_free(c);
return 1;
return cnt;
}
/* ---------------------------------------------------------------------------- */
int mp_unpack(lua_State *L) {
return mp_unpack_full(L, 0, 0);
}
static const struct luaL_reg thislib[] = {
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);
}
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 */
lua_pop(L, lua_gettop(L)-1);
return mp_unpack_full(L, limit, offset);
}
int mp_safe(lua_State *L) {
int argc, err, total_results;
argc = lua_gettop(L);
/* This adds our function to the bottom of the stack
* (the "call this function" position) */
lua_pushvalue(L, lua_upvalueindex(1));
lua_insert(L, 1);
err = lua_pcall(L, argc, LUA_MULTRET, 0);
total_results = lua_gettop(L);
if (!err) {
return total_results;
} else {
lua_pushnil(L);
lua_insert(L,-2);
return 2;
}
}
/* -------------------------------------------------------------------------- */
const struct luaL_Reg cmds[] = {
{"pack", mp_pack},
{"unpack", mp_unpack},
{NULL, NULL}
{"unpack_one", mp_unpack_one},
{"unpack_limit", mp_unpack_limit},
{0}
};
LUALIB_API int luaopen_cmsgpack (lua_State *L) {
luaL_register(L, "cmsgpack", thislib);
int luaopen_create(lua_State *L) {
int i;
/* Manually construct our module table instead of
* relying on _register or _newlib */
lua_newtable(L);
for (i = 0; i < (sizeof(cmds)/sizeof(*cmds) - 1); i++) {
lua_pushcfunction(L, cmds[i].func);
lua_setfield(L, -2, cmds[i].name);
}
/* Add metadata */
lua_pushliteral(L, LUACMSGPACK_NAME);
lua_setfield(L, -2, "_NAME");
lua_pushliteral(L, LUACMSGPACK_VERSION);
lua_setfield(L, -2, "_VERSION");
lua_pushliteral(L, LUACMSGPACK_COPYRIGHT);
lua_setfield(L, -2, "_COPYRIGHT");
lua_pushliteral(L, LUACMSGPACK_DESCRIPTION);
lua_setfield(L, -2, "_DESCRIPTION");
lua_setfield(L, -2, "_DESCRIPTION");
return 1;
}
LUALIB_API int luaopen_cmsgpack(lua_State *L) {
luaopen_create(L);
#if LUA_VERSION_NUM < 502
/* Register name globally for 5.1 */
lua_pushvalue(L, -1);
lua_setglobal(L, LUACMSGPACK_NAME);
#endif
return 1;
}
LUALIB_API int luaopen_cmsgpack_safe(lua_State *L) {
int i;
luaopen_cmsgpack(L);
/* Wrap all functions in the safe handler */
for (i = 0; i < (sizeof(cmds)/sizeof(*cmds) - 1); i++) {
lua_getfield(L, -1, cmds[i].name);
lua_pushcclosure(L, mp_safe, 1);
lua_setfield(L, -2, cmds[i].name);
}
#if LUA_VERSION_NUM < 502
/* Register name globally for 5.1 */
lua_pushvalue(L, -1);
lua_setglobal(L, LUACMSGPACK_SAFE_NAME);
#endif
return 1;
}
+5 -5
View File
@@ -136,7 +136,7 @@ static int gettoalign (size_t len, Header *h, int opt, size_t size) {
if (size == 0 || opt == 'c') return 0;
if (size > (size_t)h->align)
size = h->align; /* respect max. alignment */
return (size - (len & (size - 1))) & (size - 1);
return (int)((size - (len & (size - 1))) & (size - 1));
}
@@ -221,7 +221,7 @@ static int b_pack (lua_State *L) {
switch (opt) {
case 'b': case 'B': case 'h': case 'H':
case 'l': case 'L': case 'T': case 'i': case 'I': { /* integer types */
putinteger(L, &b, arg++, h.endian, size);
putinteger(L, &b, arg++, h.endian, (int)size);
break;
}
case 'x': {
@@ -230,13 +230,13 @@ static int b_pack (lua_State *L) {
}
case 'f': {
float f = (float)luaL_checknumber(L, arg++);
correctbytes((char *)&f, size, h.endian);
correctbytes((char *)&f, (int)size, h.endian);
luaL_addlstring(&b, (char *)&f, size);
break;
}
case 'd': {
double d = luaL_checknumber(L, arg++);
correctbytes((char *)&d, size, h.endian);
correctbytes((char *)&d, (int)size, h.endian);
luaL_addlstring(&b, (char *)&d, size);
break;
}
@@ -306,7 +306,7 @@ static int b_unpack (lua_State *L) {
case 'b': case 'B': case 'h': case 'H':
case 'l': case 'L': case 'T': case 'i': case 'I': { /* integer types */
int issigned = islower(opt);
lua_Number res = getinteger(data+pos, h.endian, issigned, size);
lua_Number res = getinteger(data+pos, h.endian, issigned, (int)size);
lua_pushnumber(L, res);
break;
}
+7 -2
View File
@@ -733,13 +733,13 @@ union luai_Cast { double l_d; long l_l; };
@* in 'string.format'.
@@ LUA_INTFRM_T is the integer type correspoding to the previous length
@* modifier.
** CHANGE them if your system supports long long or does not support long.
** CHANGE them if your system supports PORT_LONGLONG or does not support long.
*/
#if defined(LUA_USELONGLONG)
#define LUA_INTFRMLEN "ll"
#define LUA_INTFRM_T long long
#define LUA_INTFRM_T PORT_LONGLONG
#else
@@ -749,6 +749,11 @@ union luai_Cast { double l_d; long l_l; };
#endif
#ifdef _WIN32
#define snprintf _snprintf
#endif
/* =================================================================== */
+3 -3
View File
@@ -1,6 +1,6 @@
/* strbuf - string buffer routines
/* strbuf - String buffer routines
*
* Copyright (c) 2010-2011 Mark Pulford <mark@kyne.com.au>
* Copyright (c) 2010-2012 Mark Pulford <mark@kyne.com.au>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -29,7 +29,7 @@
#include "strbuf.h"
void die(const char *fmt, ...)
static void die(const char *fmt, ...)
{
va_list arg;
+24 -2
View File
@@ -1,6 +1,6 @@
/* strbuf - String buffer routines
*
* Copyright (c) 2010-2011 Mark Pulford <mark@kyne.com.au>
* Copyright (c) 2010-2012 Mark Pulford <mark@kyne.com.au>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -25,6 +25,12 @@
#include <stdlib.h>
#include <stdarg.h>
#ifdef _WIN32
#include <float.h>
#define inline __inline
#define strncasecmp _strnicmp
#endif
/* Size: Total bytes allocated to *buf
* Length: String length, excluding optional NULL terminator.
* Increment: Allocation increments when resizing the string buffer.
@@ -62,7 +68,9 @@ extern void strbuf_resize(strbuf_t *s, int len);
static int strbuf_empty_length(strbuf_t *s);
static int strbuf_length(strbuf_t *s);
static char *strbuf_string(strbuf_t *s, int *len);
static void strbuf_ensure_empty_length(strbuf_t *s, int len);
static void strbuf_ensure_empty_length(strbuf_t *s, int len);
static char *strbuf_empty_ptr(strbuf_t *s);
static void strbuf_extend_length(strbuf_t *s, int len);
/* Update */
extern void strbuf_append_fmt(strbuf_t *s, int len, const char *fmt, ...);
@@ -72,6 +80,10 @@ extern void strbuf_append_string(strbuf_t *s, const char *str);
static void strbuf_append_char(strbuf_t *s, const char c);
static void strbuf_ensure_null(strbuf_t *s);
#ifdef _WIN32
#define inline __inline
#endif
/* Reset string for before use */
static inline void strbuf_reset(strbuf_t *s)
{
@@ -96,6 +108,16 @@ static inline void strbuf_ensure_empty_length(strbuf_t *s, int len)
strbuf_resize(s, s->length + len);
}
static inline char *strbuf_empty_ptr(strbuf_t *s)
{
return s->buf + s->length;
}
static inline void strbuf_extend_length(strbuf_t *s, int len)
{
s->length += len;
}
static inline int strbuf_length(strbuf_t *s)
{
return s->length;
+11
View File
@@ -0,0 +1,11 @@
Copyright (c) 2006-2015, Salvatore Sanfilippo
Modifications 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.
* Neither the name of Redis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
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 OWNER 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.
+34
View File
@@ -0,0 +1,34 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HiredisExample", "HiredisExample\HiredisExample.vcxproj", "{E1336854-4636-4306-B3A4-F46B4D3B1240}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Win32_Interop", "..\..\src\Win32_Interop\Win32_Interop.vcxproj", "{8C07F811-C81C-432C-B334-1AE6FAECF951}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hiredis", "..\hiredis\hiredis.vcxproj", "{13E85053-54B3-487B-8DDB-3430B1C1B3BF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E1336854-4636-4306-B3A4-F46B4D3B1240}.Debug|x64.ActiveCfg = Debug|x64
{E1336854-4636-4306-B3A4-F46B4D3B1240}.Debug|x64.Build.0 = Debug|x64
{E1336854-4636-4306-B3A4-F46B4D3B1240}.Release|x64.ActiveCfg = Release|x64
{E1336854-4636-4306-B3A4-F46B4D3B1240}.Release|x64.Build.0 = Release|x64
{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}.Release|x64.ActiveCfg = Release|x64
{8C07F811-C81C-432C-B334-1AE6FAECF951}.Release|x64.Build.0 = Release|x64
{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}.Release|x64.ActiveCfg = Release|x64
{13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -0,0 +1,110 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{E1336854-4636-4306-B3A4-F46B4D3B1240}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>HiredisExample</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions);USE_DL_PREFIX;LACKS_STDLIB_H;NO_QFORKIMPL;WIN32_IOCP</PreprocessorDefinitions>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
<AdditionalIncludeDirectories>..\..\..\deps\hiredis\;..\..\deps\hiredis;..\..\src</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions);USE_DL_PREFIX;LACKS_STDLIB_H;NO_QFORKIMPL;WIN32_IOCP</PreprocessorDefinitions>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
<AdditionalIncludeDirectories>..\..\..\deps\hiredis\;..\..\deps\hiredis;..\..\src</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\src\adlist.c" />
<ClCompile Include="..\..\..\src\ae.c" />
<ClCompile Include="..\..\..\src\zmalloc.c" />
<ClCompile Include="example-ae-win.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\src\ae.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Win32_Interop\Win32_Interop.vcxproj">
<Project>{8c07f811-c81c-432c-b334-1ae6faecf951}</Project>
</ProjectReference>
<ProjectReference Include="..\..\hiredis\hiredis.vcxproj">
<Project>{13e85053-54b3-487b-8ddb-3430b1c1b3bf}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,90 @@
#ifdef _WIN32
#include "..\..\src\Win32_Interop\win32fixes.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include "hiredis.h"
#include "async.h"
#include "adapters\ae.h"
/* Put event loop in the global scope, so it can be explicitly stopped */
static aeEventLoop *loop;
static int getCallbackCalls = 0;
void getCallbackContinue(redisAsyncContext *c, void *r, void *privdata) {
redisReply *reply = r;
if (reply == NULL) return;
getCallbackCalls++;
printf("getCallback called %d times.\n", getCallbackCalls);
printf("argv[%s]: %s\n", (char*)privdata, reply->str);
}
void getCallbackEnd(redisAsyncContext *c, void *r, void *privdata) {
redisReply *reply = r;
if (reply == NULL) return;
getCallbackCalls++;
printf("getCallback called %d times.\n", getCallbackCalls);
printf("argv[%s]: %s\n", (char*)privdata, reply->str);
redisAsyncDisconnect(c);
}
void connectCallback(const redisAsyncContext *c, int status) {
if (status != REDIS_OK) {
printf("Error: %s\n", c->errstr);
return;
}
printf("Connected...\n");
}
void disconnectCallback(const redisAsyncContext *c, int status) {
if (status != REDIS_OK) {
printf("Error: %s\n", c->errstr);
return;
}
printf("Disconnected...\n");
aeStop(loop);
}
int main (int argc, char **argv) {
#ifndef _WIN32
signal(SIGPIPE, SIG_IGN);
#endif
#ifdef _WIN32
/* For Win32_IOCP the event loop must be created before the async connect */
loop = aeCreateEventLoop(1024 * 10);
#endif
redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
if (c->err) {
/* Let *c leak for now... */
printf("Error: %s\n", c->errstr);
return 1;
}
#ifndef _WIN32
loop = aeCreateEventLoop(1024*10);
#endif
redisAeAttach(loop, c);
redisAsyncSetConnectCallback(c,connectCallback);
redisAsyncSetDisconnectCallback(c,disconnectCallback);
redisAsyncCommand(c, NULL, NULL, "SET key %s", argv[argc-1], strlen(argv[argc-1]));
for (int i = 0; i < 20000; i++) {
printf("calling get %i times\n", i);
redisAsyncCommand(c, getCallbackContinue, "0", "GET key");
}
redisAsyncCommand(c, getCallbackEnd, "0", "GET key");
aeMain(loop);
return 0;
}
+189
View File
@@ -0,0 +1,189 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{B00D4BB5-44DE-405E-839C-D16F547006CF}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>RedisBenchmark</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>false</LinkIncremental>
<TargetName>redis-benchmark</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>false</LinkIncremental>
<TargetName>redis-benchmark</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<TargetName>redis-benchmark</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<TargetName>redis-benchmark</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32;USE_DL_PREFIX;LACKS_STDLIB_H;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);NO_QFORKIMPL;WIN32_IOCP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\deps\hiredis;$(SolutionDir)..\deps\lua\src</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(OutDir);$(OutDir)lib</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;uuid.lib;hiredis.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<IgnoreSpecificDefaultLibraries>MSVCRT</IgnoreSpecificDefaultLibraries>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32;USE_DL_PREFIX;LACKS_STDLIB_H;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);NO_QFORKIMPL;WIN32_IOCP;_WIN32_WINNT=0x0501</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\deps\hiredis;$(SolutionDir)..\deps\lua\src</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(OutDir);$(OutDir)lib</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;uuid.lib;hiredis.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<IgnoreSpecificDefaultLibraries>MSVCRT</IgnoreSpecificDefaultLibraries>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_OFF_T_DEFINED;_WIN32IOCP;WIN32;USE_DL_PREFIX;LACKS_STDLIB_H;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);WIN32_IOCP;WIN32_IOCP;NO_QFORKIMPL</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\deps\hiredis;$(SolutionDir)..\deps\lua\src</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(OutDir);$(OutDir)lib</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;uuid.lib;hiredis.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_OFF_T_DEFINED;_WIN32IOCP;WIN32;USE_DL_PREFIX;LACKS_STDLIB_H;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);WIN32_IOCP;WIN32_IOCP;NO_QFORKIMPL;_WIN32_WINNT=0x0501</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\deps\hiredis;$(SolutionDir)..\deps\lua\src</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(OutDir);$(OutDir)lib</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;uuid.lib;hiredis.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\src\adlist.c" />
<ClCompile Include="..\..\src\ae.c" />
<ClCompile Include="..\..\src\anet.c" />
<ClCompile Include="..\..\src\redis-benchmark.c" />
<ClCompile Include="..\..\src\sds.c" />
<ClCompile Include="..\..\src\zmalloc.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Win32_Interop\Win32_Interop.vcxproj">
<Project>{8c07f811-c81c-432c-b334-1ae6faecf951}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+171
View File
@@ -0,0 +1,171 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}</ProjectGuid>
<RootNamespace>RedisCheckAof</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetName>redis-check-aof</TargetName>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<TargetName>redis-check-aof</TargetName>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>redis-check-aof</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<TargetName>redis-check-aof</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32;_DEBUG;_CONSOLE;USE_DL_PREFIX;LACKS_STDLIB_H;%(PreprocessorDefinitions);NO_QFORKIMPL;WIN32_IOCP</PreprocessorDefinitions>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>$(SolutionDir)..\deps\lua\src</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)redis-check-aof$(TargetExt)</OutputFile>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<IgnoreSpecificDefaultLibraries>MSVCRT</IgnoreSpecificDefaultLibraries>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32;_DEBUG;_CONSOLE;USE_DL_PREFIX;LACKS_STDLIB_H;%(PreprocessorDefinitions);NO_QFORKIMPL;WIN32_IOCP;_WIN32_WINNT=0x0501</PreprocessorDefinitions>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>$(SolutionDir)..\deps\lua\src</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)redis-check-aof$(TargetExt)</OutputFile>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<IgnoreSpecificDefaultLibraries>MSVCRT</IgnoreSpecificDefaultLibraries>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32;_CONSOLE;%(PreprocessorDefinitions);WIN32_IOCP;USE_DL_PREFIX;LACKS_STDLIB_H;NO_QFORKIMPL</PreprocessorDefinitions>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>$(SolutionDir)..\deps\lua\src</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<OutputFile>$(OutDir)redis-check-aof$(TargetExt)</OutputFile>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32;_CONSOLE;%(PreprocessorDefinitions);WIN32_IOCP;USE_DL_PREFIX;LACKS_STDLIB_H;NO_QFORKIMPL;_WIN32_WINNT=0x0501</PreprocessorDefinitions>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>$(SolutionDir)..\deps\lua\src</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<OutputFile>$(OutDir)redis-check-aof$(TargetExt)</OutputFile>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\src\redis-check-aof.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Win32_Interop\Win32_Interop.vcxproj">
<Project>{8c07f811-c81c-432c-b334-1ae6faecf951}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+175
View File
@@ -0,0 +1,175 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{52193A97-D010-41D6-BF2B-33E8E764E308}</ProjectGuid>
<RootNamespace>RedisCheckDump</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetName>redis-check-dump</TargetName>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<TargetName>redis-check-dump</TargetName>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>redis-check-dump</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<TargetName>redis-check-dump</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32_IOCP;WIN32;USE_DL_PREFIX;LACKS_STDLIB_H;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);NO_QFORKIMPL</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
<AdditionalIncludeDirectories>$(SolutionDir)..\deps\lua\src</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)redis-check-dump$(TargetExt)</OutputFile>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<IgnoreSpecificDefaultLibraries>MSVCRT</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32;USE_DL_PREFIX;LACKS_STDLIB_H;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);NO_QFORKIMPL;WIN32_IOCP;_WIN32_WINNT=0x0501</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
<AdditionalIncludeDirectories>$(SolutionDir)..\deps\lua\src</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)redis-check-dump$(TargetExt)</OutputFile>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<IgnoreSpecificDefaultLibraries>MSVCRT</IgnoreSpecificDefaultLibraries>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Full</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32_IOCP;WIN32;USE_DL_PREFIX;LACKS_STDLIB_H;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);NO_QFORKIMPL</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
<AdditionalIncludeDirectories>$(SolutionDir)..\deps\lua\src</AdditionalIncludeDirectories>
<WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<OutputFile>$(OutDir)redis-check-dump$(TargetExt)</OutputFile>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32;USE_DL_PREFIX;LACKS_STDLIB_H;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);WIN32_IOCP;WIN32_IOCP;NO_QFORKIMPL;_WIN32_WINNT=0x0501</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
<AdditionalIncludeDirectories>$(SolutionDir)..\deps\lua\src</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<OutputFile>$(OutDir)redis-check-dump$(TargetExt)</OutputFile>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\src\crc64.c" />
<ClCompile Include="..\..\src\lzf_c.c" />
<ClCompile Include="..\..\src\lzf_d.c" />
<ClCompile Include="..\..\src\redis-check-dump.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Win32_Interop\Win32_Interop.vcxproj">
<Project>{8c07f811-c81c-432c-b334-1ae6faecf951}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+187
View File
@@ -0,0 +1,187 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{392BBB91-3934-4A56-AF42-65C5728311E8}</ProjectGuid>
<RootNamespace>RedisCli</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetName>redis-cli</TargetName>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<TargetName>redis-cli</TargetName>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>redis-cli</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<TargetName>redis-cli</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(SolutionDir)..\deps\hiredis;$(SolutionDir)..\deps\linenoise;$(SolutionDir)..\deps\lua\src</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32_IOCP;WIN32;USE_DL_PREFIX;LACKS_STDLIB_H;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);NO_QFORKIMPL</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)redis-cli$(TargetExt)</OutputFile>
<AdditionalLibraryDirectories>$(OutDir);$(OutDir)lib</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<IgnoreSpecificDefaultLibraries>MSVCRT</IgnoreSpecificDefaultLibraries>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(SolutionDir)..\deps\hiredis;$(SolutionDir)..\deps\linenoise;$(SolutionDir)..\deps\lua\src</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32;USE_DL_PREFIX;LACKS_STDLIB_H;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);NO_QFORKIMPL;WIN32_IOCP;_WIN32_WINNT=0x0501</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)redis-cli$(TargetExt)</OutputFile>
<AdditionalLibraryDirectories>$(OutDir);$(OutDir)lib</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<IgnoreSpecificDefaultLibraries>MSVCRT</IgnoreSpecificDefaultLibraries>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Full</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(SolutionDir)..\deps\hiredis;$(SolutionDir)..\deps\linenoise;$(SolutionDir)..\deps\lua\src</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32_IOCP;WIN32;USE_DL_PREFIX;LACKS_STDLIB_H;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);NO_QFORKIMPL</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
<WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<OutputFile>$(OutDir)redis-cli$(TargetExt)</OutputFile>
<AdditionalLibraryDirectories>$(OutDir);$(OutDir)lib</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(SolutionDir)..\deps\hiredis;$(SolutionDir)..\deps\linenoise;$(SolutionDir)..\deps\lua\src</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32;USE_DL_PREFIX;LACKS_STDLIB_H;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);WIN32_IOCP;WIN32_IOCP;NO_QFORKIMPL;_WIN32_WINNT=0x0501</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<OutputFile>$(OutDir)redis-cli$(TargetExt)</OutputFile>
<AdditionalLibraryDirectories>$(OutDir);$(OutDir)lib</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\deps\linenoise\linenoise.c" />
<ClCompile Include="..\..\src\adlist.c" />
<ClCompile Include="..\..\src\ae.c" />
<ClCompile Include="..\..\src\anet.c" />
<ClCompile Include="..\..\src\crc64.c" />
<ClCompile Include="..\..\src\redis-cli.c" />
<ClCompile Include="..\..\src\release.c" />
<ClCompile Include="..\..\src\sds.c" />
<ClCompile Include="..\..\src\zmalloc.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Win32_Interop\Win32_Interop.vcxproj">
<Project>{8c07f811-c81c-432c-b334-1ae6faecf951}</Project>
</ProjectReference>
<ProjectReference Include="..\hiredis\hiredis.vcxproj">
<Project>{13e85053-54b3-487b-8ddb-3430b1c1b3bf}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+112
View File
@@ -0,0 +1,112 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RedisServer", "RedisServer.vcxproj", "{46842776-68A5-EC98-6A09-1859BBFC73AA}"
ProjectSection(ProjectDependencies) = postProject
{170B0909-5F75-467F-9501-C99DEC16C6DC} = {170B0909-5F75-467F-9501-C99DEC16C6DC}
{13E85053-54B3-487B-8DDB-3430B1C1B3BF} = {13E85053-54B3-487B-8DDB-3430B1C1B3BF}
{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
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hiredis", "hiredis\hiredis.vcxproj", "{13E85053-54B3-487B-8DDB-3430B1C1B3BF}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RedisBenchmark", "RedisBenchmark\RedisBenchmark.vcxproj", "{B00D4BB5-44DE-405E-839C-D16F547006CF}"
ProjectSection(ProjectDependencies) = postProject
{13E85053-54B3-487B-8DDB-3430B1C1B3BF} = {13E85053-54B3-487B-8DDB-3430B1C1B3BF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RedisCheckAof", "RedisCheckAof\RedisCheckAof.vcxproj", "{A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RedisCheckDump", "RedisCheckDump\RedisCheckDump.vcxproj", "{52193A97-D010-41D6-BF2B-33E8E764E308}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RedisCli", "RedisCli\RedisCli.vcxproj", "{392BBB91-3934-4A56-AF42-65C5728311E8}"
ProjectSection(ProjectDependencies) = postProject
{13E85053-54B3-487B-8DDB-3430B1C1B3BF} = {13E85053-54B3-487B-8DDB-3430B1C1B3BF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lua", "lua\lua\lua.vcxproj", "{170B0909-5F75-467F-9501-C99DEC16C6DC}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Win32_Interop", "..\src\Win32_Interop\Win32_Interop.vcxproj", "{8C07F811-C81C-432C-B334-1AE6FAECF951}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{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|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|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|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|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|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|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|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|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|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|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|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|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|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|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|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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
+282
View File
@@ -0,0 +1,282 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{46842776-68A5-EC98-6A09-1859BBFC73AA}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CLRSupport>false</CLRSupport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
<CLRSupport>false</CLRSupport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>false</LinkIncremental>
<TargetName>redis-server</TargetName>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>false</LinkIncremental>
<TargetName>redis-server</TargetName>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<TargetName>redis-server</TargetName>
<GenerateManifest>false</GenerateManifest>
<CustomBuildAfterTargets>Build</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<TargetName>redis-server</TargetName>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32_IOCP;WIN32;USE_DL_PREFIX;LACKS_STDLIB_H;_DEBUG;_CONSOLE;__x86_64__;%(PreprocessorDefinitions);USE_DLMALLOC</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\deps\lua\src;$(SolutionDir)..\deps\hiredis</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<DisableSpecificWarnings>4996;4146</DisableSpecificWarnings>
<WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<AdditionalLibraryDirectories>$(OutDir);$(OutDir)lib</AdditionalLibraryDirectories>
<AdditionalDependencies>psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;advapi32.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<IgnoreSpecificDefaultLibraries>MSVCRT.lib</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32;USE_DL_PREFIX;LACKS_STDLIB_H;_DEBUG;_CONSOLE;__x86_64__;%(PreprocessorDefinitions);USE_DLMALLOC;WIN32_IOCP;_WIN32_WINNT=0x0501</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\deps\lua\src;$(SolutionDir)..\deps\hiredis</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<DisableSpecificWarnings>4996;4146</DisableSpecificWarnings>
<WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<AdditionalLibraryDirectories>$(OutDir);$(OutDir)lib</AdditionalLibraryDirectories>
<AdditionalDependencies>psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;advapi32.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<IgnoreSpecificDefaultLibraries>MSVCRT.lib</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32_IOCP;WIN32;USE_DL_PREFIX;LACKS_STDLIB_H;NDEBUG;_CONSOLE;__x86_64__;%(PreprocessorDefinitions);USE_DLMALLOC</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\deps\lua\src;$(SolutionDir)..\deps\hiredis</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4996;4146</DisableSpecificWarnings>
<WholeProgramOptimization>true</WholeProgramOptimization>
<Optimization>Full</Optimization>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(OutDir);$(OutDir)lib</AdditionalLibraryDirectories>
<AdditionalDependencies>psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;advapi32.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
<CustomBuildStep>
<Command>
</Command>
<Inputs>
</Inputs>
</CustomBuildStep>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>_OFF_T_DEFINED;_WIN32IOCP;WIN32;USE_DL_PREFIX;LACKS_STDLIB_H;NDEBUG;_CONSOLE;__x86_64__;%(PreprocessorDefinitions);WIN32_IOCP;USE_DLMALLOC;_WIN32_WINNT=0x0501</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\deps\lua\src;$(SolutionDir)..\deps\hiredis</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4996;4146</DisableSpecificWarnings>
<WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(OutDir);$(OutDir)lib</AdditionalLibraryDirectories>
<AdditionalDependencies>psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;advapi32.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\src\adlist.c" />
<ClCompile Include="..\src\ae.c" />
<ClCompile Include="..\src\anet.c" />
<ClCompile Include="..\src\aof.c" />
<ClCompile Include="..\src\bio.c" />
<ClCompile Include="..\src\bitops.c" />
<ClCompile Include="..\src\config.c" />
<ClCompile Include="..\src\crc64.c" />
<ClCompile Include="..\src\db.c" />
<ClCompile Include="..\src\debug.c" />
<ClCompile Include="..\src\dict.c" />
<ClCompile Include="..\src\endianconv.c" />
<ClCompile Include="..\src\hyperloglog.c" />
<ClCompile Include="..\src\intset.c" />
<ClCompile Include="..\src\latency.c" />
<ClCompile Include="..\src\lzf_c.c" />
<ClCompile Include="..\src\lzf_d.c" />
<ClCompile Include="..\src\memtest.c" />
<ClCompile Include="..\src\migrate.c" />
<ClCompile Include="..\src\multi.c" />
<ClCompile Include="..\src\networking.c" />
<ClCompile Include="..\src\notify.c" />
<ClCompile Include="..\src\object.c" />
<ClCompile Include="..\src\pqsort.c" />
<ClCompile Include="..\src\pubsub.c" />
<ClCompile Include="..\src\rand.c" />
<ClCompile Include="..\src\rdb.c" />
<ClCompile Include="..\src\redis.c" />
<ClCompile Include="..\src\release.c" />
<ClCompile Include="..\src\replication.c" />
<ClCompile Include="..\src\rio.c" />
<ClCompile Include="..\src\scripting.c" />
<ClCompile Include="..\src\sds.c" />
<ClCompile Include="..\src\sentinel.c" />
<ClCompile Include="..\src\sha1.c" />
<ClCompile Include="..\src\slowlog.c" />
<ClCompile Include="..\src\sort.c" />
<ClCompile Include="..\src\sparkline.c" />
<ClCompile Include="..\src\syncio.c" />
<ClCompile Include="..\src\t_hash.c" />
<ClCompile Include="..\src\t_list.c" />
<ClCompile Include="..\src\t_set.c" />
<ClCompile Include="..\src\t_string.c" />
<ClCompile Include="..\src\t_zset.c" />
<ClCompile Include="..\src\util.c" />
<ClCompile Include="..\src\ziplist.c" />
<ClCompile Include="..\src\zipmap.c" />
<ClCompile Include="..\src\zmalloc.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\adlist.h" />
<ClInclude Include="..\src\ae.h" />
<ClInclude Include="..\src\anet.h" />
<ClInclude Include="..\src\bio.h" />
<ClInclude Include="..\src\config.h" />
<ClInclude Include="..\src\dict.h" />
<ClInclude Include="..\src\endianconv.h" />
<ClInclude Include="..\src\fmacros.h" />
<ClInclude Include="..\src\help.h" />
<ClInclude Include="..\src\intset.h" />
<ClInclude Include="..\src\latency.h" />
<ClInclude Include="..\src\lzf.h" />
<ClInclude Include="..\src\lzfP.h" />
<ClInclude Include="..\src\pqsort.h" />
<ClInclude Include="..\src\rand.h" />
<ClInclude Include="..\src\rdb.h" />
<ClInclude Include="..\src\redis.h" />
<ClInclude Include="..\src\rio.h" />
<ClInclude Include="..\src\sds.h" />
<ClInclude Include="..\src\sha1.h" />
<ClInclude Include="..\src\slowlog.h" />
<ClInclude Include="..\src\solarisfixes.h" />
<ClInclude Include="..\src\sparkline.h" />
<ClInclude Include="..\src\testhelp.h" />
<ClInclude Include="..\src\util.h" />
<ClInclude Include="..\src\version.h" />
<ClInclude Include="..\src\ziplist.h" />
<ClInclude Include="..\src\zipmap.h" />
<ClInclude Include="..\src\zmalloc.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\src\Win32_Interop\Win32_Interop.vcxproj">
<Project>{8c07f811-c81c-432c-b334-1ae6faecf951}</Project>
</ProjectReference>
<ProjectReference Include="hiredis\hiredis.vcxproj">
<Project>{13e85053-54b3-487b-8ddb-3430b1c1b3bf}</Project>
</ProjectReference>
<ProjectReference Include="lua\lua\lua.vcxproj">
<Project>{170b0909-5f75-467f-9501-c99dec16c6dc}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Resource Include="..\src\Win32_Interop\resources\EventLog.res" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
+154
View File
@@ -0,0 +1,154 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Compression;
using System.Xml;
using System.Reflection;
using System.Diagnostics;
namespace ReleasePackagingTool
{
class Program
{
static string rootPath;
static string versionReplacementText = "CurrentRedisVersion";
static void Main(string[] args)
{
try
{
Program p = new Program();
string assemblyDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
rootPath = Path.GetFullPath(Path.Combine(assemblyDirectory, @"..\..\..\..\..\"));
string version;
version = p.GetRedisVersion();
p.UpdateNuSpecFiles(version);
p.BuildReleasePackage(version);
Console.Write("Release packaging complete.");
Environment.ExitCode = 0;
}
catch(Exception ex)
{
Console.WriteLine("Error. Failed to finish release packaging.\n" + ex.ToString());
Environment.ExitCode = -1;
}
}
string GetRedisVersion()
{
TextReader tr = File.OpenText(Path.Combine(rootPath, @"src\version.h"));
string line = tr.ReadLine();
int start = line.IndexOf('\"');
int last = line.LastIndexOf('\"');
return line.Substring(start + 1, last - start - 1);
}
void ForceFileErase(string file)
{
if (File.Exists(file))
{
File.Delete(file);
}
}
void CreateTextFileFromTemplate(string templatePath, string documentPath, string toReplace, string replaceWith )
{
string replacedText;
using (TextReader trTemplate = File.OpenText(templatePath) )
{
string templateText = trTemplate.ReadToEnd();
replacedText = templateText.Replace(toReplace, replaceWith);
}
ForceFileErase(documentPath);
using (TextWriter twDoc = File.CreateText(documentPath))
{
twDoc.Write(replacedText);
twDoc.Close();
}
}
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");
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");
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);
string executablesRoot = Path.Combine(rootPath, @"msvs\x64\Release");
List<string> executableNames = new List<string>()
{
"redis-benchmark.exe",
"redis-check-aof.exe",
"redis-check-dump.exe",
"redis-cli.exe",
"redis-server.exe"
};
List<string> symbolNames = new List<string>()
{
"redis-benchmark.pdb",
"redis-check-aof.pdb",
"redis-check-dump.pdb",
"redis-cli.pdb",
"redis-server.pdb"
};
List<string> dependencyNames = new List<string>()
{
"EventLog.dll"
};
string documentsRoot = Path.Combine(rootPath, @"msvs\setups\documentation");
List<string> docuementNames = new List<string>()
{
"Redis on Windows.docx",
"Redis on Windows Release Notes.docx",
"Windows Service Documentation.docx",
"redis.windows.conf",
"redis.windows-service.conf"
};
using (ZipArchive archive = ZipFile.Open(releasePackagePath, ZipArchiveMode.Create))
{
foreach (string executableName in executableNames)
{
archive.CreateEntryFromFile(Path.Combine(executablesRoot, executableName), executableName);
}
foreach (string symbolName in symbolNames)
{
archive.CreateEntryFromFile(Path.Combine(executablesRoot, symbolName), symbolName);
}
foreach (string dependencyName in dependencyNames)
{
archive.CreateEntryFromFile(Path.Combine(executablesRoot, dependencyName), dependencyName);
}
foreach (string documentName in docuementNames)
{
archive.CreateEntryFromFile(Path.Combine(documentsRoot, documentName), documentName);
}
}
}
}
}
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ReleasePackagingTool")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ReleasePackagingTool")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("598be236-1a86-432e-bf64-93fccc14b843")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{74A69E5D-6540-43CC-9975-20989BF19EB0}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ReleasePackagingTool</RootNamespace>
<AssemblyName>ReleasePackagingTool</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<IsWebBootstrapper>false</IsWebBootstrapper>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<Optimize>false</Optimize>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<RunPostBuildEvent>Always</RunPostBuildEvent>
</PropertyGroup>
<PropertyGroup>
<StartupObject>ReleasePackagingTool.Program</StartupObject>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.5">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.5 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<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.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
@@ -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
@@ -0,0 +1,34 @@
maxheap 50M
timeout 0
tcp-keepalive 0
loglevel notice
logfile stdout
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dir ./
appendonly no
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
@@ -0,0 +1,28 @@
@echo off
echo master
start redis-server master.conf
timeout /T 1 /NOBREAK > NUL
echo slave 1
start redis-server slave.1.conf
timeout /T 1 /NOBREAK > NUL
echo slave 2
start redis-server slave.2.conf
timeout /T 1 /NOBREAK > NUL
echo slave 3
start redis-server slave.3.conf
timeout /T 1 /NOBREAK > NUL
echo sentinal 1
start redis-server sentinel.1.conf --sentinel
timeout /T 1 /NOBREAK > NUL
echo sentinal 2
start redis-server sentinel.2.conf --sentinel
timeout /T 1 /NOBREAK > NUL
echo sentinal 3
start redis-server sentinel.3.conf --sentinel
@@ -0,0 +1,4 @@
port 6379
dbfilename master.rdb
maxheap 1GB
include base.conf
@@ -0,0 +1,8 @@
# By default the redis heap size is set equal to physical memory. It also allocates
# a file equal to the size of the heap. Sentinels do not need much heap to work.
maxheap 20MB
port 20001
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 30000
@@ -0,0 +1,8 @@
# By default the redis heap size is set equal to physical memory. It also allocates
# a file equal to the size of the heap. Sentinels do not need much heap to work.
maxheap 20MB
port 20002
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 30000
@@ -0,0 +1,8 @@
# By default the redis heap size is set equal to physical memory. It also allocates
# a file equal to the size of the heap. Sentinels do not need much heap to work.
maxheap 20MB
port 20003
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 30000
@@ -0,0 +1,3 @@
port 10001
dbfilename "slave1.rdb"
include slave.conf
@@ -0,0 +1,3 @@
port 10002
dbfilename "slave2.rdb"
include slave.conf
@@ -0,0 +1,3 @@
port 10003
dbfilename "slave3.rdb"
include slave.conf
@@ -0,0 +1,9 @@
maxheap 1GB
slaveof 127.0.0.1 6379
slave-serve-stale-data yes
slave-read-only yes
repl-ping-slave-period 2
repl-disable-tcp-nodelay no
slave-priority 100
include base.conf
+164
View File
@@ -0,0 +1,164 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{13E85053-54B3-487B-8DDB-3430B1C1B3BF}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>hiredis</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>hiredis</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<TargetName>hiredis</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetName>hiredis</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<TargetName>hiredis</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32_IOCP;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);WIN32_IOCP;_WIN32_WINNT=0x0501</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>Full</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32_IOCP;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
<WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32;%(PreprocessorDefinitions);WIN32_IOCP;WIN32_IOCP;_WIN32_WINNT=0x0501</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\deps\hiredis\async.c" />
<ClCompile Include="..\..\deps\hiredis\dict.c" />
<ClCompile Include="..\..\deps\hiredis\hiredis.c" />
<ClCompile Include="..\..\deps\hiredis\net.c" />
<ClCompile Include="..\..\deps\hiredis\sds.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\deps\hiredis\async.h" />
<ClInclude Include="..\..\deps\hiredis\dict.h" />
<ClInclude Include="..\..\deps\hiredis\fmacros.h" />
<ClInclude Include="..\..\deps\hiredis\hiredis.h" />
<ClInclude Include="..\..\deps\hiredis\net.h" />
<ClInclude Include="..\..\deps\hiredis\sds.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+217
View File
@@ -0,0 +1,217 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{170B0909-5F75-467F-9501-C99DEC16C6DC}</ProjectGuid>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<Keyword>ManagedCProj</Keyword>
<RootNamespace>lua</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CLRSupport>false</CLRSupport>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CLRSupport>false</CLRSupport>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<CLRSupport>false</CLRSupport>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<CLRSupport>false</CLRSupport>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<TargetExt>.lib</TargetExt>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<TargetExt>.lib</TargetExt>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<TargetExt>.lib</TargetExt>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<TargetExt>.lib</TargetExt>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32_IOCP;WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);LUA_ANSI;ENABLE_CJSON_GLOBAL</PreprocessorDefinitions>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DisableSpecificWarnings>4244;4018</DisableSpecificWarnings>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>
</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);WIN32_IOCP;_WIN32_WINNT=0x0501;LUA_ANSI;ENABLE_CJSON_GLOBAL</PreprocessorDefinitions>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DisableSpecificWarnings>4244;4018</DisableSpecificWarnings>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>
</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32_IOCP;WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);LUA_ANSI;ENABLE_CJSON_GLOBAL</PreprocessorDefinitions>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DisableSpecificWarnings>4244;4018</DisableSpecificWarnings>
<Optimization>Full</Optimization>
<WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>
</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PreprocessorDefinitions>_OFF_T_DEFINED;WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);WIN32_IOCP;WIN32_IOCP;_WIN32_WINNT=0x0501;LUA_ANSI;ENABLE_CJSON_GLOBAL</PreprocessorDefinitions>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DisableSpecificWarnings>4244;4018</DisableSpecificWarnings>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>
</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\deps\lua\src\fpconv.c" />
<ClCompile Include="..\..\..\deps\lua\src\lapi.c" />
<ClCompile Include="..\..\..\deps\lua\src\lauxlib.c" />
<ClCompile Include="..\..\..\deps\lua\src\lbaselib.c" />
<ClCompile Include="..\..\..\deps\lua\src\lcode.c" />
<ClCompile Include="..\..\..\deps\lua\src\ldblib.c" />
<ClCompile Include="..\..\..\deps\lua\src\ldebug.c" />
<ClCompile Include="..\..\..\deps\lua\src\ldo.c" />
<ClCompile Include="..\..\..\deps\lua\src\ldump.c" />
<ClCompile Include="..\..\..\deps\lua\src\lfunc.c" />
<ClCompile Include="..\..\..\deps\lua\src\lgc.c" />
<ClCompile Include="..\..\..\deps\lua\src\linit.c" />
<ClCompile Include="..\..\..\deps\lua\src\liolib.c" />
<ClCompile Include="..\..\..\deps\lua\src\llex.c" />
<ClCompile Include="..\..\..\deps\lua\src\lmathlib.c" />
<ClCompile Include="..\..\..\deps\lua\src\lmem.c" />
<ClCompile Include="..\..\..\deps\lua\src\loadlib.c" />
<ClCompile Include="..\..\..\deps\lua\src\lobject.c" />
<ClCompile Include="..\..\..\deps\lua\src\lopcodes.c" />
<ClCompile Include="..\..\..\deps\lua\src\loslib.c" />
<ClCompile Include="..\..\..\deps\lua\src\lparser.c" />
<ClCompile Include="..\..\..\deps\lua\src\lstate.c" />
<ClCompile Include="..\..\..\deps\lua\src\lstring.c" />
<ClCompile Include="..\..\..\deps\lua\src\lstrlib.c" />
<ClCompile Include="..\..\..\deps\lua\src\ltable.c" />
<ClCompile Include="..\..\..\deps\lua\src\ltablib.c" />
<ClCompile Include="..\..\..\deps\lua\src\ltm.c" />
<ClCompile Include="..\..\..\deps\lua\src\lua.c" />
<ClCompile Include="..\..\..\deps\lua\src\lua_bit.c" />
<ClCompile Include="..\..\..\deps\lua\src\lua_cjson.c" />
<ClCompile Include="..\..\..\deps\lua\src\lua_cmsgpack.c" />
<ClCompile Include="..\..\..\deps\lua\src\lua_struct.c" />
<ClCompile Include="..\..\..\deps\lua\src\lundump.c" />
<ClCompile Include="..\..\..\deps\lua\src\lvm.c" />
<ClCompile Include="..\..\..\deps\lua\src\lzio.c" />
<ClCompile Include="..\..\..\deps\lua\src\print.c" />
<ClCompile Include="..\..\..\deps\lua\src\strbuf.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\deps\lua\src\fpconv.h" />
<ClInclude Include="..\..\..\deps\lua\src\lapi.h" />
<ClInclude Include="..\..\..\deps\lua\src\lauxlib.h" />
<ClInclude Include="..\..\..\deps\lua\src\lcode.h" />
<ClInclude Include="..\..\..\deps\lua\src\ldebug.h" />
<ClInclude Include="..\..\..\deps\lua\src\ldo.h" />
<ClInclude Include="..\..\..\deps\lua\src\lfunc.h" />
<ClInclude Include="..\..\..\deps\lua\src\lgc.h" />
<ClInclude Include="..\..\..\deps\lua\src\llex.h" />
<ClInclude Include="..\..\..\deps\lua\src\llimits.h" />
<ClInclude Include="..\..\..\deps\lua\src\lmem.h" />
<ClInclude Include="..\..\..\deps\lua\src\lobject.h" />
<ClInclude Include="..\..\..\deps\lua\src\lopcodes.h" />
<ClInclude Include="..\..\..\deps\lua\src\lparser.h" />
<ClInclude Include="..\..\..\deps\lua\src\lstate.h" />
<ClInclude Include="..\..\..\deps\lua\src\lstring.h" />
<ClInclude Include="..\..\..\deps\lua\src\ltable.h" />
<ClInclude Include="..\..\..\deps\lua\src\ltm.h" />
<ClInclude Include="..\..\..\deps\lua\src\lua.h" />
<ClInclude Include="..\..\..\deps\lua\src\luaconf.h" />
<ClInclude Include="..\..\..\deps\lua\src\lualib.h" />
<ClInclude Include="..\..\..\deps\lua\src\lundump.h" />
<ClInclude Include="..\..\..\deps\lua\src\lvm.h" />
<ClInclude Include="..\..\..\deps\lua\src\lzio.h" />
<ClInclude Include="..\..\..\deps\lua\src\strbuf.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<!--
Use supportedRuntime tags to explicitly specify the version(s) of the .NET Framework runtime that
the custom action should run on. If no versions are specified, the chosen version of the runtime
will be the "best" match to what Microsoft.Deployment.WindowsInstaller.dll was built against.
WARNING: leaving the version unspecified is dangerous as it introduces a risk of compatibility
problems with future versions of the .NET Framework runtime. It is highly recommended that you specify
only the version(s) of the .NET Framework runtime that you have tested against.
Note for .NET Framework v3.0 and v3.5, the runtime version is still v2.0.
In order to enable .NET Framework version 2.0 runtime activation policy, which is to load all assemblies
by using the latest supported runtime, @useLegacyV2RuntimeActivationPolicy="true".
For more information, see http://msdn.microsoft.com/en-us/library/bbx34a2h.aspx
-->
<supportedRuntime version="v4.0" />
<supportedRuntime version="v2.0.50727"/>
</startup>
<!--
Add additional configuration settings here. For more information on application config files,
see http://msdn.microsoft.com/en-us/library/kza1yk3a.aspx
-->
</configuration>
@@ -0,0 +1,73 @@
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.");
}
}
}
}
@@ -0,0 +1,34 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("RedisMsi.CustomActions")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyCompany("Microsoft Open Technologies")]
[assembly: AssemblyProduct("RedisMsi.CustomActions")]
[assembly: AssemblyCopyright("Copyright © Microsoft Open Technologies 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("afda0233-dacd-4bbe-89ce-19cdb9000561")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
@@ -0,0 +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.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>
+48
View File
@@ -0,0 +1,48 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "RedisMsi", "RedisMsi\RedisMsi.wixproj", "{C829D256-16B4-4DC7-9BF9-6814F76B441E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RedisMsi.CustomActions", "RedisMsi.CustomActions\RedisMsi.CustomActions.csproj", "{A917027E-D229-46C9-B969-1F4CE7D5D2CA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Win32 = Release|Win32
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C829D256-16B4-4DC7-9BF9-6814F76B441E}.Debug|Win32.ActiveCfg = Debug|x86
{C829D256-16B4-4DC7-9BF9-6814F76B441E}.Debug|Win32.Build.0 = Debug|x86
{C829D256-16B4-4DC7-9BF9-6814F76B441E}.Debug|x64.ActiveCfg = Debug|x64
{C829D256-16B4-4DC7-9BF9-6814F76B441E}.Debug|x64.Build.0 = Debug|x64
{C829D256-16B4-4DC7-9BF9-6814F76B441E}.Debug|x86.ActiveCfg = Debug|x86
{C829D256-16B4-4DC7-9BF9-6814F76B441E}.Debug|x86.Build.0 = Debug|x86
{C829D256-16B4-4DC7-9BF9-6814F76B441E}.Release|Win32.ActiveCfg = Release|x86
{C829D256-16B4-4DC7-9BF9-6814F76B441E}.Release|Win32.Build.0 = Release|x86
{C829D256-16B4-4DC7-9BF9-6814F76B441E}.Release|x64.ActiveCfg = Release|x64
{C829D256-16B4-4DC7-9BF9-6814F76B441E}.Release|x64.Build.0 = Release|x64
{C829D256-16B4-4DC7-9BF9-6814F76B441E}.Release|x86.ActiveCfg = Release|x86
{C829D256-16B4-4DC7-9BF9-6814F76B441E}.Release|x86.Build.0 = Release|x86
{A917027E-D229-46C9-B969-1F4CE7D5D2CA}.Debug|Win32.ActiveCfg = Debug|x86
{A917027E-D229-46C9-B969-1F4CE7D5D2CA}.Debug|Win32.Build.0 = Debug|x86
{A917027E-D229-46C9-B969-1F4CE7D5D2CA}.Debug|x64.ActiveCfg = Debug|x64
{A917027E-D229-46C9-B969-1F4CE7D5D2CA}.Debug|x64.Build.0 = Debug|x64
{A917027E-D229-46C9-B969-1F4CE7D5D2CA}.Debug|x86.ActiveCfg = Debug|x86
{A917027E-D229-46C9-B969-1F4CE7D5D2CA}.Debug|x86.Build.0 = Debug|x86
{A917027E-D229-46C9-B969-1F4CE7D5D2CA}.Release|Win32.ActiveCfg = Release|x86
{A917027E-D229-46C9-B969-1F4CE7D5D2CA}.Release|Win32.Build.0 = Release|x86
{A917027E-D229-46C9-B969-1F4CE7D5D2CA}.Release|x64.ActiveCfg = Release|x64
{A917027E-D229-46C9-B969-1F4CE7D5D2CA}.Release|x64.Build.0 = Release|x64
{A917027E-D229-46C9-B969-1F4CE7D5D2CA}.Release|x86.ActiveCfg = Release|x86
{A917027E-D229-46C9-B969-1F4CE7D5D2CA}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -0,0 +1,28 @@
<?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>
<!--Documentation files to install-->
<ComponentGroup Id="DocumentationComponents" Directory="INSTALLFOLDER" Source="!(wix.DocumentationFolder)">
<Component Id="cmp_Redis_Windows_Conf" Guid="*">
<File Name="redis.windows.conf" />
</Component>
<Component Id="cmp_Redis_on_Windows_Release_NotesDOCX" Guid="*">
<File Name="Redis on Windows Release Notes.docx" />
</Component>
<Component Id="cmp_Redis_on_WindowsDOCX" Guid="*">
<File Name="Redis on Windows.docx" />
</Component>
<Component Id="cmp_Windows_Service_DocumentationDOCX" Guid="*">
<File Name="Windows Service Documentation.docx" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
@@ -0,0 +1,28 @@
<?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>
<!--Files to install, other than the main executable-->
<ComponentGroup Id="FileComponents" Directory="INSTALLFOLDER">
<Component Id="cmp_redis_benchmarkEXE" Guid="*">
<File Source="$(var.BinDir)redis-benchmark.exe" />
</Component>
<Component Id="cmp_redis_check_aofEXE" Guid="*">
<File Source="$(var.BinDir)redis-check-aof.exe" />
</Component>
<Component Id="cmp_redis_check_dumpEXE" Guid="*">
<File Source="$(var.BinDir)redis-check-dump.exe" />
</Component>
<Component Id="cmp_redis_cliEXE" Guid="*">
<File Source="$(var.BinDir)redis-cli.exe" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
@@ -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>

Some files were not shown because too many files have changed in this diff Show More