initial commit

This commit is contained in:
vms 2019-06-28 14:12:45 +03:00
parent ba5145b8e9
commit 4fd252b07c
64 changed files with 2214 additions and 198 deletions

58
.gitignore vendored
View File

@ -28,3 +28,61 @@ deps/lua/src/liblua.a
.prerequisites
*.dSYM
Makefile.dep
### C++ template
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
.idea/*
cmake-build-debug
## File-based project format:
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

480
CMakeLists.txt Normal file
View File

@ -0,0 +1,480 @@
cmake_minimum_required(VERSION 3.13)
project(redis)
set(CMAKE_CXX_STANDARD 14)
include_directories(deps/hiredis)
include_directories(deps/hiredis/adapters)
include_directories(deps/hiredis/examples)
include_directories(deps/jemalloc/include)
include_directories(deps/jemalloc/include/jemalloc)
include_directories(deps/jemalloc/include/jemalloc/internal)
include_directories(deps/jemalloc/include/msvc_compat)
include_directories(deps/jemalloc/include/msvc_compat/C99)
include_directories(deps/jemalloc/msvc/test_threads)
include_directories(deps/jemalloc/test/include)
include_directories(deps/jemalloc/test/include/test)
include_directories(deps/linenoise)
include_directories(deps/lua/etc)
include_directories(deps/lua/src)
include_directories(src)
add_executable(redis
deps/hiredis/adapters/ae.h
deps/hiredis/adapters/glib.h
deps/hiredis/adapters/ivykis.h
deps/hiredis/adapters/libev.h
deps/hiredis/adapters/libevent.h
deps/hiredis/adapters/libuv.h
deps/hiredis/adapters/macosx.h
deps/hiredis/adapters/qt.h
deps/hiredis/examples/example-ae.c
deps/hiredis/examples/example-glib.c
deps/hiredis/examples/example-ivykis.c
deps/hiredis/examples/example-libev.c
deps/hiredis/examples/example-libevent.c
deps/hiredis/examples/example-libuv.c
deps/hiredis/examples/example-macosx.c
deps/hiredis/examples/example-qt.cpp
deps/hiredis/examples/example-qt.h
deps/hiredis/examples/example.c
deps/hiredis/async.c
deps/hiredis/async.h
deps/hiredis/dict.c
deps/hiredis/dict.h
deps/hiredis/fmacros.h
deps/hiredis/hiredis.c
deps/hiredis/hiredis.h
deps/hiredis/net.c
deps/hiredis/net.h
deps/hiredis/read.c
deps/hiredis/read.h
deps/hiredis/sds.c
deps/hiredis/sds.h
deps/hiredis/sdsalloc.h
deps/hiredis/test.c
deps/hiredis/win32.h
deps/jemalloc/include/jemalloc/internal/arena_externs.h
deps/jemalloc/include/jemalloc/internal/arena_inlines_a.h
deps/jemalloc/include/jemalloc/internal/arena_inlines_b.h
deps/jemalloc/include/jemalloc/internal/arena_stats.h
deps/jemalloc/include/jemalloc/internal/arena_structs_a.h
deps/jemalloc/include/jemalloc/internal/arena_structs_b.h
deps/jemalloc/include/jemalloc/internal/arena_types.h
deps/jemalloc/include/jemalloc/internal/assert.h
deps/jemalloc/include/jemalloc/internal/atomic.h
deps/jemalloc/include/jemalloc/internal/atomic_c11.h
deps/jemalloc/include/jemalloc/internal/atomic_gcc_atomic.h
deps/jemalloc/include/jemalloc/internal/atomic_gcc_sync.h
deps/jemalloc/include/jemalloc/internal/atomic_msvc.h
deps/jemalloc/include/jemalloc/internal/background_thread_externs.h
deps/jemalloc/include/jemalloc/internal/background_thread_inlines.h
deps/jemalloc/include/jemalloc/internal/background_thread_structs.h
deps/jemalloc/include/jemalloc/internal/base_externs.h
deps/jemalloc/include/jemalloc/internal/base_inlines.h
deps/jemalloc/include/jemalloc/internal/base_structs.h
deps/jemalloc/include/jemalloc/internal/base_types.h
deps/jemalloc/include/jemalloc/internal/bin.h
deps/jemalloc/include/jemalloc/internal/bin_stats.h
deps/jemalloc/include/jemalloc/internal/bit_util.h
deps/jemalloc/include/jemalloc/internal/bitmap.h
deps/jemalloc/include/jemalloc/internal/cache_bin.h
deps/jemalloc/include/jemalloc/internal/ckh.h
deps/jemalloc/include/jemalloc/internal/ctl.h
deps/jemalloc/include/jemalloc/internal/div.h
deps/jemalloc/include/jemalloc/internal/emitter.h
deps/jemalloc/include/jemalloc/internal/extent_dss.h
deps/jemalloc/include/jemalloc/internal/extent_externs.h
deps/jemalloc/include/jemalloc/internal/extent_inlines.h
deps/jemalloc/include/jemalloc/internal/extent_mmap.h
deps/jemalloc/include/jemalloc/internal/extent_structs.h
deps/jemalloc/include/jemalloc/internal/extent_types.h
deps/jemalloc/include/jemalloc/internal/hash.h
deps/jemalloc/include/jemalloc/internal/hooks.h
deps/jemalloc/include/jemalloc/internal/jemalloc_internal_decls.h
deps/jemalloc/include/jemalloc/internal/jemalloc_internal_externs.h
deps/jemalloc/include/jemalloc/internal/jemalloc_internal_includes.h
deps/jemalloc/include/jemalloc/internal/jemalloc_internal_inlines_a.h
deps/jemalloc/include/jemalloc/internal/jemalloc_internal_inlines_b.h
deps/jemalloc/include/jemalloc/internal/jemalloc_internal_inlines_c.h
deps/jemalloc/include/jemalloc/internal/jemalloc_internal_macros.h
deps/jemalloc/include/jemalloc/internal/jemalloc_internal_types.h
deps/jemalloc/include/jemalloc/internal/large_externs.h
deps/jemalloc/include/jemalloc/internal/log.h
deps/jemalloc/include/jemalloc/internal/malloc_io.h
deps/jemalloc/include/jemalloc/internal/mutex.h
deps/jemalloc/include/jemalloc/internal/mutex_pool.h
deps/jemalloc/include/jemalloc/internal/mutex_prof.h
deps/jemalloc/include/jemalloc/internal/nstime.h
deps/jemalloc/include/jemalloc/internal/pages.h
deps/jemalloc/include/jemalloc/internal/ph.h
deps/jemalloc/include/jemalloc/internal/prng.h
deps/jemalloc/include/jemalloc/internal/prof_externs.h
deps/jemalloc/include/jemalloc/internal/prof_inlines_a.h
deps/jemalloc/include/jemalloc/internal/prof_inlines_b.h
deps/jemalloc/include/jemalloc/internal/prof_structs.h
deps/jemalloc/include/jemalloc/internal/prof_types.h
deps/jemalloc/include/jemalloc/internal/ql.h
deps/jemalloc/include/jemalloc/internal/qr.h
deps/jemalloc/include/jemalloc/internal/rb.h
deps/jemalloc/include/jemalloc/internal/rtree.h
deps/jemalloc/include/jemalloc/internal/rtree_tsd.h
deps/jemalloc/include/jemalloc/internal/smoothstep.h
deps/jemalloc/include/jemalloc/internal/spin.h
deps/jemalloc/include/jemalloc/internal/stats.h
deps/jemalloc/include/jemalloc/internal/sz.h
deps/jemalloc/include/jemalloc/internal/tcache_externs.h
deps/jemalloc/include/jemalloc/internal/tcache_inlines.h
deps/jemalloc/include/jemalloc/internal/tcache_structs.h
deps/jemalloc/include/jemalloc/internal/tcache_types.h
deps/jemalloc/include/jemalloc/internal/ticker.h
deps/jemalloc/include/jemalloc/internal/tsd.h
deps/jemalloc/include/jemalloc/internal/tsd_generic.h
deps/jemalloc/include/jemalloc/internal/tsd_malloc_thread_cleanup.h
deps/jemalloc/include/jemalloc/internal/tsd_tls.h
deps/jemalloc/include/jemalloc/internal/tsd_types.h
deps/jemalloc/include/jemalloc/internal/tsd_win.h
deps/jemalloc/include/jemalloc/internal/util.h
deps/jemalloc/include/jemalloc/internal/witness.h
deps/jemalloc/include/msvc_compat/C99/stdbool.h
deps/jemalloc/include/msvc_compat/C99/stdint.h
deps/jemalloc/include/msvc_compat/strings.h
deps/jemalloc/include/msvc_compat/windows_extra.h
deps/jemalloc/msvc/test_threads/test_threads.cpp
deps/jemalloc/msvc/test_threads/test_threads.h
deps/jemalloc/msvc/test_threads/test_threads_main.cpp
deps/jemalloc/src/arena.c
deps/jemalloc/src/background_thread.c
deps/jemalloc/src/base.c
deps/jemalloc/src/bin.c
deps/jemalloc/src/bitmap.c
deps/jemalloc/src/ckh.c
deps/jemalloc/src/ctl.c
deps/jemalloc/src/div.c
deps/jemalloc/src/extent.c
deps/jemalloc/src/extent_dss.c
deps/jemalloc/src/extent_mmap.c
deps/jemalloc/src/hash.c
deps/jemalloc/src/hooks.c
deps/jemalloc/src/jemalloc.c
deps/jemalloc/src/jemalloc_cpp.cpp
deps/jemalloc/src/large.c
deps/jemalloc/src/log.c
deps/jemalloc/src/malloc_io.c
deps/jemalloc/src/mutex.c
deps/jemalloc/src/mutex_pool.c
deps/jemalloc/src/nstime.c
deps/jemalloc/src/pages.c
deps/jemalloc/src/prng.c
deps/jemalloc/src/prof.c
deps/jemalloc/src/rtree.c
deps/jemalloc/src/stats.c
deps/jemalloc/src/sz.c
deps/jemalloc/src/tcache.c
deps/jemalloc/src/ticker.c
deps/jemalloc/src/tsd.c
deps/jemalloc/src/witness.c
deps/jemalloc/src/zone.c
deps/jemalloc/test/include/test/btalloc.h
deps/jemalloc/test/include/test/extent_hooks.h
deps/jemalloc/test/include/test/math.h
deps/jemalloc/test/include/test/mq.h
deps/jemalloc/test/include/test/mtx.h
deps/jemalloc/test/include/test/SFMT-alti.h
deps/jemalloc/test/include/test/SFMT-params.h
deps/jemalloc/test/include/test/SFMT-params11213.h
deps/jemalloc/test/include/test/SFMT-params1279.h
deps/jemalloc/test/include/test/SFMT-params132049.h
deps/jemalloc/test/include/test/SFMT-params19937.h
deps/jemalloc/test/include/test/SFMT-params216091.h
deps/jemalloc/test/include/test/SFMT-params2281.h
deps/jemalloc/test/include/test/SFMT-params4253.h
deps/jemalloc/test/include/test/SFMT-params44497.h
deps/jemalloc/test/include/test/SFMT-params607.h
deps/jemalloc/test/include/test/SFMT-params86243.h
deps/jemalloc/test/include/test/SFMT-sse2.h
deps/jemalloc/test/include/test/SFMT.h
deps/jemalloc/test/include/test/test.h
deps/jemalloc/test/include/test/thd.h
deps/jemalloc/test/include/test/timer.h
deps/jemalloc/test/integration/cpp/basic.cpp
deps/jemalloc/test/integration/aligned_alloc.c
deps/jemalloc/test/integration/allocated.c
deps/jemalloc/test/integration/extent.c
deps/jemalloc/test/integration/mallocx.c
deps/jemalloc/test/integration/MALLOCX_ARENA.c
deps/jemalloc/test/integration/overflow.c
deps/jemalloc/test/integration/posix_memalign.c
deps/jemalloc/test/integration/rallocx.c
deps/jemalloc/test/integration/sdallocx.c
deps/jemalloc/test/integration/thread_arena.c
deps/jemalloc/test/integration/thread_tcache_enabled.c
deps/jemalloc/test/integration/xallocx.c
deps/jemalloc/test/src/btalloc.c
deps/jemalloc/test/src/btalloc_0.c
deps/jemalloc/test/src/btalloc_1.c
deps/jemalloc/test/src/math.c
deps/jemalloc/test/src/mq.c
deps/jemalloc/test/src/mtx.c
deps/jemalloc/test/src/SFMT.c
deps/jemalloc/test/src/test.c
deps/jemalloc/test/src/thd.c
deps/jemalloc/test/src/timer.c
deps/jemalloc/test/stress/microbench.c
deps/jemalloc/test/unit/a0.c
deps/jemalloc/test/unit/arena_reset.c
deps/jemalloc/test/unit/arena_reset_prof.c
deps/jemalloc/test/unit/atomic.c
deps/jemalloc/test/unit/background_thread.c
deps/jemalloc/test/unit/background_thread_enable.c
deps/jemalloc/test/unit/base.c
deps/jemalloc/test/unit/bit_util.c
deps/jemalloc/test/unit/bitmap.c
deps/jemalloc/test/unit/ckh.c
deps/jemalloc/test/unit/decay.c
deps/jemalloc/test/unit/div.c
deps/jemalloc/test/unit/emitter.c
deps/jemalloc/test/unit/extent_quantize.c
deps/jemalloc/test/unit/fork.c
deps/jemalloc/test/unit/hash.c
deps/jemalloc/test/unit/hooks.c
deps/jemalloc/test/unit/junk.c
deps/jemalloc/test/unit/junk_alloc.c
deps/jemalloc/test/unit/junk_free.c
deps/jemalloc/test/unit/log.c
deps/jemalloc/test/unit/mallctl.c
deps/jemalloc/test/unit/malloc_io.c
deps/jemalloc/test/unit/math.c
deps/jemalloc/test/unit/mq.c
deps/jemalloc/test/unit/mtx.c
deps/jemalloc/test/unit/nstime.c
deps/jemalloc/test/unit/pack.c
deps/jemalloc/test/unit/pages.c
deps/jemalloc/test/unit/ph.c
deps/jemalloc/test/unit/prng.c
deps/jemalloc/test/unit/prof_accum.c
deps/jemalloc/test/unit/prof_active.c
deps/jemalloc/test/unit/prof_gdump.c
deps/jemalloc/test/unit/prof_idump.c
deps/jemalloc/test/unit/prof_reset.c
deps/jemalloc/test/unit/prof_tctx.c
deps/jemalloc/test/unit/prof_thread_name.c
deps/jemalloc/test/unit/ql.c
deps/jemalloc/test/unit/qr.c
deps/jemalloc/test/unit/rb.c
deps/jemalloc/test/unit/retained.c
deps/jemalloc/test/unit/rtree.c
deps/jemalloc/test/unit/SFMT.c
deps/jemalloc/test/unit/size_classes.c
deps/jemalloc/test/unit/slab.c
deps/jemalloc/test/unit/smoothstep.c
deps/jemalloc/test/unit/spin.c
deps/jemalloc/test/unit/stats.c
deps/jemalloc/test/unit/stats_print.c
deps/jemalloc/test/unit/ticker.c
deps/jemalloc/test/unit/tsd.c
deps/jemalloc/test/unit/witness.c
deps/jemalloc/test/unit/zero.c
deps/linenoise/example.c
deps/linenoise/linenoise.c
deps/linenoise/linenoise.h
deps/lua/etc/all.c
deps/lua/etc/lua.hpp
deps/lua/etc/min.c
deps/lua/etc/noparser.c
deps/lua/src/fpconv.c
deps/lua/src/fpconv.h
deps/lua/src/lapi.c
deps/lua/src/lapi.h
deps/lua/src/lauxlib.c
deps/lua/src/lauxlib.h
deps/lua/src/lbaselib.c
deps/lua/src/lcode.c
deps/lua/src/lcode.h
deps/lua/src/ldblib.c
deps/lua/src/ldebug.c
deps/lua/src/ldebug.h
deps/lua/src/ldo.c
deps/lua/src/ldo.h
deps/lua/src/ldump.c
deps/lua/src/lfunc.c
deps/lua/src/lfunc.h
deps/lua/src/lgc.c
deps/lua/src/lgc.h
deps/lua/src/linit.c
deps/lua/src/liolib.c
deps/lua/src/llex.c
deps/lua/src/llex.h
deps/lua/src/llimits.h
deps/lua/src/lmathlib.c
deps/lua/src/lmem.c
deps/lua/src/lmem.h
deps/lua/src/loadlib.c
deps/lua/src/lobject.c
deps/lua/src/lobject.h
deps/lua/src/lopcodes.c
deps/lua/src/lopcodes.h
deps/lua/src/loslib.c
deps/lua/src/lparser.c
deps/lua/src/lparser.h
deps/lua/src/lstate.c
deps/lua/src/lstate.h
deps/lua/src/lstring.c
deps/lua/src/lstring.h
deps/lua/src/lstrlib.c
deps/lua/src/ltable.c
deps/lua/src/ltable.h
deps/lua/src/ltablib.c
deps/lua/src/ltm.c
deps/lua/src/ltm.h
deps/lua/src/lua.c
deps/lua/src/lua.h
deps/lua/src/lua_bit.c
deps/lua/src/lua_cjson.c
deps/lua/src/lua_cmsgpack.c
deps/lua/src/lua_struct.c
deps/lua/src/luac.c
deps/lua/src/luaconf.h
deps/lua/src/lualib.h
deps/lua/src/lundump.c
deps/lua/src/lundump.h
deps/lua/src/lvm.c
deps/lua/src/lvm.h
deps/lua/src/lzio.c
deps/lua/src/lzio.h
deps/lua/src/print.c
deps/lua/src/strbuf.c
deps/lua/src/strbuf.h
src/modules/helloblock.c
src/modules/hellocluster.c
src/modules/hellodict.c
src/modules/hellotimer.c
src/modules/hellotype.c
src/modules/helloworld.c
src/modules/testmodule.c
src/adlist.c
src/adlist.h
src/ae.c
src/ae.h
src/ae_epoll.c
src/ae_evport.c
src/ae_kqueue.c
src/ae_select.c
src/anet.c
src/anet.h
src/aof.c
src/asciilogo.h
src/atomicvar.h
src/bio.c
src/bio.h
src/bitops.c
src/blocked.c
src/childinfo.c
src/cluster.c
src/cluster.h
src/config.c
src/config.h
src/crc16.c
src/crc64.c
src/crc64.h
src/db.c
src/debug.c
src/debugmacro.h
src/defrag.c
src/dict.c
src/dict.h
src/endianconv.c
src/endianconv.h
src/evict.c
src/expire.c
src/fmacros.h
src/geo.c
src/geo.h
src/geohash.c
src/geohash.h
src/geohash_helper.c
src/geohash_helper.h
src/help.h
src/hyperloglog.c
src/intset.c
src/intset.h
src/latency.c
src/latency.h
src/lazyfree.c
src/listpack.c
src/listpack.h
src/listpack_malloc.h
src/localtime.c
src/lolwut.c
src/lolwut5.c
src/lzf.h
src/lzf_c.c
src/lzf_d.c
src/lzfP.h
src/memtest.c
src/module.c
src/multi.c
src/networking.c
src/notify.c
src/object.c
src/pqsort.c
src/pqsort.h
src/pubsub.c
src/quicklist.c
src/quicklist.h
src/rand.c
src/rand.h
src/rax.c
src/rax.h
src/rax_malloc.h
src/rdb.c
src/rdb.h
src/redis-benchmark.c
src/redis-check-aof.c
src/redis-check-rdb.c
src/redis-cli.c
src/redisassert.h
src/redismodule.h
src/release.c
src/release.h
src/replication.c
src/rio.c
src/rio.h
src/scripting.c
src/sds.c
src/sds.h
src/sdsalloc.h
src/sentinel.c
src/server.c
src/server.h
src/setproctitle.c
src/sha1.c
src/sha1.h
src/siphash.c
src/slowlog.c
src/slowlog.h
src/solarisfixes.h
src/sort.c
src/sparkline.c
src/sparkline.h
src/stream.h
src/syncio.c
src/t_hash.c
src/t_list.c
src/t_set.c
src/t_stream.c
src/t_string.c
src/t_zset.c
src/testhelp.h
src/util.c
src/util.h
src/version.h
src/ziplist.c
src/ziplist.h
src/zipmap.c
src/zipmap.h
src/zmalloc.c
src/zmalloc.h
utils/hashtable/rehashing.c
utils/lru/lfu-simulation.c
utils/corrupt_rdb.c src/wrapper.c)

13
Dockerfile Normal file
View File

@ -0,0 +1,13 @@
FROM ubuntu:19.04
RUN apt-get update \
&& apt-get install -y ca-certificates \
curl \
git \
make
RUN curl -L https://github.com/CraneStation/wasi-sdk/releases/download/wasi-sdk-5/wasi-sdk-5.0-linux.tar.gz | tar xz --strip-components=1 -C /
VOLUME /code
WORKDIR /code
CMD make wasm

View File

@ -5,6 +5,9 @@ default: all
.DEFAULT:
cd src && $(MAKE) $@
wasm:
cd src && $(MAKE) -f Makefile_wasm
install:
cd src && $(MAKE) $@

View File

@ -447,12 +447,16 @@ static int luaB_newproxy (lua_State *L) {
static const luaL_Reg base_funcs[] = {
{"assert", luaB_assert},
{"collectgarbage", luaB_collectgarbage},
#if __redis_unmodified_upstream // Disable working with files
{"dofile", luaB_dofile},
#endif
{"error", luaB_error},
{"gcinfo", luaB_gcinfo},
{"getfenv", luaB_getfenv},
{"getmetatable", luaB_getmetatable},
#if __redis_unmodified_upstream // Disable working with files
{"loadfile", luaB_loadfile},
#endif
{"load", luaB_load},
{"loadstring", luaB_loadstring},
{"next", luaB_next},

View File

@ -391,8 +391,10 @@ static const luaL_Reg dblib[] = {
};
#if __redis_unmodified_upstream // Disable lua debugging API of Redis
LUALIB_API int luaopen_debug (lua_State *L) {
luaL_register(L, LUA_DBLIBNAME, dblib);
return 1;
}
#endif

6
deps/lua/src/ldo.c vendored
View File

@ -5,7 +5,9 @@
*/
#if __redis_unmodified_upstream // Currently setjmp/longjump cannot be translated to Wasm
#include <setjmp.h>
#endif
#include <stdlib.h>
#include <string.h>
@ -103,7 +105,11 @@ void luaD_throw (lua_State *L, int errcode) {
lua_unlock(L);
G(L)->panic(L);
}
#if __redis_unmodified_upstream // Disable a call to exit from libc
exit(EXIT_FAILURE);
#else
__builtin_unreachable();
#endif
}
}

View File

@ -19,10 +19,14 @@ static const luaL_Reg lualibs[] = {
{LUA_LOADLIBNAME, luaopen_package},
{LUA_TABLIBNAME, luaopen_table},
{LUA_IOLIBNAME, luaopen_io},
#if __redis_unmodified_upstream // Disable the lua os API of Redis
{LUA_OSLIBNAME, luaopen_os},
#endif
{LUA_STRLIBNAME, luaopen_string},
{LUA_MATHLIBNAME, luaopen_math},
#if __redis_unmodified_upstream // Disable the lua debugging API of Redis
{LUA_DBLIBNAME, luaopen_debug},
#endif
{NULL, NULL}
};

View File

@ -235,9 +235,10 @@ static const luaL_Reg syslib[] = {
/* }====================================================== */
#if __redis_unmodified_upstream // Disable lua os module
LUALIB_API int luaopen_os (lua_State *L) {
luaL_register(L, LUA_OSLIBNAME, syslib);
return 1;
}
#endif

8
deps/lua/src/lua.c vendored
View File

@ -5,7 +5,9 @@
*/
#if __redis_unmodified_upstream // Disable syscalls from some libs
#include <signal.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -33,8 +35,10 @@ static void lstop (lua_State *L, lua_Debug *ar) {
static void laction (int i) {
#if __redis_unmodified_upstream // Disable signal handler
signal(i, SIG_DFL); /* if another SIGINT happens before lstop,
terminate process (default action) */
#endif
lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
}
@ -98,9 +102,13 @@ static int docall (lua_State *L, int narg, int clear) {
int base = lua_gettop(L) - narg; /* function index */
lua_pushcfunction(L, traceback); /* push traceback function */
lua_insert(L, base); /* put it under chunk and args */
#if __redis_unmodified_upstream // Disable signal handlers
signal(SIGINT, laction);
#endif
status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base);
#if __redis_unmodified_upstream // Disable signal handlers
signal(SIGINT, SIG_DFL);
#endif
lua_remove(L, base); /* remove traceback function */
/* force a complete garbage collection in case of errors */
if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0);

View File

@ -1405,11 +1405,17 @@ int luaopen_cjson(lua_State *l)
{
lua_cjson_new(l);
#if __redis_unmodified_upstream // It could be built without explicit enabling of this macro
#ifdef ENABLE_CJSON_GLOBAL
/* Register a global "cjson" table. */
lua_pushvalue(l, -1);
lua_setglobal(l, CJSON_MODNAME);
#endif
#else
/* Register a global "cjson" table. */
lua_pushvalue(l, -1);
lua_setglobal(l, CJSON_MODNAME);
#endif
/* Return cjson table */
return 1;

View File

@ -617,11 +617,16 @@ union luai_Cast { double l_d; long l_l; };
#define luai_jmpbuf jmp_buf
#else
#if __redis_unmodified_upstream // Currently setjmp/longjump cannot be translated to Wasm
/* default handling with long jumps */
#define LUAI_THROW(L,c) longjmp((c)->b, 1)
#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
#define luai_jmpbuf jmp_buf
#else
#define LUAI_THROW(L,c)
#define LUAI_TRY(L,c,a) { a }
#define luai_jmpbuf int
#endif
#endif
@ -653,7 +658,11 @@ union luai_Cast { double l_d; long l_l; };
e = (e == -1); }
#else
#if __redis_unmodified_upstream // Disable getting tmp folder
#define LUA_TMPNAMBUFSIZE L_tmpnam
#else
#define LUA_TMPNAMBUFSIZE 260
#endif
#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
#endif

View File

@ -24,8 +24,10 @@ LUALIB_API int (luaopen_table) (lua_State *L);
#define LUA_IOLIBNAME "io"
LUALIB_API int (luaopen_io) (lua_State *L);
#if __redis_unmodified_upstream // Disable os module of lua
#define LUA_OSLIBNAME "os"
LUALIB_API int (luaopen_os) (lua_State *L);
#endif
#define LUA_STRLIBNAME "string"
LUALIB_API int (luaopen_string) (lua_State *L);
@ -33,8 +35,10 @@ LUALIB_API int (luaopen_string) (lua_State *L);
#define LUA_MATHLIBNAME "math"
LUALIB_API int (luaopen_math) (lua_State *L);
#if __redis_unmodified_upstream // Disable the debug module of lua
#define LUA_DBLIBNAME "debug"
LUALIB_API int (luaopen_debug) (lua_State *L);
#endif
#define LUA_LOADLIBNAME "package"
LUALIB_API int (luaopen_package) (lua_State *L);

View File

@ -31,6 +31,7 @@
static void die(const char *fmt, ...)
{
#if __redis_unmodified_upstream // Disable a call to exit from libc
va_list arg;
va_start(arg, fmt);
@ -39,6 +40,10 @@ static void die(const char *fmt, ...)
fprintf(stderr, "\n");
exit(-1);
#else
// TODO: enable server logs
__builtin_unreachable();
#endif
}
void strbuf_init(strbuf_t *s, int len)

7
docker-compose.yml Normal file
View File

@ -0,0 +1,7 @@
version: '3'
services:
redis:
build:
context: .
volumes:
- .:/code

23
src/Makefile_wasm Normal file
View File

@ -0,0 +1,23 @@
TARGET = redis
CC = /opt/wasi-sdk/bin/clang
SYSROOT = /opt/wasi-sdk/share/sysroot
TARGET_TRIPLE = wasm32-unknown-wasi
CFLAGS = -nostartfiles -fvisibility=hidden
LDFLAGS = -Wl,--no-entry,--demangle,--allow-undefined
EXPORT_FUNCS = --export=allocate,--export=deallocate,--export=invoke
SDK = sdk/allocator.cpp sdk/logger.cpp
LUA =/code/deps/lua/src
REDIS_SERVER = adlist.c quicklist.c dict.c server.c sds.c zmalloc.c lzf_c.c lzf_d.c pqsort.c zipmap.c sha1.c ziplist.c release.c networking.c util.c object.c db.c t_string.c t_list.c t_set.c t_zset.c t_hash.c multi.c sort.c intset.c crc16.c endianconv.c slowlog.c scripting.c rand.c crc64.c bitops.c notify.c hyperloglog.c latency.c sparkline.c geo.c evict.c expire.c geohash.c geohash_helper.c defrag.c siphash.c rax.c t_stream.c listpack.c lolwut.c lolwut5.c wrapper.c
.PHONY: default all clean
default: $(TARGET)
all: default
$(TARGET): $(REDIS_SERVER)
$(CC) --sysroot=$(SYSROOT) --target=$(TARGET_TRIPLE) -I$(LUA) $(CFLAGS) $(LDFLAGS) -Wl,$(EXPORT_FUNCS) $^ -c
.PRECIOUS: $(TARGET)
clean:
-rm -f $(TARGET).wasm

View File

@ -57,11 +57,14 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#if __redis_unmodified_upstream // Disable syscalls from pthread.h
#include <pthread.h>
#endif
#ifndef __ATOMIC_VAR_H
#define __ATOMIC_VAR_H
#if __redis_unmodified_upstream // Make these macros independent on various flags
/* To test Redis with Helgrind (a Valgrind tool) it is useful to define
* the following macro, so that __sync macros are used: those can be detected
* by Helgrind (even if they are less efficient) so that no false positive
@ -130,4 +133,26 @@
#define REDIS_ATOMIC_API "pthread-mutex"
#endif
#else
#define atomicIncr(var,count) do { \
var += (count); \
} while(0)
#define atomicGetIncr(var,oldvalue_var,count) do { \
oldvalue_var = var; \
var += (count); \
} while(0)
#define atomicDecr(var,count) do { \
var -= (count); \
} while(0)
#define atomicGet(var,dstvar) do { \
dstvar = var; \
} while(0)
#define atomicSet(var,value) do { \
var = value; \
} while(0)
#define REDIS_ATOMIC_API "wasm-atomic-api"
#endif
#endif /* __ATOMIC_VAR_H */

View File

@ -29,6 +29,11 @@
*/
#include "server.h"
#if __redis_unmodified_upstream // To make all implicit functions prototypes explicit
#else
#include <stdio.h>
#include <string.h>
#endif
/* -----------------------------------------------------------------------------
* Helpers and low level bit functions.

View File

@ -165,7 +165,9 @@ void unblockClient(client *c) {
c->btype == BLOCKED_STREAM) {
unblockClientWaitingData(c);
} else if (c->btype == BLOCKED_WAIT) {
#if __redis_unmodified_upstream // Disable the cluster API of Redis
unblockClientWaitingReplicas(c);
#endif
} else if (c->btype == BLOCKED_MODULE) {
unblockClientFromModule(c);
} else {
@ -604,5 +606,3 @@ void signalKeyAsReady(redisDb *db, robj *key) {
incrRefCount(key);
serverAssert(dictAdd(db->ready_keys,key,NULL) == DICT_OK);
}

View File

@ -143,16 +143,20 @@ int yesnotoi(char *s) {
}
void appendServerSaveParams(time_t seconds, int changes) {
#if __redis_unmodified_upstream // Disable saveparams
server.saveparams = zrealloc(server.saveparams,sizeof(struct saveparam)*(server.saveparamslen+1));
server.saveparams[server.saveparamslen].seconds = seconds;
server.saveparams[server.saveparamslen].changes = changes;
server.saveparamslen++;
#endif
}
void resetServerSaveParams(void) {
#if __redis_unmodified_upstream // Disable saevparams
zfree(server.saveparams);
server.saveparams = NULL;
server.saveparamslen = 0;
#endif
}
void queueLoadModule(sds path, sds *argv, int argc) {
@ -344,7 +348,9 @@ void loadServerConfigFromString(char *config) {
err = "lfu-decay-time must be 0 or greater";
goto loaderr;
}
} else if ((!strcasecmp(argv[0],"slaveof") ||
}
#if __redis_unmodified_upstream // Disable the cluster and replication API of Redis
else if ((!strcasecmp(argv[0],"slaveof") ||
!strcasecmp(argv[0],"replicaof")) && argc == 3) {
slaveof_linenum = linenum;
server.masterhost = sdsnew(argv[1]);
@ -424,7 +430,9 @@ void loadServerConfigFromString(char *config) {
if ((server.rdb_checksum = yesnotoi(argv[1])) == -1) {
err = "argument must be 'yes' or 'no'"; goto loaderr;
}
} else if (!strcasecmp(argv[0],"activerehashing") && argc == 2) {
}
#endif
else if (!strcasecmp(argv[0],"activerehashing") && argc == 2) {
if ((server.activerehashing = yesnotoi(argv[1])) == -1) {
err = "argument must be 'yes' or 'no'"; goto loaderr;
}
@ -443,9 +451,11 @@ void loadServerConfigFromString(char *config) {
} else if ((!strcasecmp(argv[0],"slave-lazy-flush") ||
!strcasecmp(argv[0],"replica-lazy-flush")) && argc == 2)
{
#if __redis_unmodified_upstream // Disable the cluster API of Redis
if ((server.repl_slave_lazy_flush = yesnotoi(argv[1])) == -1) {
err = "argument must be 'yes' or 'no'"; goto loaderr;
}
#endif
} else if (!strcasecmp(argv[0],"activedefrag") && argc == 2) {
if ((server.active_defrag_enabled = yesnotoi(argv[1])) == -1) {
err = "argument must be 'yes' or 'no'"; goto loaderr;
@ -467,7 +477,9 @@ void loadServerConfigFromString(char *config) {
server.config_hz = atoi(argv[1]);
if (server.config_hz < CONFIG_MIN_HZ) server.config_hz = CONFIG_MIN_HZ;
if (server.config_hz > CONFIG_MAX_HZ) server.config_hz = CONFIG_MAX_HZ;
} else if (!strcasecmp(argv[0],"appendonly") && argc == 2) {
}
#if __redis_unmodified_upstream // Disable the replication API of Redis
else if (!strcasecmp(argv[0],"appendonly") && argc == 2) {
int yes;
if ((yes = yesnotoi(argv[1])) == -1) {
@ -526,7 +538,9 @@ void loadServerConfigFromString(char *config) {
if ((server.aof_use_rdb_preamble = yesnotoi(argv[1])) == -1) {
err = "argument must be 'yes' or 'no'"; goto loaderr;
}
} else if (!strcasecmp(argv[0],"requirepass") && argc == 2) {
}
#endif
else if (!strcasecmp(argv[0],"requirepass") && argc == 2) {
if (strlen(argv[1]) > CONFIG_AUTHPASS_MAX_LEN) {
err = "Password is longer than CONFIG_AUTHPASS_MAX_LEN";
goto loaderr;
@ -540,8 +554,10 @@ void loadServerConfigFromString(char *config) {
err = "dbfilename can't be a path, just a filename";
goto loaderr;
}
#if __redis_unmodified_upstream // Disable the replication API of Redis
zfree(server.rdb_filename);
server.rdb_filename = zstrdup(argv[1]);
#endif
} else if (!strcasecmp(argv[0],"active-defrag-threshold-lower") && argc == 2) {
server.active_defrag_threshold_lower = atoi(argv[1]);
if (server.active_defrag_threshold_lower < 0 ||
@ -628,7 +644,10 @@ void loadServerConfigFromString(char *config) {
err = "Target command name already exists"; goto loaderr;
}
}
} else if (!strcasecmp(argv[0],"cluster-enabled") && argc == 2) {
}
#if __redis_unmodified_upstream // Disable the cluster API of Redis
else if (!strcasecmp(argv[0],"cluster-enabled") && argc == 2) {
if ((server.cluster_enabled = yesnotoi(argv[1])) == -1) {
err = "argument must be 'yes' or 'no'"; goto loaderr;
}
@ -696,7 +715,9 @@ void loadServerConfigFromString(char *config) {
server.lua_time_limit = strtoll(argv[1],NULL,10);
} else if (!strcasecmp(argv[0],"lua-replicate-commands") && argc == 2) {
server.lua_always_replicate_commands = yesnotoi(argv[1]);
} else if (!strcasecmp(argv[0],"slowlog-log-slower-than") &&
}
#endif
else if (!strcasecmp(argv[0],"slowlog-log-slower-than") &&
argc == 2)
{
server.slowlog_log_slower_than = strtoll(argv[1],NULL,10);
@ -796,7 +817,9 @@ void loadServerConfigFromString(char *config) {
err = "sentinel directive while not in sentinel mode";
goto loaderr;
}
#if __redis_unmodified_upstream // Disable sentinel mode
err = sentinelHandleConfiguration(argv+1,argc-1);
#endif
if (err) goto loaderr;
}
} else {
@ -805,6 +828,7 @@ void loadServerConfigFromString(char *config) {
sdsfreesplitres(argv,argc);
}
#if __redis_unmodified_upstream // Disable the cluster API of Redis
/* Sanity checks. */
if (server.cluster_enabled && server.masterhost) {
linenum = slaveof_linenum;
@ -812,7 +836,7 @@ void loadServerConfigFromString(char *config) {
err = "replicaof directive not allowed in cluster mode";
goto loaderr;
}
#endif
sdsfreesplitres(lines,totlines);
return;
@ -924,10 +948,14 @@ void configSetCommand(client *c) {
} config_set_special_field("masterauth") {
zfree(server.masterauth);
server.masterauth = ((char*)o->ptr)[0] ? zstrdup(o->ptr) : NULL;
} config_set_special_field("cluster-announce-ip") {
}
#if __redis_unmodified_upstream // Disable the cluster API of Redis
config_set_special_field("cluster-announce-ip") {
zfree(server.cluster_announce_ip);
server.cluster_announce_ip = ((char*)o->ptr)[0] ? zstrdup(o->ptr) : NULL;
} config_set_special_field("maxclients") {
}
#endif
config_set_special_field("maxclients") {
int orig_value = server.maxclients;
if (getLongLongFromObject(o,&ll) == C_ERR || ll < 1) goto badfmt;
@ -1056,7 +1084,9 @@ void configSetCommand(client *c) {
if (flags == -1) goto badfmt;
server.notify_keyspace_events = flags;
} config_set_special_field_with_alias("slave-announce-ip",
}
#if __redis_unmodified_upstream // Disable the cluster API of Redis
config_set_special_field_with_alias("slave-announce-ip",
"replica-announce-ip")
{
zfree(server.slave_announce_ip);
@ -1070,13 +1100,15 @@ void configSetCommand(client *c) {
"repl-disable-tcp-nodelay",server.repl_disable_tcp_nodelay) {
} config_set_bool_field(
"repl-diskless-sync",server.repl_diskless_sync) {
} config_set_bool_field(
}
config_set_bool_field(
"cluster-require-full-coverage",server.cluster_require_full_coverage) {
} config_set_bool_field(
"cluster-slave-no-failover",server.cluster_slave_no_failover) {
} config_set_bool_field(
"cluster-replica-no-failover",server.cluster_slave_no_failover) {
} config_set_bool_field(
}
config_set_bool_field(
"aof-rewrite-incremental-fsync",server.aof_rewrite_incremental_fsync) {
} config_set_bool_field(
"rdb-save-incremental-fsync",server.rdb_save_incremental_fsync) {
@ -1096,7 +1128,9 @@ void configSetCommand(client *c) {
"slave-ignore-maxmemory",server.repl_slave_ignore_maxmemory) {
} config_set_bool_field(
"replica-ignore-maxmemory",server.repl_slave_ignore_maxmemory) {
} config_set_bool_field(
}
#endif
config_set_bool_field(
"activerehashing",server.activerehashing) {
} config_set_bool_field(
"activedefrag",server.active_defrag_enabled) {
@ -1176,9 +1210,11 @@ void configSetCommand(client *c) {
"zset-max-ziplist-value",server.zset_max_ziplist_value,0,LONG_MAX) {
} config_set_numerical_field(
"hll-sparse-max-bytes",server.hll_sparse_max_bytes,0,LONG_MAX) {
} config_set_numerical_field(
}
config_set_numerical_field(
"lua-time-limit",server.lua_time_limit,0,LONG_MAX) {
} config_set_numerical_field(
}
config_set_numerical_field(
"slowlog-log-slower-than",server.slowlog_log_slower_than,-1,LLONG_MAX) {
} config_set_numerical_field(
"slowlog-max-len",ll,0,LONG_MAX) {
@ -1216,7 +1252,9 @@ void configSetCommand(client *c) {
} config_set_numerical_field(
"min-replicas-max-lag",server.repl_min_slaves_max_lag,0,INT_MAX) {
refreshGoodSlavesCount();
} config_set_numerical_field(
}
#if __redis_unmodified_upstream // Disable the cluster API of Redis
config_set_numerical_field(
"cluster-node-timeout",server.cluster_node_timeout,0,LLONG_MAX) {
} config_set_numerical_field(
"cluster-announce-port",server.cluster_announce_port,0,65535) {
@ -1228,7 +1266,9 @@ void configSetCommand(client *c) {
"cluster-slave-validity-factor",server.cluster_slave_validity_factor,0,INT_MAX) {
} config_set_numerical_field(
"cluster-replica-validity-factor",server.cluster_slave_validity_factor,0,INT_MAX) {
} config_set_numerical_field(
}
#endif
config_set_numerical_field(
"hz",server.config_hz,0,INT_MAX) {
/* Hz is more an hint from the user, so we accept values out of range
* but cap them to reasonable values. */
@ -1331,15 +1371,21 @@ void configGetCommand(client *c) {
serverAssertWithInfo(c,o,sdsEncodedObject(o));
/* String values */
#if __redis_unmodified_upstream // Disable the replication API of Redis
config_get_string_field("dbfilename",server.rdb_filename);
#endif
config_get_string_field("requirepass",server.requirepass);
#if __redis_unmodified_upstream // Disable the cluster API of Redis
config_get_string_field("masterauth",server.masterauth);
config_get_string_field("cluster-announce-ip",server.cluster_announce_ip);
#endif
config_get_string_field("unixsocket",server.unixsocket);
config_get_string_field("logfile",server.logfile);
config_get_string_field("pidfile",server.pidfile);
#if __redis_unmodified_upstream // Disable the replication API of Redis
config_get_string_field("slave-announce-ip",server.slave_announce_ip);
config_get_string_field("replica-announce-ip",server.slave_announce_ip);
#endif
/* Numerical values */
config_get_numerical_field("maxmemory",server.maxmemory);
@ -1355,10 +1401,12 @@ void configGetCommand(client *c) {
config_get_numerical_field("active-defrag-cycle-min",server.active_defrag_cycle_min);
config_get_numerical_field("active-defrag-cycle-max",server.active_defrag_cycle_max);
config_get_numerical_field("active-defrag-max-scan-fields",server.active_defrag_max_scan_fields);
#if __redis_unmodified_upstream // Disable the replication API of Redis
config_get_numerical_field("auto-aof-rewrite-percentage",
server.aof_rewrite_perc);
config_get_numerical_field("auto-aof-rewrite-min-size",
server.aof_rewrite_min_size);
#endif
config_get_numerical_field("hash-max-ziplist-entries",
server.hash_max_ziplist_entries);
config_get_numerical_field("hash-max-ziplist-value",
@ -1387,10 +1435,14 @@ void configGetCommand(client *c) {
config_get_numerical_field("slowlog-max-len",
server.slowlog_max_len);
config_get_numerical_field("port",server.port);
#if __redis_unmodified_upstream // Disable the cluster API of Redis
config_get_numerical_field("cluster-announce-port",server.cluster_announce_port);
config_get_numerical_field("cluster-announce-bus-port",server.cluster_announce_bus_port);
#endif
config_get_numerical_field("tcp-backlog",server.tcp_backlog);
config_get_numerical_field("databases",server.dbnum);
#if __redis_unmodified_upstream // Disable the replication API of Redis
config_get_numerical_field("repl-ping-slave-period",server.repl_ping_slave_period);
config_get_numerical_field("repl-ping-replica-period",server.repl_ping_slave_period);
config_get_numerical_field("repl-timeout",server.repl_timeout);
@ -1406,14 +1458,18 @@ void configGetCommand(client *c) {
config_get_numerical_field("min-replicas-to-write",server.repl_min_slaves_to_write);
config_get_numerical_field("min-slaves-max-lag",server.repl_min_slaves_max_lag);
config_get_numerical_field("min-replicas-max-lag",server.repl_min_slaves_max_lag);
#endif
config_get_numerical_field("hz",server.config_hz);
#if __redis_unmodified_upstream // Disable the cluster API of Redis
config_get_numerical_field("cluster-node-timeout",server.cluster_node_timeout);
config_get_numerical_field("cluster-migration-barrier",server.cluster_migration_barrier);
config_get_numerical_field("cluster-slave-validity-factor",server.cluster_slave_validity_factor);
config_get_numerical_field("cluster-replica-validity-factor",server.cluster_slave_validity_factor);
config_get_numerical_field("repl-diskless-sync-delay",server.repl_diskless_sync_delay);
#endif
config_get_numerical_field("tcp-keepalive",server.tcpkeepalive);
#if __redis_unmodified_upstream // Disable the cluster API of Redis
/* Bool (yes/no) values */
config_get_bool_field("cluster-require-full-coverage",
server.cluster_require_full_coverage);
@ -1437,12 +1493,16 @@ void configGetCommand(client *c) {
server.repl_slave_ignore_maxmemory);
config_get_bool_field("stop-writes-on-bgsave-error",
server.stop_writes_on_bgsave_err);
#endif
config_get_bool_field("daemonize", server.daemonize);
#if __redis_unmodified_upstream // DIsable the replication API of Redis
config_get_bool_field("rdbcompression", server.rdb_compression);
config_get_bool_field("rdbchecksum", server.rdb_checksum);
#endif
config_get_bool_field("activerehashing", server.activerehashing);
config_get_bool_field("activedefrag", server.active_defrag_enabled);
config_get_bool_field("protected-mode", server.protected_mode);
#if __redis_unmodified_upstream // Disable the replication API of Redis
config_get_bool_field("repl-disable-tcp-nodelay",
server.repl_disable_tcp_nodelay);
config_get_bool_field("repl-diskless-sync",
@ -1455,16 +1515,19 @@ void configGetCommand(client *c) {
server.aof_load_truncated);
config_get_bool_field("aof-use-rdb-preamble",
server.aof_use_rdb_preamble);
#endif
config_get_bool_field("lazyfree-lazy-eviction",
server.lazyfree_lazy_eviction);
config_get_bool_field("lazyfree-lazy-expire",
server.lazyfree_lazy_expire);
config_get_bool_field("lazyfree-lazy-server-del",
server.lazyfree_lazy_server_del);
#if __redis_unmodified_upstream // Disable the cluster API of Redis
config_get_bool_field("slave-lazy-flush",
server.repl_slave_lazy_flush);
config_get_bool_field("replica-lazy-flush",
server.repl_slave_lazy_flush);
#endif
config_get_bool_field("dynamic-hz",
server.dynamic_hz);
@ -1475,8 +1538,10 @@ void configGetCommand(client *c) {
server.verbosity,loglevel_enum);
config_get_enum_field("supervised",
server.supervised_mode,supervised_mode_enum);
#if __redis_unmodified_upstream // Disable the replication API of Redis
config_get_enum_field("appendfsync",
server.aof_fsync,aof_fsync_enum);
#endif
config_get_enum_field("syslog-facility",
server.syslog_facility,syslog_facility_enum);
@ -1588,9 +1653,11 @@ int dictSdsKeyCaseCompare(void *privdata, const void *key1, const void *key2);
void dictSdsDestructor(void *privdata, void *val);
void dictListDestructor(void *privdata, void *val);
#if __redis_unmodified_upstream // Disable the sentinel mode
/* Sentinel config rewriting is implemented inside sentinel.c by
* rewriteConfigSentinelOption(). */
void rewriteConfigSentinelOption(struct rewriteConfigState *state);
#endif
dictType optionToLineDictType = {
dictSdsCaseHash, /* hash function */
@ -1903,7 +1970,7 @@ void rewriteConfigDirOption(struct rewriteConfigState *state) {
/* Rewrite the slaveof option. */
void rewriteConfigSlaveofOption(struct rewriteConfigState *state, char *option) {
sds line;
#if __redis_unmodified_upstream // Disable the cluster API of Redis
/* If this is a master, we want all the slaveof config options
* in the file to be removed. Note that if this is a cluster instance
* we don't want a slaveof directive inside redis.conf. */
@ -1911,6 +1978,8 @@ void rewriteConfigSlaveofOption(struct rewriteConfigState *state, char *option)
rewriteConfigMarkAsProcessed(state,option);
return;
}
#endif
line = sdscatprintf(sdsempty(),"%s %s %d", option,
server.masterhost, server.masterport);
rewriteConfigRewriteLine(state,option,line,1);
@ -2123,15 +2192,19 @@ int rewriteConfig(char *path) {
rewriteConfigYesNoOption(state,"daemonize",server.daemonize,0);
rewriteConfigStringOption(state,"pidfile",server.pidfile,CONFIG_DEFAULT_PID_FILE);
rewriteConfigNumericalOption(state,"port",server.port,CONFIG_DEFAULT_SERVER_PORT);
#if __redis_unmodified_upstream // Disable the cluster API of Redis
rewriteConfigNumericalOption(state,"cluster-announce-port",server.cluster_announce_port,CONFIG_DEFAULT_CLUSTER_ANNOUNCE_PORT);
rewriteConfigNumericalOption(state,"cluster-announce-bus-port",server.cluster_announce_bus_port,CONFIG_DEFAULT_CLUSTER_ANNOUNCE_BUS_PORT);
#endif
rewriteConfigNumericalOption(state,"tcp-backlog",server.tcp_backlog,CONFIG_DEFAULT_TCP_BACKLOG);
rewriteConfigBindOption(state);
rewriteConfigStringOption(state,"unixsocket",server.unixsocket,NULL);
rewriteConfigOctalOption(state,"unixsocketperm",server.unixsocketperm,CONFIG_DEFAULT_UNIX_SOCKET_PERM);
rewriteConfigNumericalOption(state,"timeout",server.maxidletime,CONFIG_DEFAULT_CLIENT_TIMEOUT);
rewriteConfigNumericalOption(state,"tcp-keepalive",server.tcpkeepalive,CONFIG_DEFAULT_TCP_KEEPALIVE);
#if __redis_unmodified_upstream // Disable the replication APi of Redis
rewriteConfigNumericalOption(state,"replica-announce-port",server.slave_announce_port,CONFIG_DEFAULT_SLAVE_ANNOUNCE_PORT);
#endif
rewriteConfigEnumOption(state,"loglevel",server.verbosity,loglevel_enum,CONFIG_DEFAULT_VERBOSITY);
rewriteConfigStringOption(state,"logfile",server.logfile,CONFIG_DEFAULT_LOGFILE);
rewriteConfigYesNoOption(state,"syslog-enabled",server.syslog_enabled,CONFIG_DEFAULT_SYSLOG_ENABLED);
@ -2139,12 +2212,15 @@ int rewriteConfig(char *path) {
rewriteConfigSyslogfacilityOption(state);
rewriteConfigSaveOption(state);
rewriteConfigNumericalOption(state,"databases",server.dbnum,CONFIG_DEFAULT_DBNUM);
#if __redis_unmodified_upstream // Disable the replication API of Redis
rewriteConfigYesNoOption(state,"stop-writes-on-bgsave-error",server.stop_writes_on_bgsave_err,CONFIG_DEFAULT_STOP_WRITES_ON_BGSAVE_ERROR);
rewriteConfigYesNoOption(state,"rdbcompression",server.rdb_compression,CONFIG_DEFAULT_RDB_COMPRESSION);
rewriteConfigYesNoOption(state,"rdbchecksum",server.rdb_checksum,CONFIG_DEFAULT_RDB_CHECKSUM);
rewriteConfigStringOption(state,"dbfilename",server.rdb_filename,CONFIG_DEFAULT_RDB_FILENAME);
#endif
rewriteConfigDirOption(state);
rewriteConfigSlaveofOption(state,"replicaof");
#if __redis_unmodified_upstream // Disable the replication API of Redis
rewriteConfigStringOption(state,"replica-announce-ip",server.slave_announce_ip,CONFIG_DEFAULT_SLAVE_ANNOUNCE_IP);
rewriteConfigStringOption(state,"masterauth",server.masterauth,NULL);
rewriteConfigStringOption(state,"cluster-announce-ip",server.cluster_announce_ip,NULL);
@ -2161,6 +2237,7 @@ int rewriteConfig(char *path) {
rewriteConfigNumericalOption(state,"replica-priority",server.slave_priority,CONFIG_DEFAULT_SLAVE_PRIORITY);
rewriteConfigNumericalOption(state,"min-replicas-to-write",server.repl_min_slaves_to_write,CONFIG_DEFAULT_MIN_SLAVES_TO_WRITE);
rewriteConfigNumericalOption(state,"min-replicas-max-lag",server.repl_min_slaves_max_lag,CONFIG_DEFAULT_MIN_SLAVES_MAX_LAG);
#endif
rewriteConfigStringOption(state,"requirepass",server.requirepass,NULL);
rewriteConfigNumericalOption(state,"maxclients",server.maxclients,CONFIG_DEFAULT_MAX_CLIENTS);
rewriteConfigBytesOption(state,"maxmemory",server.maxmemory,CONFIG_DEFAULT_MAXMEMORY);
@ -2176,6 +2253,7 @@ int rewriteConfig(char *path) {
rewriteConfigNumericalOption(state,"active-defrag-cycle-min",server.active_defrag_cycle_min,CONFIG_DEFAULT_DEFRAG_CYCLE_MIN);
rewriteConfigNumericalOption(state,"active-defrag-cycle-max",server.active_defrag_cycle_max,CONFIG_DEFAULT_DEFRAG_CYCLE_MAX);
rewriteConfigNumericalOption(state,"active-defrag-max-scan-fields",server.active_defrag_max_scan_fields,CONFIG_DEFAULT_DEFRAG_MAX_SCAN_FIELDS);
#if __redis_unmodified_upstream // Disable the replication API of Redis
rewriteConfigYesNoOption(state,"appendonly",server.aof_state != AOF_OFF,0);
rewriteConfigStringOption(state,"appendfilename",server.aof_filename,CONFIG_DEFAULT_AOF_FILENAME);
rewriteConfigEnumOption(state,"appendfsync",server.aof_fsync,aof_fsync_enum,CONFIG_DEFAULT_AOF_FSYNC);
@ -2190,6 +2268,7 @@ int rewriteConfig(char *path) {
rewriteConfigNumericalOption(state,"cluster-node-timeout",server.cluster_node_timeout,CLUSTER_DEFAULT_NODE_TIMEOUT);
rewriteConfigNumericalOption(state,"cluster-migration-barrier",server.cluster_migration_barrier,CLUSTER_DEFAULT_MIGRATION_BARRIER);
rewriteConfigNumericalOption(state,"cluster-replica-validity-factor",server.cluster_slave_validity_factor,CLUSTER_DEFAULT_SLAVE_VALIDITY);
#endif
rewriteConfigNumericalOption(state,"slowlog-log-slower-than",server.slowlog_log_slower_than,CONFIG_DEFAULT_SLOWLOG_LOG_SLOWER_THAN);
rewriteConfigNumericalOption(state,"latency-monitor-threshold",server.latency_monitor_threshold,CONFIG_DEFAULT_LATENCY_MONITOR_THRESHOLD);
rewriteConfigNumericalOption(state,"slowlog-max-len",server.slowlog_max_len,CONFIG_DEFAULT_SLOWLOG_MAX_LEN);
@ -2209,19 +2288,25 @@ int rewriteConfig(char *path) {
rewriteConfigYesNoOption(state,"protected-mode",server.protected_mode,CONFIG_DEFAULT_PROTECTED_MODE);
rewriteConfigClientoutputbufferlimitOption(state);
rewriteConfigNumericalOption(state,"hz",server.config_hz,CONFIG_DEFAULT_HZ);
#if __redis_unmodified_upstream // Disable the replication API of Redis
rewriteConfigYesNoOption(state,"aof-rewrite-incremental-fsync",server.aof_rewrite_incremental_fsync,CONFIG_DEFAULT_AOF_REWRITE_INCREMENTAL_FSYNC);
rewriteConfigYesNoOption(state,"rdb-save-incremental-fsync",server.rdb_save_incremental_fsync,CONFIG_DEFAULT_RDB_SAVE_INCREMENTAL_FSYNC);
rewriteConfigYesNoOption(state,"aof-load-truncated",server.aof_load_truncated,CONFIG_DEFAULT_AOF_LOAD_TRUNCATED);
rewriteConfigYesNoOption(state,"aof-use-rdb-preamble",server.aof_use_rdb_preamble,CONFIG_DEFAULT_AOF_USE_RDB_PREAMBLE);
#endif
rewriteConfigEnumOption(state,"supervised",server.supervised_mode,supervised_mode_enum,SUPERVISED_NONE);
rewriteConfigYesNoOption(state,"lazyfree-lazy-eviction",server.lazyfree_lazy_eviction,CONFIG_DEFAULT_LAZYFREE_LAZY_EVICTION);
rewriteConfigYesNoOption(state,"lazyfree-lazy-expire",server.lazyfree_lazy_expire,CONFIG_DEFAULT_LAZYFREE_LAZY_EXPIRE);
rewriteConfigYesNoOption(state,"lazyfree-lazy-server-del",server.lazyfree_lazy_server_del,CONFIG_DEFAULT_LAZYFREE_LAZY_SERVER_DEL);
#if __redis_unmodified_upstream // Disable the replication API of Redis
rewriteConfigYesNoOption(state,"replica-lazy-flush",server.repl_slave_lazy_flush,CONFIG_DEFAULT_SLAVE_LAZY_FLUSH);
#endif
rewriteConfigYesNoOption(state,"dynamic-hz",server.dynamic_hz,CONFIG_DEFAULT_DYNAMIC_HZ);
#if __redis_unmodified_upstream // Disable the sentinel mode of Redis
/* Rewrite Sentinel config if in Sentinel mode. */
if (server.sentinel_mode) rewriteConfigSentinelOption(state);
#endif
/* Step 3: remove all the orphaned lines in the old file, that is, lines
* that were used by a config option and are no longer used, like in case

View File

@ -116,6 +116,7 @@
#define rdb_fsync_range(fd,off,size) fsync(fd)
#endif
#if __redis_unmodified_upstream // Disable setprotitle
/* Check if we can use setproctitle().
* BSD systems have support for it, we provide an implementation for
* Linux and osx. */
@ -129,6 +130,7 @@
void spt_init(int argc, char *argv[]);
void setproctitle(const char *fmt, ...);
#endif
#endif
/* Byte ordering detection */
#include <sys/types.h> /* This will likely define BYTE_ORDER */

View File

@ -31,8 +31,14 @@
#include "cluster.h"
#include "atomicvar.h"
#if __redis_unmodified_upstream // Disable possible syscalls from signal.h and some libs explicitly
#include <signal.h>
#else
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <strings.h>
#endif
/*-----------------------------------------------------------------------------
* C-level DB API
@ -57,6 +63,7 @@ robj *lookupKey(redisDb *db, robj *key, int flags) {
if (de) {
robj *val = dictGetVal(de);
#if __redis_unmodified_upstream // Disable replication API of Redis
/* Update the access time for the ageing algorithm.
* Don't do it if we have a saving child, as this will trigger
* a copy on write madness. */
@ -70,6 +77,19 @@ robj *lookupKey(redisDb *db, robj *key, int flags) {
val->lru = LRU_CLOCK();
}
}
#else
/* Update the access time for the ageing algorithm.
* Don't do it if we have a saving child, as this will trigger
* a copy on write madness. */
if (!(flags & LOOKUP_NOTOUCH))
{
if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) {
updateLFU(val);
} else {
val->lru = LRU_CLOCK();
}
}
#endif
return val;
} else {
return NULL;
@ -109,6 +129,7 @@ robj *lookupKeyReadWithFlags(redisDb *db, robj *key, int flags) {
return NULL;
}
#if __redis_unmodified_upstream // Disable the cluster API of Redis
/* However if we are in the context of a slave, expireIfNeeded() will
* not really try to expire the key, it only returns information
* about the "logical" status of the key: key expiring is up to the
@ -129,6 +150,7 @@ robj *lookupKeyReadWithFlags(redisDb *db, robj *key, int flags) {
server.stat_keyspace_misses++;
return NULL;
}
#endif
}
val = lookupKey(db,key,flags);
if (val == NULL)
@ -175,10 +197,12 @@ void dbAdd(redisDb *db, robj *key, robj *val) {
int retval = dictAdd(db->dict, copy, val);
serverAssertWithInfo(NULL,key,retval == DICT_OK);
#if __redis_unmodified_upstream // Disable the blocked API of Redis
if (val->type == OBJ_LIST ||
val->type == OBJ_ZSET)
signalKeyAsReady(db, key);
if (server.cluster_enabled) slotToKeyAdd(key);
#endif
}
/* Overwrite an existing key with a new value. Incrementing the reference
@ -197,10 +221,12 @@ void dbOverwrite(redisDb *db, robj *key, robj *val) {
}
dictSetVal(db->dict, de, val);
#if __redis_unmodified_upstream // Disable the lazy free API of Redis
if (server.lazyfree_lazy_server_del) {
freeObjAsync(old);
dictSetVal(db->dict, &auxentry, NULL);
}
#endif
dictFreeVal(db->dict, &auxentry);
}
@ -273,7 +299,9 @@ int dbSyncDelete(redisDb *db, robj *key) {
* the key, because it is shared with the main dictionary. */
if (dictSize(db->expires) > 0) dictDelete(db->expires,key->ptr);
if (dictDelete(db->dict,key->ptr) == DICT_OK) {
#if __redis_unmodified_upstream // Disable the cluster API of Redis
if (server.cluster_enabled) slotToKeyDel(key);
#endif
return 1;
} else {
return 0;
@ -283,8 +311,12 @@ int dbSyncDelete(redisDb *db, robj *key) {
/* This is a wrapper whose behavior depends on the Redis lazy free
* configuration. Deletes the key synchronously or asynchronously. */
int dbDelete(redisDb *db, robj *key) {
#if __redis_unmodified_upstream // Disable the lazy free API of Redis
return server.lazyfree_lazy_server_del ? dbAsyncDelete(db,key) :
dbSyncDelete(db,key);
#else
return dbSyncDelete(db,key);
#endif
}
/* Prepare the string object stored at 'key' to be modified destructively
@ -340,7 +372,9 @@ robj *dbUnshareStringValue(redisDb *db, robj *key, robj *o) {
* database(s). Otherwise -1 is returned in the specific case the
* DB number is out of range, and errno is set to EINVAL. */
long long emptyDb(int dbnum, int flags, void(callback)(void*)) {
#if __redis_unmodified_upstream // Disable the lazy free API of Redis
int async = (flags & EMPTYDB_ASYNC);
#endif
long long removed = 0;
if (dbnum < -1 || dbnum >= server.dbnum) {
@ -358,13 +392,19 @@ long long emptyDb(int dbnum, int flags, void(callback)(void*)) {
for (int j = startdb; j <= enddb; j++) {
removed += dictSize(server.db[j].dict);
#if __redis_unmodified_upstream // Disable the lazy free API of Redis
if (async) {
emptyDbAsync(&server.db[j]);
} else {
dictEmpty(server.db[j].dict,callback);
dictEmpty(server.db[j].expires,callback);
}
#else
dictEmpty(server.db[j].dict,callback);
dictEmpty(server.db[j].expires,callback);
#endif
}
#if __redis_unmodified_upstream // Disable the cluster API of Redis
if (server.cluster_enabled) {
if (async) {
slotToKeyFlushAsync();
@ -372,6 +412,7 @@ long long emptyDb(int dbnum, int flags, void(callback)(void*)) {
slotToKeyFlush();
}
}
#endif
if (dbnum == -1) flushSlaveKeysWithExpireList();
return removed;
}
@ -448,6 +489,7 @@ void flushallCommand(client *c) {
signalFlushedDb(-1);
server.dirty += emptyDb(-1,flags,NULL);
addReply(c,shared.ok);
#if __redis_unmodified_upstream // Disable the replication API of Redis
if (server.rdb_child_pid != -1) {
kill(server.rdb_child_pid,SIGUSR1);
rdbRemoveTempFile(server.rdb_child_pid);
@ -461,6 +503,7 @@ void flushallCommand(client *c) {
rdbSave(server.rdb_filename,rsiptr);
server.dirty = saved_dirty;
}
#endif
server.dirty++;
}
@ -470,8 +513,12 @@ void delGenericCommand(client *c, int lazy) {
for (j = 1; j < c->argc; j++) {
expireIfNeeded(c->db,c->argv[j]);
#if __redis_unmodified_upstream // Disable the lazy free API of Redis
int deleted = lazy ? dbAsyncDelete(c->db,c->argv[j]) :
dbSyncDelete(c->db,c->argv[j]);
#else
int deleted = dbSyncDelete(c->db,c->argv[j]);
#endif
if (deleted) {
signalModifiedKey(c->db,c->argv[j]);
notifyKeyspaceEvent(NOTIFY_GENERIC,
@ -509,11 +556,12 @@ void selectCommand(client *c) {
if (getLongFromObjectOrReply(c, c->argv[1], &id,
"invalid DB index") != C_OK)
return;
#if __redis_unmodified_upstream // Disable the cluster API of Redis
if (server.cluster_enabled && id != 0) {
addReplyError(c,"SELECT is not allowed in cluster mode");
return;
}
#endif
if (selectDb(c,id) == C_ERR) {
addReplyError(c,"DB index is out of range");
} else {
@ -809,9 +857,11 @@ void dbsizeCommand(client *c) {
addReplyLongLong(c,dictSize(c->db->dict));
}
#if __redis_unmodified_upstream // Disable replication API of Redis
void lastsaveCommand(client *c) {
addReplyLongLong(c,server.lastsave);
}
#endif
void typeCommand(client *c) {
robj *o;
@ -839,6 +889,7 @@ void typeCommand(client *c) {
}
void shutdownCommand(client *c) {
#if __redis_unmodified_upstream // Disable the replication API of Redis
int flags = 0;
if (c->argc > 2) {
@ -860,10 +911,15 @@ void shutdownCommand(client *c) {
* with half-read data).
*
* Also when in Sentinel mode clear the SAVE flag and force NOSAVE. */
#if __redis_unmodified_upstream // Disable the replication API of Redis
if (server.loading || server.sentinel_mode)
flags = (flags & ~SHUTDOWN_SAVE) | SHUTDOWN_NOSAVE;
if (prepareForShutdown(flags) == C_OK) exit(0);
#endif
addReplyError(c,"Errors trying to SHUTDOWN. Check logs.");
#else
addReplyError(c,"Currently SHUTDOWN command isn't supported.");
#endif
}
void renameGenericCommand(client *c, int nx) {
@ -922,10 +978,12 @@ void moveCommand(client *c) {
int srcid;
long long dbid, expire;
#if __redis_unmodified_upstream // Disable cluster API of Redis
if (server.cluster_enabled) {
addReplyError(c,"MOVE is not allowed in cluster mode");
return;
}
#endif
/* Obtain source and target DB pointers */
src = c->db;
@ -971,6 +1029,7 @@ void moveCommand(client *c) {
addReply(c,shared.cone);
}
#if __redis_unmodified_upstream // Disable the blocked API of Redis
/* Helper function for dbSwapDatabases(): scans the list of keys that have
* one or more blocked clients for B[LR]POP or other blocking commands
* and signal the keys as ready if they are of the right type. See the comment
@ -988,6 +1047,7 @@ void scanDatabaseForReadyLists(redisDb *db) {
}
dictReleaseIterator(di);
}
#endif
/* Swap two databases at runtime so that all clients will magically see
* the new database even if already connected. Note that the client
@ -1015,6 +1075,7 @@ int dbSwapDatabases(int id1, int id2) {
db2->expires = aux.expires;
db2->avg_ttl = aux.avg_ttl;
#if __redis_unmodified_upstream // Disable the blocked API of Redis
/* Now we need to handle clients blocked on lists: as an effect
* of swapping the two DBs, a client that was waiting for list
* X in a given DB, may now actually be unblocked if X happens
@ -1026,6 +1087,7 @@ int dbSwapDatabases(int id1, int id2) {
* if needed. */
scanDatabaseForReadyLists(db1);
scanDatabaseForReadyLists(db2);
#endif
return C_OK;
}
@ -1033,11 +1095,13 @@ int dbSwapDatabases(int id1, int id2) {
void swapdbCommand(client *c) {
long id1, id2;
#if __redis_unmodified_upstream // Disable the cluster API of Redis
/* Not allowed in cluster mode: we have just DB 0 there. */
if (server.cluster_enabled) {
addReplyError(c,"SWAPDB is not allowed in cluster mode");
return;
}
#endif
/* Get the two DBs indexes. */
if (getLongFromObjectOrReply(c, c->argv[1], &id1,
@ -1082,9 +1146,11 @@ void setExpire(client *c, redisDb *db, robj *key, long long when) {
de = dictAddOrFind(db->expires,dictGetKey(kde));
dictSetSignedIntegerVal(de,when);
#if __redis_unmodified_upstream // Disable the cluster API of Redis
int writable_slave = server.masterhost && server.repl_slave_ro == 0;
if (c && writable_slave && !(c->flags & CLIENT_MASTER))
rememberSlaveKeyWithExpire(db,key);
#endif
}
/* Return the expire time of the specified key, or -1 if no expire
@ -1118,9 +1184,11 @@ void propagateExpire(redisDb *db, robj *key, int lazy) {
incrRefCount(argv[0]);
incrRefCount(argv[1]);
#if __redis_unmodified_upstream // Disable the replication API of Redis
if (server.aof_state != AOF_OFF)
feedAppendOnlyFile(server.delCommand,db->id,argv,2);
replicationFeedSlaves(server.slaves,db->id,argv,2);
#endif
decrRefCount(argv[0]);
decrRefCount(argv[1]);
@ -1132,8 +1200,10 @@ int keyIsExpired(redisDb *db, robj *key) {
if (when < 0) return 0; /* No expire for this key */
#if __redis_unmodified_upstream // Disable the expire API of Redis
/* Don't expire anything while loading. It will be done later. */
if (server.loading) return 0;
#endif
/* If we are in the context of a Lua script, we pretend that time is
* blocked to when the Lua script started. This way a key can expire
@ -1141,7 +1211,6 @@ int keyIsExpired(redisDb *db, robj *key) {
* script execution, making propagation to slaves / AOF consistent.
* See issue #1525 on Github for more information. */
mstime_t now = server.lua_caller ? server.lua_time_start : mstime();
return now > when;
}
@ -1182,8 +1251,12 @@ int expireIfNeeded(redisDb *db, robj *key) {
propagateExpire(db,key,server.lazyfree_lazy_expire);
notifyKeyspaceEvent(NOTIFY_EXPIRED,
"expired",key,db->id);
#if __redis_unmodified_upstream // Disable the lazy free API of Redis
return server.lazyfree_lazy_expire ? dbAsyncDelete(db,key) :
dbSyncDelete(db,key);
#else
return dbSyncDelete(db,key);
#endif
}
/* -----------------------------------------------------------------------------
@ -1238,6 +1311,7 @@ int *getKeysUsingCommandTable(struct redisCommand *cmd,robj **argv, int argc, in
* This function uses the command table if a command-specific helper function
* is not required, otherwise it calls the command-specific function. */
int *getKeysFromCommand(struct redisCommand *cmd, robj **argv, int argc, int *numkeys) {
#if __redis_unmodified_upstream // Disable the module API of Redis
if (cmd->flags & CMD_MODULE_GETKEYS) {
return moduleGetCommandKeysViaAPI(cmd,argv,argc,numkeys);
} else if (!(cmd->flags & CMD_MODULE) && cmd->getkeys_proc) {
@ -1245,6 +1319,9 @@ int *getKeysFromCommand(struct redisCommand *cmd, robj **argv, int argc, int *nu
} else {
return getKeysUsingCommandTable(cmd,argv,argc,numkeys);
}
#else
return getKeysUsingCommandTable(cmd,argv,argc,numkeys);
#endif
}
/* Free the result of getKeysFromCommand. */
@ -1463,6 +1540,7 @@ int *xreadGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys)
return keys;
}
#if __redis_unmodified_upstream // Disable the cluster API of Redis
/* Slot to Key API. This is used by Redis Cluster in order to obtain in
* a fast way a key that belongs to a specified hash slot. This is useful
* while rehashing the cluster and in other conditions when we need to
@ -1547,3 +1625,4 @@ unsigned int delKeysInSlot(unsigned int hashslot) {
unsigned int countKeysInSlot(unsigned int hashslot) {
return server.cluster->slots_keys_count[hashslot];
}
#endif

View File

@ -31,6 +31,7 @@
#include "sha1.h" /* SHA1 is used for DEBUG DIGEST */
#include "crc64.h"
#if __redis_unmodified_upstream // Disable the debug API of Redis
#include <arpa/inet.h>
#include <signal.h>
#include <dlfcn.h>
@ -353,7 +354,9 @@ NULL
} else if (!strcasecmp(c->argv[1]->ptr,"log") && c->argc == 3) {
serverLog(LL_WARNING, "DEBUG LOG: %s", (char*)c->argv[2]->ptr);
addReply(c,shared.ok);
} else if (!strcasecmp(c->argv[1]->ptr,"reload")) {
}
#if __redis_unmodified_upstream // Disable the replication API of Redis
else if (!strcasecmp(c->argv[1]->ptr,"reload")) {
rdbSaveInfo rsi, *rsiptr;
rsiptr = rdbPopulateSaveInfo(&rsi);
if (rdbSave(server.rdb_filename,rsiptr) != C_OK) {
@ -383,7 +386,9 @@ NULL
server.dirty = 0; /* Prevent AOF / replication */
serverLog(LL_WARNING,"Append Only File loaded by DEBUG LOADAOF");
addReply(c,shared.ok);
} else if (!strcasecmp(c->argv[1]->ptr,"object") && c->argc == 3) {
}
#endif
else if (!strcasecmp(c->argv[1]->ptr,"object") && c->argc == 3) {
dictEntry *de;
robj *val;
char *strenc;
@ -427,7 +432,7 @@ NULL
nextra += used;
remaining -= used;
}
#if __redis_unmodified_upstream // Disable the replication API of Redis
addReplyStatusFormat(c,
"Value at:%p refcount:%d "
"encoding:%s serializedlength:%zu "
@ -435,6 +440,7 @@ NULL
(void*)val, val->refcount,
strenc, rdbSavedObjectLen(val),
val->lru, estimateObjectIdleTime(val)/1000, extra);
#endif
} else if (!strcasecmp(c->argv[1]->ptr,"sdslen") && c->argc == 3) {
dictEntry *de;
robj *val;
@ -543,12 +549,16 @@ NULL
{
server.active_expire_enabled = atoi(c->argv[2]->ptr);
addReply(c,shared.ok);
} else if (!strcasecmp(c->argv[1]->ptr,"lua-always-replicate-commands") &&
}
#if __redis_unmodified_upstream // Disable the replication API of Redis
else if (!strcasecmp(c->argv[1]->ptr,"lua-always-replicate-commands") &&
c->argc == 3)
{
server.lua_always_replicate_commands = atoi(c->argv[2]->ptr);
addReply(c,shared.ok);
} else if (!strcasecmp(c->argv[1]->ptr,"error") && c->argc == 3) {
}
#endif
else if (!strcasecmp(c->argv[1]->ptr,"error") && c->argc == 3) {
sds errstr = sdsnewlen("-",1);
errstr = sdscatsds(errstr,c->argv[2]->ptr);
@ -617,8 +627,10 @@ NULL
}
} else if (!strcasecmp(c->argv[1]->ptr,"change-repl-id") && c->argc == 2) {
serverLog(LL_WARNING,"Changing replication IDs after receiving DEBUG change-repl-id");
#if __redis_unmodified_upstream // Disable of replication API of Redis
changeReplicationId();
clearReplicationId2();
#endif
addReply(c,shared.ok);
} else if (!strcasecmp(c->argv[1]->ptr,"stringmatch-test") && c->argc == 2)
{
@ -629,7 +641,10 @@ NULL
return;
}
}
#else
#include <stdlib.h>
#include <stdio.h>
#endif
/* =========================== Crash handling ============================== */
void _serverAssert(const char *estr, const char *file, int line) {
@ -642,7 +657,11 @@ void _serverAssert(const char *estr, const char *file, int line) {
server.assert_line = line;
serverLog(LL_WARNING,"(forcing SIGSEGV to print the bug report.)");
#endif
#if __redis_unmodified_upstream // Use unreachable Wasm instructions instead of invalid pointer dereference
*((char*)-1) = 'x';
#else
__builtin_unreachable();
#endif
}
void _serverAssertPrintClientInfo(const client *c) {
@ -720,7 +739,11 @@ void _serverPanic(const char *file, int line, const char *msg, ...) {
serverLog(LL_WARNING,"(forcing SIGSEGV in order to print the stack trace)");
#endif
serverLog(LL_WARNING,"------------------------------------------------");
#if __redis_unmodified_upstream // Use unreachable Wasm instructions instead of invalid pointer dereference
*((char*)-1) = 'x';
#else
__builtin_unreachable();
#endif
}
void bugReportStart(void) {
@ -731,6 +754,7 @@ void bugReportStart(void) {
}
}
#if __redis_unmodified_upstream // Disable the extended bugreport since there are no such capabilities in Wasm yet
#ifdef HAVE_BACKTRACE
static void *getMcontextEip(ucontext_t *uc) {
#if defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_6)
@ -1334,8 +1358,10 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) {
" Suspect RAM error? Use redis-server --test-memory to verify it.\n\n"
);
#if __redis_unmodified_upstream // Disable the deamonization of Redis
/* free(messages); Don't call free() with possibly corrupted memory. */
if (server.daemonize && server.supervised == 0) unlink(server.pidfile);
#endif
/* Make sure we exit with the right signal at the end. So for instance
* the core will be dumped if enabled. */
@ -1444,3 +1470,4 @@ void disableWatchdog(void) {
sigaction(SIGALRM, &act, NULL);
server.watchdog_period = 0;
}
#endif

View File

@ -30,6 +30,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#if __redis_unmodified_upstream // Disable writing to files
#include <stdio.h>
#define D(...) \
do { \
@ -39,3 +40,9 @@
fprintf(fp,"\n"); \
fclose(fp); \
} while (0);
#else
// TODO: add logs
#define D(...) \
do { \
} while (0);
#endif

View File

@ -35,7 +35,9 @@
*/
#include "server.h"
#if __redis_unmodified_upstream // Disable imports from time.h
#include <time.h>
#endif
#include <assert.h>
#include <stddef.h>

View File

@ -41,7 +41,11 @@
#include <string.h>
#include <stdarg.h>
#include <limits.h>
#if __redis_unmodified_upstream // Disable imports from time.h
#include <sys/time.h>
#else
#include "server.h"
#endif
#include "dict.h"
#include "zmalloc.h"
@ -230,21 +234,27 @@ int dictRehash(dict *d, int n) {
return 1;
}
#if __redis_unmodified_upstream // Currently it is impossible to get the current time inside a Wasm module
long long timeInMilliseconds(void) {
struct timeval tv;
gettimeofday(&tv,NULL);
return (((long long)tv.tv_sec)*1000)+(tv.tv_usec/1000);
}
#endif
/* Rehash for an amount of time between ms milliseconds and ms+1 milliseconds */
int dictRehashMilliseconds(dict *d, int ms) {
#if __redis_unmodified_upstream // Disable the lazy, time-oriented rehashing
long long start = timeInMilliseconds();
#endif
int rehashes = 0;
while(dictRehash(d,100)) {
rehashes += 100;
#if __redis_unmodified_upstream // Disable the lazy, time-oriented rehashing
if (timeInMilliseconds()-start > ms) break;
#endif
}
return rehashes;
}
@ -489,7 +499,9 @@ dictEntry *dictFind(dict *d, const void *key)
return he;
he = he->next;
}
if (!dictIsRehashing(d)) return NULL;
if (!dictIsRehashing(d)) {
return NULL;
}
}
return NULL;
}

View File

@ -34,6 +34,12 @@
#include "bio.h"
#include "atomicvar.h"
#if __redis_unmodified_upstream // Include some libs explicitly
#else
#include <stdlib.h>
#include <string.h>
#endif
/* ----------------------------------------------------------------------------
* Data structures
* --------------------------------------------------------------------------*/
@ -351,6 +357,7 @@ unsigned long LFUDecrAndReturn(robj *o) {
* returns the sum of AOF and slaves buffer. */
size_t freeMemoryGetNotCountedMemory(void) {
size_t overhead = 0;
#if __redis_unmodified_upstream // Disable the cluster API of Redis
int slaves = listLength(server.slaves);
if (slaves) {
@ -366,6 +373,7 @@ size_t freeMemoryGetNotCountedMemory(void) {
if (server.aof_state != AOF_OFF) {
overhead += sdsalloc(server.aof_buf)+aofRewriteBufferSize();
}
#endif
return overhead;
}
@ -446,17 +454,25 @@ int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree, float *lev
int freeMemoryIfNeeded(void) {
/* By default replicas should ignore maxmemory
* and just be masters exact copies. */
#if __redis_unmodified_upstream // Disable the cluster API of Redis
if (server.masterhost && server.repl_slave_ignore_maxmemory) return C_OK;
#endif
size_t mem_reported, mem_tofree, mem_freed;
mstime_t latency, eviction_latency;
long long delta;
#if __redis_unmodified_upstream // Disable the cluster API of Redis
int slaves = listLength(server.slaves);
#else
int slaves = 0;
#endif
/* When clients are paused the dataset should be static not just from the
* POV of clients not being able to write, but also from the POV of
* expires and evictions of keys not being performed. */
#if __redis_unmodified_upstream // Disable the cluster API of Redis
if (clientsArePaused()) return C_OK;
#endif
if (getMaxmemoryState(&mem_reported,NULL,&mem_tofree,NULL) == C_OK)
return C_OK;
@ -564,10 +580,14 @@ int freeMemoryIfNeeded(void) {
* we only care about memory used by the key space. */
delta = (long long) zmalloc_used_memory();
latencyStartMonitor(eviction_latency);
#if __redis_unmodified_upstream // Disable the lazy free API of Redis
if (server.lazyfree_lazy_eviction)
dbAsyncDelete(db,keyobj);
else
dbSyncDelete(db,keyobj);
#else
dbSyncDelete(db,keyobj);
#endif
latencyEndMonitor(eviction_latency);
latencyAddSampleIfNeeded("eviction-del",eviction_latency);
latencyRemoveNestedEvent(latency,eviction_latency);
@ -583,7 +603,9 @@ int freeMemoryIfNeeded(void) {
* start spending so much time here that is impossible to
* deliver data to the slaves fast enough, so we force the
* transmission here inside the loop. */
#if __redis_unmodified_upstream // Disable the cluster API of Redis
if (slaves) flushSlavesOutputBuffers();
#endif
/* Normally our stop condition is the ability to release
* a fixed, pre-computed amount of memory. However when we
@ -611,6 +633,7 @@ int freeMemoryIfNeeded(void) {
return C_OK;
cant_free:
#if __redis_unmodified_upstream // Disable the lazy memory freeing
/* We are here if we are not able to reclaim memory. There is only one
* last thing we can try: check if the lazyfree thread has jobs in queue
* and wait... */
@ -619,6 +642,7 @@ cant_free:
break;
usleep(1000);
}
#endif
return C_ERR;
}
@ -630,6 +654,10 @@ cant_free:
*
*/
int freeMemoryIfNeededAndSafe(void) {
#if __redis_unmodified_upstream // Disable the replication API of Redis
if (server.lua_timedout || server.loading) return C_OK;
#else
if (server.lua_timedout) return C_OK;
#endif
return freeMemoryIfNeeded();
}

View File

@ -58,10 +58,14 @@ int activeExpireCycleTryExpire(redisDb *db, dictEntry *de, long long now) {
robj *keyobj = createStringObject(key,sdslen(key));
propagateExpire(db,keyobj,server.lazyfree_lazy_expire);
#if __redis_unmodified_upstream // Disable the lazy free API of Redis
if (server.lazyfree_lazy_expire)
dbAsyncDelete(db,keyobj);
else
dbSyncDelete(db,keyobj);
#else
dbSyncDelete(db,keyobj);
#endif
notifyKeyspaceEvent(NOTIFY_EXPIRED,
"expired",keyobj,db->id);
decrRefCount(keyobj);
@ -105,10 +109,12 @@ void activeExpireCycle(int type) {
int dbs_per_call = CRON_DBS_PER_CALL;
long long start = ustime(), timelimit, elapsed;
#if __redis_unmodified_upstream // Disable the cluster API of Redis
/* When clients are paused the dataset should be static not just from the
* POV of clients not being able to write, but also from the POV of
* expires and evictions of keys not being performed. */
if (clientsArePaused()) return;
#endif
if (type == ACTIVE_EXPIRE_CYCLE_FAST) {
/* Don't start a fast cycle if the previous cycle did not exit
@ -424,11 +430,19 @@ void expireGenericCommand(client *c, long long basetime, int unit) {
*
* Instead we take the other branch of the IF statement setting an expire
* (possibly in the past) and wait for an explicit DEL from the master. */
#if __redis_unmodified_upstream // Disable the replication API of Redis
if (when <= mstime() && !server.loading && !server.masterhost) {
#else
if (when <= mstime() && !server.masterhost) {
#endif
robj *aux;
#if __redis_unmodified_upstream // Disable the lazy free API of Redis
int deleted = server.lazyfree_lazy_expire ? dbAsyncDelete(c->db,key) :
dbSyncDelete(c->db,key);
#else
int deleted = dbSyncDelete(c->db,key);
#endif
serverAssertWithInfo(c,key,deleted);
server.dirty++;

View File

@ -31,6 +31,12 @@
#include "geo.h"
#include "geohash_helper.h"
#include "debugmacro.h"
#if __redis_unmodified_upstream // Include some libs explicitly
#else
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#endif
/* Things exported from t_zset.c only for geo.c, since it is the only other
* part of Redis that requires close zset introspection. */

View File

@ -33,6 +33,12 @@
#include <stdint.h>
#include <math.h>
#if __redis_unmodified_upstream // Include some libs explicitly
#else
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#endif
/* The Redis HyperLogLog implementation is based on the following ideas:
*
@ -1036,7 +1042,7 @@ uint64_t hllCount(struct hllhdr *hdr, int *invalid) {
z *= 0.5;
}
z += m * hllSigma(reghisto[0]/(double)m);
E = llroundl(HLL_ALPHA_INF*m*m/z);
E = lround(HLL_ALPHA_INF*m*m/z);
return (uint64_t) E;
}

View File

@ -34,6 +34,12 @@
*/
#include "server.h"
#if __redis_unmodified_upstream // Include some libs explicitly
#else
#include <stdio.h>
#include <string.h>
#include <strings.h>
#endif
/* Dictionary type for latency events. */
int dictStringKeyCompare(void *privdata, const void *key1, const void *key2) {
@ -58,6 +64,7 @@ dictType latencyTimeSeriesDictType = {
/* ------------------------- Utility functions ------------------------------ */
#if __redis_unmodified_upstream // Disable writing to file
#ifdef __linux__
/* Returns 1 if Transparent Huge Pages support is enabled in the kernel.
* Otherwise (or if we are unable to check) 0 is returned. */
@ -74,6 +81,7 @@ int THPIsEnabled(void) {
return (strstr(buf,"[never]") == NULL) ? 1 : 0;
}
#endif
#endif
/* Report the amount of AnonHugePages in smap, in bytes. If the return
* value of the function is non-zero, the process is being targeted by
@ -97,7 +105,11 @@ void latencyMonitorInit(void) {
* server.latency_monitor_threshold. */
void latencyAddSample(char *event, mstime_t latency) {
struct latencyTimeSeries *ts = dictFetchValue(server.latency_events,event);
#if __redis_unmodified_upstream // Currently it is impossible to get the current time inside a Wasm module
time_t now = time(NULL);
#else
time_t now = ustime();
#endif
int prev;
/* Create the time series if it does not exist. */
@ -120,7 +132,11 @@ void latencyAddSample(char *event, mstime_t latency) {
return;
}
#if __redis_unmodified_upstream // Currently it is impossible to get the current time inside a Wasm module
ts->samples[ts->idx].time = time(NULL);
#else
ts->samples[ts->idx].time = ustime();
#endif
ts->samples[ts->idx].latency = latency;
ts->idx++;
@ -196,7 +212,11 @@ void analyzeLatencyForEvent(char *event, struct latencyStats *ls) {
* the second a range of seconds. */
if (ls->samples) {
ls->avg = sum / ls->samples;
#if __redis_unmodified_upstream // Currently it is impossible to get the current time inside a Wasm module
ls->period = time(NULL) - ls->period;
#else
ls->period = ustime() - ls->period;
#endif
if (ls->period == 0) ls->period = 1;
}
@ -442,11 +462,11 @@ sds createLatencyReport(void) {
if (advise_no_appendfsync) {
report = sdscat(report,"- Assuming from the point of view of data safety this is viable in your environment, you could try to enable the 'no-appendfsync-on-rewrite' option, so that fsync will not be performed while there is a child rewriting the AOF file or producing an RDB file (the moment where there is high disk contention).\n");
}
#if __redis_unmodified_upstream // Disable the replication API of Redis
if (advise_relax_fsync_policy && server.aof_fsync == AOF_FSYNC_ALWAYS) {
report = sdscat(report,"- Your fsync policy is set to 'always'. It is very hard to get good performances with such a setup, if possible try to relax the fsync policy to 'onesec'.\n");
}
#endif
if (advise_write_load_info) {
report = sdscat(report,"- Latency during the AOF atomic rename operation or when the final difference is flushed to the AOF file at the end of the rewrite, sometimes is caused by very high write load, causing the AOF buffer to get very large. If possible try to send less commands to accomplish the same work, or use Lua scripts to group multiple operations into a single EVALSHA call.\n");
}
@ -535,7 +555,11 @@ sds latencyCommandGenSparkeline(char *event, struct latencyTimeSeries *ts) {
}
/* Use as label the number of seconds / minutes / hours / days
* ago the event happened. */
#if __redis_unmodified_upstream // Currently it is impossible to get the current time inside a Wasm module
elapsed = time(NULL) - ts->samples[i].time;
#else
elapsed = ustime() - ts->samples[i].time;
#endif
if (elapsed < 60)
snprintf(buf,sizeof(buf),"%ds",elapsed);
else if (elapsed < 3600)

View File

@ -36,6 +36,12 @@
#include "server.h"
#include <math.h>
#if __redis_unmodified_upstream // Include some libs explicitly
#else
#include <stdlib.h>
#include <string.h>
#endif
/* This structure represents our canvas. Drawing functions will take a pointer
* to a canvas to write to it. Later the canvas can be rendered to a string
* suitable to be printed on the screen, using unicode Braille characters. */

View File

@ -676,8 +676,10 @@ int commandFlagsFromString(char *s) {
int RM_CreateCommand(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc cmdfunc, const char *strflags, int firstkey, int lastkey, int keystep) {
int flags = strflags ? commandFlagsFromString((char*)strflags) : 0;
if (flags == -1) return REDISMODULE_ERR;
#if __redis_unmodified_upstream // Disable the module API of Redis
if ((flags & CMD_MODULE_NO_CLUSTER) && server.cluster_enabled)
return REDISMODULE_ERR;
#endif
struct redisCommand *rediscmd;
RedisModuleCommandProxy *cp;
@ -1428,8 +1430,10 @@ int RM_GetContextFlags(RedisModuleCtx *ctx) {
flags |= REDISMODULE_CTX_FLAGS_REPLICATED;
}
#if __redis_unmodified_upstream // Disable the cluser API of Redis
if (server.cluster_enabled)
flags |= REDISMODULE_CTX_FLAGS_CLUSTER;
#endif
/* Maxmemory and eviction policy */
if (server.maxmemory > 0) {
@ -1439,6 +1443,7 @@ int RM_GetContextFlags(RedisModuleCtx *ctx) {
flags |= REDISMODULE_CTX_FLAGS_EVICT;
}
#if __redis_unmodified_upstream // Disable the replication and cluster API of Redis
/* Persistence flags */
if (server.aof_state != AOF_OFF)
flags |= REDISMODULE_CTX_FLAGS_AOF;
@ -1453,6 +1458,7 @@ int RM_GetContextFlags(RedisModuleCtx *ctx) {
if (server.repl_slave_ro)
flags |= REDISMODULE_CTX_FLAGS_READONLY;
}
#endif
/* OOM flag. */
float level;
@ -2752,6 +2758,7 @@ RedisModuleCallReply *RM_Call(RedisModuleCtx *ctx, const char *cmdname, const ch
goto cleanup;
}
#if __redis_unmodified_upstream // Disable the cluster API of Redis
/* If this is a Redis Cluster node, we need to make sure the module is not
* trying to access non-local keys, with the exception of commands
* received from our master. */
@ -2766,6 +2773,7 @@ RedisModuleCallReply *RM_Call(RedisModuleCtx *ctx, const char *cmdname, const ch
goto cleanup;
}
}
#endif
/* If we are using single commands replication, we need to wrap what
* we propagate into a MULTI/EXEC block, so that it will be atomic like
@ -3087,6 +3095,7 @@ void *RM_ModuleTypeGetValue(RedisModuleKey *key) {
return mv->value;
}
#if __redis_unmodified_upstream // Disable the replication API of Redis
/* --------------------------------------------------------------------------
* RDB loading and saving functions
* -------------------------------------------------------------------------- */
@ -3306,6 +3315,7 @@ loaderr:
moduleRDBLoadError(io);
return 0; /* Never reached. */
}
#endif
/* --------------------------------------------------------------------------
* Key digest API (DEBUG DIGEST interface for modules types)
@ -3367,6 +3377,7 @@ void RM_DigestEndSequence(RedisModuleDigest *md) {
memset(md->o,0,sizeof(md->o));
}
#if __redis_unmodified_upstream // Disable the replication API of Redis
/* --------------------------------------------------------------------------
* AOF API for modules data types
* -------------------------------------------------------------------------- */
@ -3421,6 +3432,7 @@ void RM_EmitAOF(RedisModuleIO *io, const char *cmdname, const char *fmt, ...) {
zfree(argv);
return;
}
#endif
/* --------------------------------------------------------------------------
* IO context handling
@ -3499,6 +3511,7 @@ void RM_LogIOError(RedisModuleIO *io, const char *levelstr, const char *fmt, ...
va_end(ap);
}
#if __redis_unmodified_upstream // Disable the blocking API of Redis
/* --------------------------------------------------------------------------
* Blocking clients from modules
* -------------------------------------------------------------------------- */
@ -3793,6 +3806,7 @@ RedisModuleBlockedClient *RM_GetBlockedClientHandle(RedisModuleCtx *ctx) {
int RM_BlockedClientDisconnected(RedisModuleCtx *ctx) {
return (ctx->flags & REDISMODULE_CTX_BLOCKED_DISCONNECTED) != 0;
}
#endif
/* --------------------------------------------------------------------------
* Thread Safe Contexts
@ -3977,6 +3991,7 @@ void moduleUnsubscribeNotifications(RedisModule *module) {
}
}
#if __redis_unmodified_upstream // Disable the cluster API of Redis
/* --------------------------------------------------------------------------
* Modules Cluster API
* -------------------------------------------------------------------------- */
@ -4229,6 +4244,7 @@ void RM_SetClusterFlags(RedisModuleCtx *ctx, uint64_t flags) {
if (flags & REDISMODULE_CLUSTER_FLAG_NO_REDIRECTION)
server.cluster_module_flags |= CLUSTER_MODULE_FLAG_NO_REDIRECTION;
}
#endif
/* --------------------------------------------------------------------------
* Modules Timers API
@ -5136,6 +5152,7 @@ void moduleRegisterCoreAPI(void) {
REGISTER_API(ModuleTypeSetValue);
REGISTER_API(ModuleTypeGetType);
REGISTER_API(ModuleTypeGetValue);
#if __redis_unmodified_upstream // Disable the replication API of Redis
REGISTER_API(SaveUnsigned);
REGISTER_API(LoadUnsigned);
REGISTER_API(SaveSigned);
@ -5149,18 +5166,21 @@ void moduleRegisterCoreAPI(void) {
REGISTER_API(SaveFloat);
REGISTER_API(LoadFloat);
REGISTER_API(EmitAOF);
#endif
REGISTER_API(Log);
REGISTER_API(LogIOError);
REGISTER_API(StringAppendBuffer);
REGISTER_API(RetainString);
REGISTER_API(StringCompare);
REGISTER_API(GetContextFromIO);
#if __redis_unmodified_upstream // Disable the blocking API of Redis
REGISTER_API(BlockClient);
REGISTER_API(UnblockClient);
REGISTER_API(IsBlockedReplyRequest);
REGISTER_API(IsBlockedTimeoutRequest);
REGISTER_API(GetBlockedClientPrivateData);
REGISTER_API(AbortBlock);
#endif
REGISTER_API(Milliseconds);
REGISTER_API(GetThreadSafeContext);
REGISTER_API(FreeThreadSafeContext);
@ -5170,22 +5190,28 @@ void moduleRegisterCoreAPI(void) {
REGISTER_API(DigestAddLongLong);
REGISTER_API(DigestEndSequence);
REGISTER_API(SubscribeToKeyspaceEvents);
#if __redis_unmodified_upstream // Disable the cluster API of Redis
REGISTER_API(RegisterClusterMessageReceiver);
REGISTER_API(SendClusterMessage);
REGISTER_API(GetClusterNodeInfo);
REGISTER_API(GetClusterNodesList);
REGISTER_API(FreeClusterNodesList);
#endif
REGISTER_API(CreateTimer);
REGISTER_API(StopTimer);
REGISTER_API(GetTimerInfo);
#if __redis_unmodified_upstream // Disable the cluster API of Redis
REGISTER_API(GetMyClusterID);
REGISTER_API(GetClusterSize);
#endif
REGISTER_API(GetRandomBytes);
REGISTER_API(GetRandomHexChars);
#if __redis_unmodified_upstream // Disable the cluster API of Redis
REGISTER_API(BlockedClientDisconnected);
REGISTER_API(SetDisconnectCallback);
REGISTER_API(GetBlockedClientHandle);
REGISTER_API(SetClusterFlags);
#endif
REGISTER_API(CreateDict);
REGISTER_API(FreeDict);
REGISTER_API(DictSize);

View File

@ -28,6 +28,10 @@
*/
#include "server.h"
#if __redis_unmodified_upstream // Include some libs explicitly
#else
#include <string.h>
#endif
/* ================================ MULTI/EXEC ============================== */
@ -139,6 +143,7 @@ void execCommand(client *c) {
goto handle_monitor;
}
#if __redis_unmodified_upstream // Disable the cluster API of Redis
/* If there are write commands inside the transaction, and this is a read
* only slave, we want to send an error. This happens when the transaction
* was initiated when the instance was a master or a writable replica and
@ -153,7 +158,7 @@ void execCommand(client *c) {
discardTransaction(c);
goto handle_monitor;
}
#endif
/* Exec all the queued commands */
unwatchAllKeys(c); /* Unwatch ASAP otherwise we'll waste CPU cycles */
orig_argv = c->argv;
@ -175,7 +180,11 @@ void execCommand(client *c) {
must_propagate = 1;
}
#if __redis_unmodified_upstream // Disable the cluster API of Redis
call(c,server.loading ? CMD_CALL_NONE : CMD_CALL_FULL);
#else
call(c, CMD_CALL_FULL);
#endif
/* Commands may alter argc/argv, restore mstate. */
c->mstate.commands[j].argc = c->argc;
@ -187,11 +196,13 @@ void execCommand(client *c) {
c->cmd = orig_cmd;
discardTransaction(c);
#if __redis_unmodified_upstream // Disable the cluster API of Redis
/* Make sure the EXEC command will be propagated as well if MULTI
* was already propagated. */
if (must_propagate) {
int is_master = server.masterhost == NULL;
server.dirty++;
/* If inside the MULTI/EXEC block this instance was suddenly
* switched from master to slave (using the SLAVEOF command), the
* initial MULTI was propagated into the replication backlog, but the
@ -211,6 +222,10 @@ handle_monitor:
* table, and we do it here with correct ordering. */
if (listLength(server.monitors) && !server.loading)
replicationFeedMonitors(c,server.monitors,c->db->id,c->argv,c->argc);
#else
handle_monitor:
return;
#endif
}
/* ===================== WATCH (CAS alike for MULTI/EXEC) ===================

View File

@ -29,9 +29,14 @@
#include "server.h"
#include "atomicvar.h"
#if __redis_unmodified_upstream // Disable imports from uio.h and include some libs explicitly
#include <sys/uio.h>
#else
#include <math.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#endif
static void setProtocolError(const char *errstr, client *c);
@ -85,6 +90,7 @@ void linkClient(client *c) {
client *createClient(int fd) {
client *c = zmalloc(sizeof(client));
#if __redis_unmodified_upstream // Disable the net API of Redis
/* passing -1 as fd it is possible to create a non connected client.
* This is useful since all the commands needs to be executed
* in the context of a client. When commands are executed in other
@ -102,6 +108,7 @@ client *createClient(int fd) {
return NULL;
}
}
#endif
selectDb(c,0);
uint64_t client_id;
@ -124,6 +131,7 @@ client *createClient(int fd) {
c->flags = 0;
c->ctime = c->lastinteraction = server.unixtime;
c->authenticated = 0;
#if __redis_unmodified_upstream // Disable the replication API of Redis
c->replstate = REPL_STATE_NONE;
c->repl_put_online_on_ack = 0;
c->reploff = 0;
@ -133,6 +141,7 @@ client *createClient(int fd) {
c->slave_listening_port = 0;
c->slave_ip[0] = '\0';
c->slave_capa = SLAVE_CAPA_NONE;
#endif
c->reply = listCreate();
c->reply_bytes = 0;
c->obuf_soft_limit_reached_time = 0;
@ -147,7 +156,9 @@ client *createClient(int fd) {
c->bpop.xread_group_noack = 0;
c->bpop.numreplicas = 0;
c->bpop.reploffset = 0;
#if __redis_unmodified_upstream // Disable the replication API of Redis
c->woff = 0;
#endif
c->watched_keys = listCreate();
c->pubsub_channels = dictCreate(&objectKeyPointerValueDictType,NULL);
c->pubsub_patterns = listCreate();
@ -160,6 +171,7 @@ client *createClient(int fd) {
return c;
}
#if __redis_unmodified_upstream // Disable the replication API of Redis
/* This funciton puts the client in the queue of clients that should write
* their output buffers to the socket. Note that it does not *yet* install
* the write handler, to start clients are put in a queue of clients that need
@ -185,6 +197,7 @@ void clientInstallWriteHandler(client *c) {
listAddNodeHead(server.clients_pending_write,c);
}
}
#endif
/* This function is called every time we are going to transmit new data
* to the client. The behavior is the following:
@ -209,6 +222,7 @@ void clientInstallWriteHandler(client *c) {
* data to the clients output buffers. If the function returns C_ERR no
* data should be appended to the output buffers. */
int prepareClientToWrite(client *c) {
#if __redis_unmodified_upstream // Client has to be able to write output
/* If it's the Lua client we always return ok without installing any
* handler since there is no socket at all. */
if (c->flags & (CLIENT_LUA|CLIENT_MODULE)) return C_OK;
@ -226,6 +240,7 @@ int prepareClientToWrite(client *c) {
/* Schedule the client to write the output buffers to the socket, unless
* it should already be setup to do so (it has already pending data). */
if (!clientHasPendingReplies(c)) clientInstallWriteHandler(c);
#endif
/* Authorize the caller to queue in the output buffer of this client. */
return C_OK;
@ -295,6 +310,7 @@ void _addReplyStringToList(client *c, const char *s, size_t len) {
/* Add the object 'obj' string representation to the client output buffer. */
void addReply(client *c, robj *obj) {
if (prepareClientToWrite(c) != C_OK) return;
if (sdsEncodedObject(obj)) {
@ -471,6 +487,7 @@ void setDeferredMultiBulkLength(client *c, void *node, long length) {
void addReplyDouble(client *c, double d) {
char dbuf[128], sbuf[128];
int dlen, slen;
if (isinf(d)) {
/* Libc in odd systems (Hi Solaris!) will format infinite in a
* different way, so better to handle it in an explicit way. */
@ -646,6 +663,7 @@ int clientHasPendingReplies(client *c) {
return c->bufpos || listLength(c->reply);
}
#if __redis_unmodified_upstream // Disable the net API of Redis
#define MAX_ACCEPTS_PER_CALL 1000
static void acceptCommonHandler(int fd, int flags, char *ip) {
client *c;
@ -755,8 +773,9 @@ void acceptUnixHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
acceptCommonHandler(cfd,CLIENT_UNIX_SOCKET,NULL);
}
}
#endif
static void freeClientArgv(client *c) {
void freeClientArgv(client *c) {
int j;
for (j = 0; j < c->argc; j++)
decrRefCount(c->argv[j]);
@ -764,6 +783,7 @@ static void freeClientArgv(client *c) {
c->cmd = NULL;
}
#if __redis_unmodified_upstream // Disable the cluster API of Redis
/* Close all the slaves connections. This is useful in chained replication
* when we resync with our own master and want to force all our slaves to
* resync with us as well. */
@ -773,6 +793,7 @@ void disconnectSlaves(void) {
freeClient((client*)ln->value);
}
}
#endif
/* Remove the specified client from global lists where the client could
* be referenced, not including the Pub/Sub channels.
@ -783,6 +804,7 @@ void unlinkClient(client *c) {
/* If this is marked as current client unset it. */
if (server.current_client == c) server.current_client = NULL;
#if __redis_unmodified_upstream // Disable the net API of Redis
/* Certain operations must be done only if the client has an active socket.
* If the client was already unlinked or if it's a "fake client" the
* fd is already set to -1. */
@ -809,6 +831,7 @@ void unlinkClient(client *c) {
listDelNode(server.clients_pending_write,ln);
c->flags &= ~CLIENT_PENDING_WRITE;
}
#endif
/* When client was just unblocked because of a blocking operation,
* remove it from the list of unblocked clients. */
@ -821,6 +844,7 @@ void unlinkClient(client *c) {
}
void freeClient(client *c) {
#if __redis_unmodified_upstream // Disable client freeing
listNode *ln;
/* If a client is protected, yet we need to free it right now, make sure
@ -918,19 +942,22 @@ void freeClient(client *c) {
freeClientMultiState(c);
sdsfree(c->peerid);
zfree(c);
#endif
}
/* Schedule a client to free it at a safe time in the serverCron() function.
* This function is useful when we need to terminate a client but we are in
* a context where calling freeClient() is not possible, because the client
* should be valid for the continuation of the flow of the program. */
void freeClientAsync(client *c) {
#if __redis_unmodified_upstream // Disable client freeing
if (c->flags & CLIENT_CLOSE_ASAP || c->flags & CLIENT_LUA) return;
c->flags |= CLIENT_CLOSE_ASAP;
listAddNodeTail(server.clients_to_close,c);
#endif
}
void freeClientsInAsyncFreeQueue(void) {
#if __redis_unmodified_upstream // Disable client freeing
while (listLength(server.clients_to_close)) {
listNode *ln = listFirst(server.clients_to_close);
client *c = listNodeValue(ln);
@ -939,6 +966,7 @@ void freeClientsInAsyncFreeQueue(void) {
freeClient(c);
listDelNode(server.clients_to_close,ln);
}
#endif
}
/* Return a client by ID, or NULL if the client ID is not in the set
@ -950,6 +978,7 @@ client *lookupClientByID(uint64_t id) {
return (c == raxNotFound) ? NULL : c;
}
#if __redis_unmodified_upstream // Disable the net API of Redis
/* Write data in output buffers to client. Return C_OK if the client
* is still valid after the call, C_ERR if it was freed. */
int writeToClient(int fd, client *c, int handler_installed) {
@ -1082,6 +1111,7 @@ int handleClientsWithPendingWrites(void) {
* so that in the middle of receiving the query, and serving it
* to the client, we'll call beforeSleep() that will do the
* actual fsync of AOF to disk. AE_BARRIER ensures that. */
#if __redis_unmodified_upstream // Disable the replication API of Redis
if (server.aof_state == AOF_ON &&
server.aof_fsync == AOF_FSYNC_ALWAYS)
{
@ -1092,10 +1122,12 @@ int handleClientsWithPendingWrites(void) {
{
freeClientAsync(c);
}
#endif
}
}
return processed;
}
#endif
/* resetClient prepare the client to process the next command */
void resetClient(client *c) {
@ -1106,10 +1138,12 @@ void resetClient(client *c) {
c->multibulklen = 0;
c->bulklen = -1;
#if __redis_unmodified_upstream // Disable the cluster API of Redis
/* We clear the ASKING flag as well if we are not inside a MULTI, and
* if what we just executed is not the ASKING command itself. */
if (!(c->flags & CLIENT_MULTI) && prevcmd != askingCommand)
c->flags &= ~CLIENT_ASKING;
#endif
/* Remove the CLIENT_REPLY_SKIP flag if any so that the reply
* to the next command will be sent, but set the flag if the command
@ -1121,6 +1155,7 @@ void resetClient(client *c) {
}
}
#if __redis_unmodified_upstream // Disable the event engine and net API of Redis
/* This funciton is used when we want to re-enter the event loop but there
* is the risk that the client we are dealing with will be freed in some
* way. This happens for instance in:
@ -1145,9 +1180,12 @@ void unprotectClient(client *c) {
if (c->flags & CLIENT_PROTECTED) {
c->flags &= ~CLIENT_PROTECTED;
aeCreateFileEvent(server.el,c->fd,AE_READABLE,readQueryFromClient,c);
#if __redis_unmodified_upstream // Disable the cluster API of Redis
if (clientHasPendingReplies(c)) clientInstallWriteHandler(c);
#endif
}
}
#endif
/* Like processMultibulkBuffer(), but for the inline protocol instead of RESP,
* this function consumes the client query buffer and creates a command ready
@ -1189,11 +1227,13 @@ int processInlineBuffer(client *c) {
return C_ERR;
}
#if __redis_unmodified_upstream // Disable the replication API of Redis
/* Newline from slaves can be used to refresh the last ACK time.
* This is useful for a slave to ping back while loading a big
* RDB file. */
if (querylen == 0 && c->flags & CLIENT_SLAVE)
c->repl_ack_time = server.unixtime;
#endif
/* Move querybuffer position to the next query in the buffer. */
c->qb_pos += querylen+linefeed_chars;
@ -1402,6 +1442,7 @@ void processInputBuffer(client *c) {
/* Keep processing while there is something in the input buffer */
while(c->qb_pos < sdslen(c->querybuf)) {
#if __redis_unmodified_upstream // Disable the cluster API of Redis
/* Return if clients are paused. */
if (!(c->flags & CLIENT_SLAVE) && clientsArePaused()) break;
@ -1413,6 +1454,7 @@ void processInputBuffer(client *c) {
* stream (instead of replying -BUSY like we do with other clients) and
* later resume the processing. */
if (server.lua_timedout && c->flags & CLIENT_MASTER) break;
#endif
/* CLIENT_CLOSE_AFTER_REPLY closes the connection once the reply is
* written to the client. Make sure to not let the reply grow after
@ -1444,6 +1486,8 @@ void processInputBuffer(client *c) {
} else {
/* Only reset the client when the command was executed. */
if (processCommand(c) == C_OK) {
// TODO: check the interconnection between CLIENT_MULTI and reploff
#if __redis_unmodified_upstream // Disable the replication API of Redis
if (c->flags & CLIENT_MASTER && !(c->flags & CLIENT_MULTI)) {
/* Update the applied replication offset of our master. */
c->reploff = c->read_reploff - sdslen(c->querybuf) + c->qb_pos;
@ -1455,6 +1499,7 @@ void processInputBuffer(client *c) {
* The client will be reset in unblockClientFromModule(). */
if (!(c->flags & CLIENT_BLOCKED) || c->btype != BLOCKED_MODULE)
resetClient(c);
#endif
}
/* freeMemoryIfNeeded may flush slave output buffers. This may
* result into a slave, that may be the active client, to be
@ -1472,6 +1517,7 @@ void processInputBuffer(client *c) {
server.current_client = NULL;
}
#if __redis_unmodified_upstream // Disable the replication API of Redis
/* This is a wrapper for processInputBuffer that also cares about handling
* the replication forwarding to the sub-slaves, in case the client 'c'
* is flagged as master. Usually you want to call this instead of the
@ -1490,14 +1536,21 @@ void processInputBufferAndReplicate(client *c) {
}
}
}
#endif
#if __redis_unmodified_upstream // Disable the event engine of Redis
void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) {
client *c = (client*) privdata;
int nread, readlen;
size_t qblen;
UNUSED(el);
UNUSED(mask);
#else
void readQueryFromClient(client *c, int mask, const char *request, int req_length) {
int nread, readlen;
size_t qblen;
UNUSED(mask);
#endif
readlen = PROTO_IOBUF_LEN;
/* If this is a multi bulk request, and we are processing a bulk reply
* that is large enough, try to maximize the probability that the query
@ -1518,6 +1571,7 @@ void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) {
qblen = sdslen(c->querybuf);
if (c->querybuf_peak < qblen) c->querybuf_peak = qblen;
c->querybuf = sdsMakeRoomFor(c->querybuf, readlen);
#if __redis_unmodified_upstream // Disable the net API of Redis
nread = read(fd, c->querybuf+qblen, readlen);
if (nread == -1) {
if (errno == EAGAIN) {
@ -1538,11 +1592,23 @@ void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) {
c->pending_querybuf = sdscatlen(c->pending_querybuf,
c->querybuf+qblen,nread);
}
#else
nread = readlen < req_length ? readlen : req_length;
memcpy(c->querybuf+qblen, request, nread);
#endif
sdsIncrLen(c->querybuf,nread);
c->lastinteraction = server.unixtime;
#if __redis_unmodified_upstream // Disable the replication API of Redis
if (c->flags & CLIENT_MASTER) c->read_reploff += nread;
#endif
server.stat_net_input_bytes += nread;
#if __redis_unmodified_upstream // Add some additional logging
#else
serverLog(1, "readlen = %d, req_length = %d, nread = %d, server.client_max_querybuf_len = %zu, sdslen(c->querybuf) = %zu\n", readlen, req_length, nread, server.client_max_querybuf_len, sdslen(c->querybuf));
#endif
if (sdslen(c->querybuf) > server.client_max_querybuf_len) {
sds ci = catClientInfoString(sdsempty(),c), bytes = sdsempty();
@ -1554,6 +1620,7 @@ void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) {
return;
}
#if __redis_unmodified_upstream // Disable the replication API of Redis
/* Time to process the buffer. If the client is a master we need to
* compute the difference between the applied offset before and after
* processing the buffer, to understand how much of the replication stream
@ -1561,6 +1628,9 @@ void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) {
* corresponding part of the replication stream, will be propagated to
* the sub-slaves and to the replication backlog. */
processInputBufferAndReplicate(c);
#else
processInputBuffer(c);
#endif
}
void getClientsMaxBuffers(unsigned long *longest_output_list,
@ -1581,6 +1651,7 @@ void getClientsMaxBuffers(unsigned long *longest_output_list,
*biggest_input_buffer = bib;
}
#if __redis_unmodified_upstream // Disable the net API of Redis
/* A Redis "Peer ID" is a colon separated ip:port pair.
* For IPv4 it's in the form x.y.z.k:port, example: "127.0.0.1:1234".
* For IPv6 addresses we use [] around the IP part, like in "[::1]:1234".
@ -1602,6 +1673,7 @@ void genClientPeerId(client *client, char *peerid,
anetFormatPeer(client->fd,peerid,peerid_len);
}
}
#endif
/* This function returns the client peer id, by creating and caching it
* if client->peerid is NULL, otherwise returning the cached value.
@ -1611,7 +1683,15 @@ char *getClientPeerId(client *c) {
char peerid[NET_PEER_ID_LEN];
if (c->peerid == NULL) {
#if __redis_unmodified_upstream // Disable the net API of Redis
genClientPeerId(c,peerid,sizeof(peerid));
#else
peerid[0] = 'W';
peerid[1] = 'a';
peerid[2] = 's';
peerid[3] = 'm';
peerid[4] = '\x00';
#endif
c->peerid = sdsnew(peerid);
}
return c->peerid;
@ -1643,15 +1723,16 @@ sds catClientInfoString(sds s, client *client) {
if (p == flags) *p++ = 'N';
*p++ = '\0';
#if __redis_unmodified_upstream // Disable the event engine of Redis
emask = client->fd == -1 ? 0 : aeGetFileEvents(server.el,client->fd);
p = events;
if (emask & AE_READABLE) *p++ = 'r';
if (emask & AE_WRITABLE) *p++ = 'w';
#endif
*p = '\0';
return sdscatfmt(s,
"id=%U addr=%s fd=%i name=%s age=%I idle=%I flags=%s db=%i sub=%i psub=%i multi=%i qbuf=%U qbuf-free=%U obl=%U oll=%U omem=%U events=%s cmd=%s",
"id=%U fd=%i name=%s age=%I idle=%I flags=%s db=%i sub=%i psub=%i multi=%i qbuf=%U qbuf-free=%U obl=%U oll=%U omem=%U events=%s cmd=%s",
(unsigned long long) client->id,
getClientPeerId(client),
client->fd,
client->name ? (char*)client->name->ptr : "",
(long long)(server.unixtime - client->ctime),
@ -1686,6 +1767,7 @@ sds getAllClientsInfoString(int type) {
return o;
}
#if __redis_unmodified_upstream // Disable client command
void clientCommand(client *c) {
listNode *ln;
listIter li;
@ -1861,6 +1943,7 @@ NULL
} else {
addReply(c,shared.czero);
}
addReply(c,shared.czero);
} else if (!strcasecmp(c->argv[1]->ptr,"setname") && c->argc == 3) {
int j, len = sdslen(c->argv[2]->ptr);
char *p = c->argv[2]->ptr;
@ -1905,7 +1988,9 @@ NULL
addReplyErrorFormat(c, "Unknown subcommand or wrong number of arguments for '%s'. Try CLIENT HELP", (char*)c->argv[1]->ptr);
}
}
#endif
#if __redis_unmodified_upstream // Disable the securityWarning command
/* This callback is bound to POST and "Host:" command names. Those are not
* really commands, but are used in security attacks in order to talk to
* Redis instances via HTTP, with a technique called "cross protocol scripting"
@ -1925,6 +2010,7 @@ void securityWarningCommand(client *c) {
}
freeClientAsync(c);
}
#endif
/* Rewrite the command vector of the client. All the new objects ref count
* is incremented. The old command vector is freed, and the old objects
@ -2115,6 +2201,7 @@ void asyncCloseClientOnOutputBufferLimitReached(client *c) {
}
}
#if __redis_unmodified_upstream // Disable the event engine and net API of Redis
/* Helper function used by freeMemoryIfNeeded() in order to flush slaves
* output buffers without returning control to the event loop.
* This is also called by SHUTDOWN for a best-effort attempt to send
@ -2178,7 +2265,6 @@ int clientsArePaused(void) {
client *c;
server.clients_paused = 0;
/* Put all the clients in the unblocked clients queue in order to
* force the re-processing of the input buffer if any. */
listRewind(server.clients,&li);
@ -2218,3 +2304,4 @@ int processEventsWhileBlocked(void) {
}
return count;
}
#endif

View File

@ -95,6 +95,7 @@ sds keyspaceEventsFlagsToString(int flags) {
* 'key' is a Redis object representing the key name.
* 'dbid' is the database ID where the key lives. */
void notifyKeyspaceEvent(int type, char *event, robj *key, int dbid) {
#if __redis_unmodified_upstream // Disable the event engine of Redis
sds chan;
robj *chanobj, *eventobj;
int len = -1;
@ -135,4 +136,5 @@ void notifyKeyspaceEvent(int type, char *event, robj *key, int dbid) {
decrRefCount(chanobj);
}
decrRefCount(eventobj);
#endif
}

View File

@ -30,6 +30,13 @@
#include "server.h"
#include <math.h>
#if __redis_unmodified_upstream // Include some libs explicitly
#else
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#endif
#include <ctype.h>
#ifdef __CYGWIN__
@ -652,6 +659,7 @@ int getLongDoubleFromObject(robj *o, long double *target) {
if (sdsEncodedObject(o)) {
errno = 0;
value = strtold(o->ptr, &eptr);
if (sdslen(o->ptr) == 0 ||
isspace(((const char*)o->ptr)[0]) ||
(size_t)(eptr-(char*)o->ptr) != sdslen(o->ptr) ||
@ -978,12 +986,15 @@ struct redisMemOverhead *getMemoryOverheadData(void) {
mem_total += server.initial_memory_usage;
mem = 0;
#if __redis_unmodified_upstream // Disable the replication API of Redis
if (server.repl_backlog)
mem += zmalloc_size(server.repl_backlog);
#endif
mh->repl_backlog = mem;
mem_total += mem;
mem = 0;
#if __redis_unmodified_upstream // Disable the cluster API of Redis
if (listLength(server.slaves)) {
listIter li;
listNode *ln;
@ -996,6 +1007,7 @@ struct redisMemOverhead *getMemoryOverheadData(void) {
mem += sizeof(client);
}
}
#endif
mh->clients_slaves = mem;
mem_total+=mem;
@ -1018,22 +1030,26 @@ struct redisMemOverhead *getMemoryOverheadData(void) {
mem_total+=mem;
mem = 0;
#if __redis_unmodified_upstream // Disable the replication API of Redis
if (server.aof_state != AOF_OFF) {
mem += sdsalloc(server.aof_buf);
mem += aofRewriteBufferSize();
}
mh->aof_buffer = mem;
mem_total+=mem;
#endif
mem = server.lua_scripts_mem;
mem += dictSize(server.lua_scripts) * sizeof(dictEntry) +
dictSlots(server.lua_scripts) * sizeof(dictEntry*);
#if __redis_unmodified_upstream // Disable the replication API of Redis
mem += dictSize(server.repl_scriptcache_dict) * sizeof(dictEntry) +
dictSlots(server.repl_scriptcache_dict) * sizeof(dictEntry*);
if (listLength(server.repl_scriptcache_fifo) > 0) {
mem += listLength(server.repl_scriptcache_fifo) * (sizeof(listNode) +
sdsZmallocSize(listNodeValue(listFirst(server.repl_scriptcache_fifo))));
}
#endif
mh->lua_caches = mem;
mem_total+=mem;
@ -1132,9 +1148,15 @@ sds getMemoryDoctorReport(void) {
num_reports++;
}
#if __redis_unmodified_upstream // Disable the cluster API of Redis
/* Clients using more than 200k each average? */
long numslaves = listLength(server.slaves);
long numclients = listLength(server.clients)-numslaves;
#else
/* Clients using more than 200k each average? */
long numslaves = 0;
long numclients = listLength(server.clients)-numslaves;
#endif
if (mh->clients_normal / numclients > (1024*200)) {
big_client_buf = 1;
num_reports++;

View File

@ -316,10 +316,13 @@ void punsubscribeCommand(client *c) {
void publishCommand(client *c) {
int receivers = pubsubPublishMessage(c->argv[1],c->argv[2]);
#if __redis_unmodified_upstream // Disable the cluster API of Redis
if (server.cluster_enabled)
clusterPropagatePublish(c->argv[1],c->argv[2]);
else
forceCommandPropagation(c,PROPAGATE_REPL);
#endif
addReplyLongLong(c,receivers);
}

View File

@ -1817,6 +1817,7 @@ uint64_t raxSize(rax *rax) {
return rax->numele;
}
#if __redis_unmodified_upstream // Disable the radix tree debugging API of Redis
/* ----------------------------- Introspection ------------------------------ */
/* This function is mostly used for debugging and learning purposes.
@ -1941,3 +1942,4 @@ unsigned long raxTouch(raxNode *n) {
}
return sum;
}
#endif

View File

@ -38,12 +38,17 @@
#ifndef __REDIS_ASSERT_H__
#define __REDIS_ASSERT_H__
#if __redis_unmodified_upstream // Use the unreachable Wasm instruction instead of exit that can involve some syscalls
#include <unistd.h> /* for _exit() */
#define assert(_e) ((_e)?(void)0 : (_serverAssert(#_e,__FILE__,__LINE__),_exit(1)))
#define panic(...) _serverPanic(__FILE__,__LINE__,__VA_ARGS__),_exit(1)
#else
#define assert(_e) ((_e)?(void)0 : (_serverAssert(#_e,__FILE__,__LINE__),__builtin_unreachable()))
#define panic(...) _serverPanic(__FILE__,__LINE__,__VA_ARGS__),__builtin_unreachable()
#endif
void _serverAssert(char *estr, char *file, int line);
void _serverAssert(const char *estr, const char *file, int line);
void _serverPanic(const char *file, int line, const char *msg, ...);
#endif

View File

@ -2010,12 +2010,14 @@ void replicationHandleMasterDisconnection(void) {
}
void replicaofCommand(client *c) {
#if __redis_unmodified_upstream // Disable the cluster API of Redis
/* SLAVEOF is not allowed in cluster mode as replication is automatically
* configured using the current address of the master node. */
if (server.cluster_enabled) {
addReplyError(c,"REPLICAOF not allowed in cluster mode.");
return;
}
#endif
/* The special host/port combination "NO" "ONE" turns the instance
* into a master. Otherwise the new master address is set. */

View File

@ -38,6 +38,12 @@
#include <ctype.h>
#include <math.h>
#if __redis_unmodified_upstream // Include some libs explicitly
#else
#include <stdlib.h>
#include <string.h>
#endif
char *redisProtocolToLuaType_Int(lua_State *lua, char *reply);
char *redisProtocolToLuaType_Bulk(lua_State *lua, char *reply);
char *redisProtocolToLuaType_Status(lua_State *lua, char *reply);
@ -45,6 +51,7 @@ char *redisProtocolToLuaType_Error(lua_State *lua, char *reply);
char *redisProtocolToLuaType_MultiBulk(lua_State *lua, char *reply);
int redis_math_random (lua_State *L);
int redis_math_randomseed (lua_State *L);
#if __redis_unmodified_upstream // Disable the lua debugger API of Redis
void ldbInit(void);
void ldbDisable(client *c);
void ldbEnable(client *c);
@ -75,6 +82,7 @@ struct ldbState {
size_t maxlen; /* Max var dump / reply length. */
int maxlen_hint_sent; /* Did we already hint about "set maxlen"? */
} ldb;
#endif
/* ---------------------------------------------------------------------------
* Utility functions.
@ -208,11 +216,13 @@ char *redisProtocolToLuaType_MultiBulk(lua_State *lua, char *reply) {
void luaPushError(lua_State *lua, char *error) {
lua_Debug dbg;
#if __redis_unmodified_upstream // Disable the lua debugger API of Redis
/* If debugging is active and in step mode, log errors resulting from
* Redis commands. */
if (ldb.active && ldb.step) {
ldbLog(sdscatprintf(sdsempty(),"<error> %s",error));
}
#endif
lua_newtable(lua);
lua_pushstring(lua,"err");
@ -443,6 +453,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
c->argv = argv;
c->argc = argc;
#if __redis_unmodified_upstream // Disable the lua debugger API of Redis
/* Log the command if debugging is active. */
if (ldb.active && ldb.step) {
sds cmdlog = sdsnew("<redis>");
@ -458,6 +469,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
}
ldbLog(cmdlog);
}
#endif
/* Command lookup */
cmd = lookupCommand(argv[0]->ptr);
@ -479,6 +491,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
goto cleanup;
}
#if __redis_unmodified_upstream // Disable the cluster API of Redis
/* Write commands are forbidden against read-only slaves, or if a
* command marked as non-deterministic was already called in the context
* of this script. */
@ -488,7 +501,8 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
luaPushError(lua,
"Write commands not allowed after non deterministic commands. Call redis.replicate_commands() at the start of your script in order to switch to single commands replication mode.");
goto cleanup;
} else if (server.masterhost && server.repl_slave_ro &&
}
else if (server.masterhost && server.repl_slave_ro &&
!server.loading &&
!(server.lua_caller->flags & CLIENT_MASTER))
{
@ -507,13 +521,16 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
goto cleanup;
}
}
#endif
/* If we reached the memory limit configured via maxmemory, commands that
* could enlarge the memory usage are not allowed, but only if this is the
* first write in the context of this script, otherwise we can't stop
* in the middle. */
if (server.maxmemory && /* Maxmemory is actually enabled. */
#if __redis_unmodified_upstream // Disable the replication API of Redis
!server.loading && /* Don't care about mem if loading. */
#endif
!server.masterhost && /* Slave must execute the script. */
server.lua_write_dirty == 0 && /* Script had no side effects so far. */
(cmd->flags & CMD_DENYOOM))
@ -527,6 +544,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
if (cmd->flags & CMD_RANDOM) server.lua_random_dirty = 1;
if (cmd->flags & CMD_WRITE) server.lua_write_dirty = 1;
#if __redis_unmodified_upstream // Disable the cluster API of Redis
/* If this is a Redis Cluster node, we need to make sure Lua is not
* trying to access non-local keys, with the exception of commands
* received from our master or when loading the AOF back in memory. */
@ -545,6 +563,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
goto cleanup;
}
}
#endif
/* If we are using single commands replication, we need to wrap what
* we propagate into a MULTI/EXEC block, so that it will be atomic like
@ -593,9 +612,11 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
if (raise_error && reply[0] != '-') raise_error = 0;
redisProtocolToLuaType(lua,reply);
#if __redis_unmodified_upstream // Disable the lua debugger API of Redis
/* If the debugger is active, log the reply from Redis. */
if (ldb.active && ldb.step)
ldbLogRedisReply(reply);
#endif
/* Sort the output array if needed, assuming it is a non-null multi bulk
* reply as expected. */
@ -727,6 +748,7 @@ int luaRedisReplicateCommandsCommand(lua_State *lua) {
return 1;
}
#if __redis_unmodified_upstream // Disable the lua debugger API of Redis
/* redis.breakpoint()
*
* Allows to stop execution during a debuggign session from within
@ -783,6 +805,7 @@ int luaRedisSetReplCommand(lua_State *lua) {
server.lua_repl = flags;
return 0;
}
#endif
/* redis.log() */
int luaLogCommand(lua_State *lua) {
@ -840,7 +863,9 @@ void luaLoadLibraries(lua_State *lua) {
luaLoadLib(lua, LUA_TABLIBNAME, luaopen_table);
luaLoadLib(lua, LUA_STRLIBNAME, luaopen_string);
luaLoadLib(lua, LUA_MATHLIBNAME, luaopen_math);
#if __redis_unmodified_upstream // Disable the lua debugger API of Redis
luaLoadLib(lua, LUA_DBLIBNAME, luaopen_debug);
#endif
luaLoadLib(lua, "cjson", luaopen_cjson);
luaLoadLib(lua, "struct", luaopen_struct);
luaLoadLib(lua, "cmsgpack", luaopen_cmsgpack);
@ -855,10 +880,12 @@ void luaLoadLibraries(lua_State *lua) {
/* Remove a functions that we don't want to expose to the Redis scripting
* environment. */
void luaRemoveUnsupportedFunctions(lua_State *lua) {
#if __redis_unmodified_upstream // We use patched version of lua where these function has been already disabled
lua_pushnil(lua);
lua_setglobal(lua,"loadfile");
lua_pushnil(lua);
lua_setglobal(lua,"dofile");
#endif
}
/* This function installs metamethods in the global table _G that prevent
@ -917,7 +944,9 @@ void scriptingInit(int setup) {
server.lua_client = NULL;
server.lua_caller = NULL;
server.lua_timedout = 0;
#if __redis_unmodified_upstream // Disable the lua debugger API of Redis
ldbInit();
#endif
}
luaLoadLibraries(lua);
@ -972,6 +1001,7 @@ void scriptingInit(int setup) {
lua_pushstring(lua, "error_reply");
lua_pushcfunction(lua, luaRedisErrorReplyCommand);
lua_settable(lua, -3);
lua_pushstring(lua, "status_reply");
lua_pushcfunction(lua, luaRedisStatusReplyCommand);
lua_settable(lua, -3);
@ -981,10 +1011,12 @@ void scriptingInit(int setup) {
lua_pushcfunction(lua, luaRedisReplicateCommandsCommand);
lua_settable(lua, -3);
#if __redis_unmodified_upstream // Disable the replication API of Redis
/* redis.set_repl and associated flags. */
lua_pushstring(lua,"set_repl");
lua_pushcfunction(lua,luaRedisSetReplCommand);
lua_settable(lua,-3);
#endif
lua_pushstring(lua,"REPL_NONE");
lua_pushnumber(lua,PROPAGATE_NONE);
@ -1006,6 +1038,7 @@ void scriptingInit(int setup) {
lua_pushnumber(lua,PROPAGATE_AOF|PROPAGATE_REPL);
lua_settable(lua,-3);
#if __redis_unmodified_upstream // Disable the lua debugger API of Redis
/* redis.breakpoint */
lua_pushstring(lua,"breakpoint");
lua_pushcfunction(lua,luaRedisBreakpointCommand);
@ -1015,6 +1048,7 @@ void scriptingInit(int setup) {
lua_pushstring(lua,"debug");
lua_pushcfunction(lua,luaRedisDebugCommand);
lua_settable(lua,-3);
#endif
/* Finally set the table as 'redis' global var. */
lua_setglobal(lua,"redis");
@ -1074,10 +1108,12 @@ void scriptingInit(int setup) {
server.lua_client->flags |= CLIENT_LUA;
}
#if __redis_unmodified_upstream // Disable the lua debugger API of Redis
/* Lua beginners often don't use "local", this is likely to introduce
* subtle bugs in their code. To prevent problems we protect accesses
* to global variables. */
scriptingEnableGlobalsProtection(lua);
#endif
server.lua = lua;
}
@ -1314,6 +1350,7 @@ void evalGenericCommand(client *c, int evalsha) {
/* Try to lookup the Lua function */
lua_getglobal(lua, funcname);
if (lua_isnil(lua,-1)) {
lua_pop(lua,1); /* remove the nil from the stack */
/* Function not defined... let's define it if we have the
@ -1353,6 +1390,7 @@ void evalGenericCommand(client *c, int evalsha) {
server.lua_caller = c;
server.lua_time_start = mstime();
server.lua_kill = 0;
#if __redis_unmodified_upstream // Disable the lua debugger API of Redis
if (server.lua_time_limit > 0 && ldb.active == 0) {
lua_sethook(lua,luaMaskCountHook,LUA_MASKCOUNT,100000);
delhook = 1;
@ -1360,12 +1398,14 @@ void evalGenericCommand(client *c, int evalsha) {
lua_sethook(server.lua,luaLdbLineHook,LUA_MASKLINE|LUA_MASKCOUNT,100000);
delhook = 1;
}
#endif
/* At this point whether this script was never seen before or if it was
* already defined, we can call it. We have zero arguments and expect
* a single return value. */
err = lua_pcall(lua,0,1,-2);
#if __redis_unmodified_upstream // Disable the lua debugger and cluster API of Redis
/* Perform some cleanup that we need to do both on error and success. */
if (delhook) lua_sethook(lua,NULL,0,0); /* Disable hook */
if (server.lua_timedout) {
@ -1376,6 +1416,7 @@ void evalGenericCommand(client *c, int evalsha) {
if (server.masterhost && server.master)
queueClientForReprocessing(server.master);
}
#endif
server.lua_caller = NULL;
/* Call the Lua garbage collector from time to time to avoid a
@ -1406,6 +1447,7 @@ void evalGenericCommand(client *c, int evalsha) {
lua_pop(lua,1); /* Remove the error handler. */
}
#if __redis_unmodified_upstream // Disable the replication API of Redis
/* If we are using single commands replication, emit EXEC if there
* was at least a write. */
if (server.lua_replicate_commands) {
@ -1456,13 +1498,16 @@ void evalGenericCommand(client *c, int evalsha) {
forceCommandPropagation(c,PROPAGATE_REPL|PROPAGATE_AOF);
}
}
#endif
}
void evalCommand(client *c) {
if (!(c->flags & CLIENT_LUA_DEBUG))
evalGenericCommand(c,0);
#if __redis_unmodified_upstream // Disable the lua debugger API of Redis
else
evalGenericCommandWithDebugging(c,0);
#endif
}
void evalShaCommand(client *c) {
@ -1484,6 +1529,7 @@ void evalShaCommand(client *c) {
void scriptCommand(client *c) {
if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"help")) {
#if __redis_unmodified_upstream // Disable the script DEBUG, FLUSH, KILL API of Redis
const char *help[] = {
"DEBUG (yes|sync|no) -- Set the debug mode for subsequent scripts executed.",
"EXISTS <sha1> [<sha1> ...] -- Return information about the existence of the scripts in the script cache.",
@ -1492,13 +1538,23 @@ void scriptCommand(client *c) {
"LOAD <script> -- Load a script into the scripts cache, without executing it.",
NULL
};
#endif
const char *help[] = {
"EXISTS <sha1> [<sha1> ...] -- Return information about the existence of the scripts in the script cache.",
"LOAD <script> -- Load a script into the scripts cache, without executing it.",
NULL
};
addReplyHelp(c, help);
} else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"flush")) {
}
#if __redis_unmodified_upstream // Disable the script FLUSH API of Redis
else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"flush")) {
scriptingReset();
addReply(c,shared.ok);
replicationScriptCacheFlush();
server.dirty++; /* Propagating this command is a good idea. */
} else if (c->argc >= 2 && !strcasecmp(c->argv[1]->ptr,"exists")) {
}
#endif
else if (c->argc >= 2 && !strcasecmp(c->argv[1]->ptr,"exists")) {
int j;
addReplyMultiBulkLen(c, c->argc-2);
@ -1513,7 +1569,9 @@ NULL
if (sha == NULL) return; /* The error was sent by luaCreateFunction(). */
addReplyBulkCBuffer(c,sha,40);
forceCommandPropagation(c,PROPAGATE_REPL|PROPAGATE_AOF);
} else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"kill")) {
}
#if __redis_unmodified_upstream // Disable the script DEBUG, KILL API of Redis
else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"kill")) {
if (server.lua_caller == NULL) {
addReplySds(c,sdsnew("-NOTBUSY No scripts in execution right now.\r\n"));
} else if (server.lua_caller->flags & CLIENT_MASTER) {
@ -1543,11 +1601,14 @@ NULL
addReplyError(c,"Use SCRIPT DEBUG yes/sync/no");
return;
}
} else {
}
#endif
else {
addReplySubcommandSyntaxError(c);
}
}
#if __redis_unmodified_upstream // Disable the lua debugger API of Redis
/* ---------------------------------------------------------------------------
* LDB: Redis Lua debugging facilities
* ------------------------------------------------------------------------- */
@ -2447,4 +2508,4 @@ void luaLdbLineHook(lua_State *lua, lua_Debug *ar) {
server.lua_time_start = mstime();
}
}
#endif

13
src/sdk/allocator.c Normal file
View File

@ -0,0 +1,13 @@
#include "allocator.h"
#include <stdlib.h>
#define UNUSED(x) (void)(x)
void *allocate(size_t size) {
return malloc(size);
}
void deallocate(void *ptr, size_t size) {
UNUSED(size);
free(ptr);
}

27
src/sdk/allocator.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef C_SDK_ALLOCATOR_H
#define C_SDK_ALLOCATOR_H
#include <stddef.h> // for size_t
/**
* Allocates a memory region of given size.
*
* Used by Wasm VM for byte array passing. Should be exported from module.
*
* @param size a size of needed memory region.
* @return a pointer to allocated memory region.
*/
void *allocate(size_t size);
/**
* Frees a memory region.
*
* Used by Wasm VM for freeing previous memory allocated by `allocate` function.
* Should be exported from module.
*
* @param ptr the pointer to the previously allocated memory region.
* @param size the size of the previously allocated memory region.
*/
void deallocate(void *ptr, size_t size);
#endif //C_SDK_ALLOCATOR_H

15
src/sdk/logger.c Normal file
View File

@ -0,0 +1,15 @@
#include "logger.h"
#define __LOGGER_IMPORT(name) \
__attribute__((__import_module__("logger"), __import_name__(#name)))
void __write(char ch) __LOGGER_IMPORT(write);
void __flush() __LOGGER_IMPORT(flush);
void wasm_log(const char *str, int len) {
for(int byteId = 0; byteId < len; ++byteId) {
__write(str[byteId]);
}
__flush();
}

11
src/sdk/logger.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef C_SDK_LOGGER_H
#define C_SDK_LOGGER_H
/**
* Writes provided string to Wasm VM logger.
*
* @param log_message a message that should be logged.
*/
void wasm_log(const char *str, int len);
#endif //C_SDK_LOGGER_H

View File

@ -34,7 +34,11 @@
#define __SDS_H
#define SDS_MAX_PREALLOC (1024*1024)
#if NOT_WAWSM
const char *SDS_NOINIT;
#else
extern const char *SDS_NOINIT;
#endif
#include <sys/types.h>
#include <stdarg.h>

View File

@ -4514,4 +4514,3 @@ void sentinelTimer(void) {
* election because of split brain voting). */
server.hz = CONFIG_DEFAULT_HZ + rand() % CONFIG_DEFAULT_HZ;
}

File diff suppressed because it is too large Load Diff

View File

@ -35,19 +35,26 @@
#include "solarisfixes.h"
#include "rio.h"
#if __redis_unmodified_upstream // Disable syscalls from some included libs
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <time.h>
#endif
#include <limits.h>
#include <unistd.h>
#include <errno.h>
#if __redis_unmodified_upstream // Disable syscalls from some included libs
#include <inttypes.h>
#include <pthread.h>
#include <syslog.h>
#include <netinet/in.h>
#endif
#include <lua.h>
#if __redis_unmodified_upstream // Disable syscalls from signal.h
#include <signal.h>
#endif
typedef long long mstime_t; /* millisecond time type. */
@ -452,9 +459,15 @@ typedef long long mstime_t; /* millisecond time type. */
#define run_with_period(_ms_) if ((_ms_ <= 1000/server.hz) || !(server.cronloops%((_ms_)/(1000/server.hz))))
/* We can print the stacktrace, so our assert is defined this way: */
#if __redis_unmodified_upstream // Use the unreachable Wasm instruction instead of exit that can involve some syscalls
#define serverAssertWithInfo(_c,_o,_e) ((_e)?(void)0 : (_serverAssertWithInfo(_c,_o,#_e,__FILE__,__LINE__),_exit(1)))
#define serverAssert(_e) ((_e)?(void)0 : (_serverAssert(#_e,__FILE__,__LINE__),_exit(1)))
#define serverPanic(...) _serverPanic(__FILE__,__LINE__,__VA_ARGS__),_exit(1)
#else
#define serverAssertWithInfo(_c,_o,_e) ((_e)?(void)0 : (_serverAssertWithInfo(_c,_o,#_e,__FILE__,__LINE__),__builtin_unreachable()))
#define serverAssert(_e) ((_e)?(void)0 : (_serverAssert(#_e,__FILE__,__LINE__),__builtin_unreachable()))
#define serverPanic(...) _serverPanic(__FILE__,__LINE__,__VA_ARGS__),__builtin_unreachable()
#endif
/*-----------------------------------------------------------------------------
* Data types
@ -540,6 +553,7 @@ typedef struct moduleValue {
void *value;
} moduleValue;
#if __redis_unmodified_upstream // Disable the module API of Redis
/* This is a wrapper for the 'rio' streams used inside rdb.c in Redis, so that
* the user does not have to take the total count of the written bytes nor
* to care about error conditions. */
@ -552,6 +566,7 @@ typedef struct RedisModuleIO {
* 2 (current version with opcodes annotation). */
struct RedisModuleCtx *ctx; /* Optional context, see RM_GetContextFromIO()*/
} RedisModuleIO;
#endif
/* Macro to initialize an IO context. Note that the 'ver' field is populated
* inside rdb.c according to the version of the value to load. */
@ -736,6 +751,8 @@ typedef struct client {
time_t obuf_soft_limit_reached_time;
int flags; /* Client flags: CLIENT_* macros. */
int authenticated; /* When requirepass is non-NULL. */
#if __redis_unmodified_upstream // Disable the replication API of Redis
int replstate; /* Replication state if this is a slave. */
int repl_put_online_on_ack; /* Install slave write handler on ACK. */
int repldbfd; /* Replication DB file descriptor. */
@ -753,10 +770,13 @@ typedef struct client {
int slave_listening_port; /* As configured with: SLAVECONF listening-port */
char slave_ip[NET_IP_STR_LEN]; /* Optionally given by REPLCONF ip-address */
int slave_capa; /* Slave capabilities: SLAVE_CAPA_* bitwise OR. */
#endif
multiState mstate; /* MULTI/EXEC state */
int btype; /* Type of blocking op if CLIENT_BLOCKED. */
blockingState bpop; /* blocking state */
#if __redis_unmodified_upstream // Disable the replication API of Redis
long long woff; /* Last write global replication offset. */
#endif
list *watched_keys; /* Keys WATCHED for MULTI/EXEC CAS */
dict *pubsub_channels; /* channels a client is interested in (SUBSCRIBE) */
list *pubsub_patterns; /* patterns a client is interested in (SUBSCRIBE) */
@ -913,8 +933,9 @@ struct malloc_stats {
/*-----------------------------------------------------------------------------
* Global server state
*----------------------------------------------------------------------------*/
#if __redis_unmodified_upstream // Disable cluster API of redis
struct clusterState;
#endif
/* AIX defines hz to __hz, we don't use this define and in order to allow
* Redis build on AIX we need to undef it. */
@ -928,7 +949,9 @@ struct clusterState;
struct redisServer {
/* General */
#if __redis_unmodified_upstream // Disable pid file of Redis
pid_t pid; /* Main process pid. */
#endif
char *configfile; /* Absolute config file path, or NULL */
char *executable; /* Absolute executable file path. */
char **exec_argv; /* Executable argv vector (copy). */
@ -940,13 +963,17 @@ struct redisServer {
redisDb *db;
dict *commands; /* Command table */
dict *orig_commands; /* Command table before command renaming. */
#if __redis_unmodified_upstream // Disable the event engine API of Redis
aeEventLoop *el;
#endif
unsigned int lruclock; /* Clock for LRU eviction */
int shutdown_asap; /* SHUTDOWN needed ASAP */
int activerehashing; /* Incremental rehash in serverCron() */
int active_defrag_running; /* Active defragmentation running (holds current scan aggressiveness) */
char *requirepass; /* Pass for AUTH command, or NULL */
#if __redis_unmodified_upstream // Disable the pid file
char *pidfile; /* PID file path */
#endif
int arch_bits; /* 32 or 64 depending on sizeof(long) */
int cronloops; /* Number of times the cron function run */
char runid[CONFIG_RUN_ID_SIZE+1]; /* ID always different at every exec. */
@ -961,6 +988,7 @@ struct redisServer {
int module_blocked_pipe[2]; /* Pipe used to awake the event loop if a
client blocked on a module command needs
to be processed. */
#if __redis_unmodified_upstream // Disable the net API of Redis
/* Networking */
int port; /* TCP listening port */
int tcp_backlog; /* TCP listen() backlog */
@ -991,6 +1019,13 @@ struct redisServer {
off_t loading_loaded_bytes;
time_t loading_start_time;
off_t loading_process_events_interval_bytes;
#else
list *clients; /* List of active clients */
list *monitors; /* List of slaves and MONITORs */
client *current_client; /* Current client, only used on crash report */
rax *clients_index; /* Active clients dictionary by client ID. */
uint64_t next_client_id; /* Next client unique ID. Incremental. */
#endif
/* Fast pointers to often looked up command */
struct redisCommand *delCommand, *multiCommand, *lpushCommand,
*lpopCommand, *rpopCommand, *zpopminCommand,
@ -1054,6 +1089,8 @@ struct redisServer {
int supervised_mode; /* See SUPERVISED_* */
int daemonize; /* True if running as a daemon */
clientBufferLimitsConfig client_obuf_limits[CLIENT_TYPE_OBUF_COUNT];
#if __redis_unmodified_upstream // Disable the replication API of Redis
/* AOF persistence */
int aof_state; /* AOF_(ON|OFF|WAIT_REWRITE) */
int aof_fsync; /* Kind of fsync() policy */
@ -1119,11 +1156,16 @@ struct redisServer {
} child_info_data;
/* Propagation of commands in AOF / replication */
redisOpArray also_propagate; /* Additional command to propagate. */
#else
time_t lastsave; /* Unix time of last successful save */
long long dirty; /* Changes to DB from the last save */
#endif
/* Logging */
char *logfile; /* Path of log file */
int syslog_enabled; /* Is syslog enabled? */
char *syslog_ident; /* Syslog ident */
int syslog_facility; /* Syslog facility */
#if __redis_unmodified_upstream // Disable the replication API of Redis
/* Replication (master) */
char replid[CONFIG_RUN_ID_SIZE+1]; /* My current replication ID. */
char replid2[CONFIG_RUN_ID_SIZE+1]; /* replid inherited from master*/
@ -1184,6 +1226,9 @@ struct redisServer {
/* Synchronous replication. */
list *clients_waiting_acks; /* Clients waiting in WAIT command. */
int get_ack_from_slaves; /* If true we send REPLCONF GETACK. */
#else
char *masterhost; /* Hostname of master */
#endif
/* Limits */
unsigned int maxclients; /* Max number of simultaneous clients */
unsigned long long maxmemory; /* Max number of memory bytes to use */
@ -1225,6 +1270,7 @@ struct redisServer {
list *pubsub_patterns; /* A list of pubsub_patterns */
int notify_keyspace_events; /* Events to propagate via Pub/Sub. This is an
xor of NOTIFY_... flags. */
#if __redis_unmodified_upstream // Disable the cluster API of Redis
/* Cluster */
int cluster_enabled; /* Is cluster enabled? */
mstime_t cluster_node_timeout; /* Cluster node timeout. */
@ -1243,6 +1289,8 @@ struct redisServer {
to set in order to suppress certain
native Redis Cluster features. Check the
REDISMODULE_CLUSTER_FLAG_*. */
#endif
/* Scripting */
lua_State *lua; /* The Lua interpreter. We use just one for all clients */
client *lua_client; /* The "fake client" to query Redis from Lua */
@ -1262,6 +1310,7 @@ struct redisServer {
execution. */
int lua_kill; /* Kill the script if true. */
int lua_always_replicate_commands; /* Default replication type. */
/* Lazy free */
int lazyfree_lazy_eviction;
int lazyfree_lazy_expire;
@ -1278,11 +1327,13 @@ struct redisServer {
/* System hardware info */
size_t system_memory_size; /* Total memory in system as reported by OS */
#if __redis_unmodified_upstream // Disable mutexes usage
/* Mutexes used to protect atomic variables when atomic builtins are
* not available. */
pthread_mutex_t lruclock_mutex;
pthread_mutex_t next_client_id_mutex;
pthread_mutex_t unixtime_mutex;
#endif
};
typedef struct pubsubPattern {
@ -1402,7 +1453,9 @@ void moduleFreeContext(struct RedisModuleCtx *ctx);
void unblockClientFromModule(client *c);
void moduleHandleBlockedClients(void);
void moduleBlockedClientTimedOut(client *c);
#if __redis_unmodified_upstream // Disable the event engine API of Redis
void moduleBlockedClientPipeReadable(aeEventLoop *el, int fd, void *privdata, int mask);
#endif
size_t moduleCount(void);
void moduleAcquireGIL(void);
void moduleReleaseGIL(void);
@ -1425,15 +1478,21 @@ void closeTimedoutClients(void);
void freeClient(client *c);
void freeClientAsync(client *c);
void resetClient(client *c);
#if __redis_unmodified_upstream // Disable the event engine API of Redis
void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask);
#endif
void *addDeferredMultiBulkLength(client *c);
void setDeferredMultiBulkLength(client *c, void *node, long length);
void processInputBuffer(client *c);
void processInputBufferAndReplicate(client *c);
#if __redis_unmodified_upstream // Disable the event engine API of Redis
void acceptHandler(aeEventLoop *el, int fd, void *privdata, int mask);
void acceptTcpHandler(aeEventLoop *el, int fd, void *privdata, int mask);
void acceptUnixHandler(aeEventLoop *el, int fd, void *privdata, int mask);
void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask);
#else
void readQueryFromClient(client *c, int mask, const char *request, int req_length);
#endif
void addReplyString(client *c, const char *s, size_t len);
void addReplyBulk(client *c, robj *obj);
void addReplyBulkCString(client *c, const char *s);
@ -1569,6 +1628,7 @@ unsigned long long estimateObjectIdleTime(robj *o);
void trimStringObjectIfNeeded(robj *o);
#define sdsEncodedObject(objptr) (objptr->encoding == OBJ_ENCODING_RAW || objptr->encoding == OBJ_ENCODING_EMBSTR)
#if __redis_unmodified_upstream // Disable the replication API of Redis
/* Synchronous I/O with timeout */
ssize_t syncWrite(int fd, char *ptr, ssize_t size, long long timeout);
ssize_t syncRead(int fd, char *ptr, ssize_t size, long long timeout);
@ -1608,16 +1668,20 @@ void feedReplicationBacklog(void *ptr, size_t len);
void startLoading(FILE *fp);
void loadingProgress(off_t pos);
void stopLoading(void);
#endif
#define DISK_ERROR_TYPE_AOF 1 /* Don't accept writes: AOF errors. */
#define DISK_ERROR_TYPE_RDB 2 /* Don't accept writes: RDB errors. */
#define DISK_ERROR_TYPE_NONE 0 /* No problems, we can accept writes. */
int writeCommandsDeniedByDiskError(void);
#if __redis_unmodified_upstream // Disable the persistence API of Redis
/* RDB persistence */
#include "rdb.h"
int rdbSaveRio(rio *rdb, int *error, int flags, rdbSaveInfo *rsi);
#endif
#if __redis_unmodified_upstream // Disable the persistence API of Redis
/* AOF persistence */
void flushAppendOnlyFile(int force);
void feedAppendOnlyFile(struct redisCommand *cmd, int dictid, robj **argv, int argc);
@ -1636,6 +1700,7 @@ void openChildInfoPipe(void);
void closeChildInfoPipe(void);
void sendChildInfo(int process_type);
void receiveChildInfo(void);
#endif
/* Sorted sets data type */
@ -1883,16 +1948,20 @@ void sentinelTimer(void);
char *sentinelHandleConfiguration(char **argv, int argc);
void sentinelIsRunning(void);
#if __redis_unmodified_upstream // Disable the replication API of Redis
/* redis-check-rdb & aof */
int redis_check_rdb(char *rdbfilename, FILE *fp);
int redis_check_rdb_main(int argc, char **argv, FILE *fp);
int redis_check_aof_main(int argc, char **argv);
#endif
/* Scripting */
void scriptingInit(int setup);
#if __redis_unmodified_upstream // Disable the lua debugger
int ldbRemoveChild(pid_t pid);
void ldbKillForkedSessions(void);
int ldbPendingChildren(void);
#endif
sds luaCreateFunction(client *c, lua_State *lua, robj *body);
/* Blocked clients */
@ -1960,7 +2029,9 @@ void randomkeyCommand(client *c);
void keysCommand(client *c);
void scanCommand(client *c);
void dbsizeCommand(client *c);
#if __redis_unmodified_upstream // Disable replication API of Redis
void lastsaveCommand(client *c);
#endif
void saveCommand(client *c);
void bgsaveCommand(client *c);
void bgrewriteaofCommand(client *c);
@ -2003,7 +2074,9 @@ void lremCommand(client *c);
void rpoplpushCommand(client *c);
void infoCommand(client *c);
void mgetCommand(client *c);
#if __redis_unmodified_upstream // Disable the monitor command
void monitorCommand(client *c);
#endif
void expireCommand(client *c);
void expireatCommand(client *c);
void pexpireCommand(client *c);
@ -2084,7 +2157,9 @@ void readwriteCommand(client *c);
void dumpCommand(client *c);
void objectCommand(client *c);
void memoryCommand(client *c);
#if __redis_unmodified_upstream // Disable client command
void clientCommand(client *c);
#endif
void evalCommand(client *c);
void evalShaCommand(client *c);
void scriptCommand(client *c);
@ -2140,7 +2215,9 @@ void _serverAssert(const char *estr, const char *file, int line);
void _serverPanic(const char *file, int line, const char *msg, ...);
void bugReportStart(void);
void serverLogObjectDebugInfo(const robj *o);
#if __redis_unmodified_upstream // Disable sigsegv handler
void sigsegvHandler(int sig, siginfo_t *info, void *secret);
#endif
sds genRedisInfoString(char *section);
void enableWatchdog(int period);
void disableWatchdog(void);
@ -2150,9 +2227,20 @@ int memtest_preserving_test(unsigned long *m, size_t bytes, int passes);
void mixDigest(unsigned char *digest, void *ptr, size_t len);
void xorDigest(unsigned char *digest, void *ptr, size_t len);
#if __redis_unmodified_upstream // Disable redis debug macros
#define redisDebug(fmt, ...) \
printf("DEBUG %s:%d > " fmt "\n", __FILE__, __LINE__, __VA_ARGS__)
#define redisDebugMark() \
printf("-- MARK %s:%d --\n", __FILE__, __LINE__)
#endif
#if __redis_unmodified_upstream // Export some functions to use it our wrapper
#else
int serverCron();
void afterSleep();
void beforeSleep();
int initRedis(int argc, char **argv);
void freeClientArgv(client *c);
#endif
#endif

View File

@ -41,6 +41,10 @@
#include "server.h"
#include "slowlog.h"
#if __redis_unmodified_upstream // Include some libs explicitly
#else
#include <strings.h>
#endif
/* Create a new slowlog entry.
* Incrementing the ref count of all the objects retained is up to
@ -85,7 +89,11 @@ slowlogEntry *slowlogCreateEntry(client *c, robj **argv, int argc, long long dur
}
}
}
#if __redis_unmodified_upstream // Currently it is impossible to get the current time inside a Wasm module
se->time = time(NULL);
#else
se->time = ustime();
#endif
se->duration = duration;
se->id = server.slowlog_entry_id++;
se->peerid = sdsnew(getClientPeerId(c));

View File

@ -32,6 +32,12 @@
#include "server.h"
#include "pqsort.h" /* Partial qsort for SORT+LIMIT */
#include <math.h> /* isnan() */
#if __redis_unmodified_upstream // Include some libs explicitly
#else
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#endif
zskiplistNode* zslGetElementByRank(zskiplist *zsl, unsigned long rank);
@ -253,19 +259,23 @@ void sortCommand(client *c) {
} else {
/* If BY is specified with a real patter, we can't accept
* it in cluster mode. */
#if __redis_unmodified_upstream // Disable the cluster API of Redis
if (server.cluster_enabled) {
addReplyError(c,"BY option of SORT denied in Cluster mode.");
syntax_error++;
break;
}
#endif
}
j++;
} else if (!strcasecmp(c->argv[j]->ptr,"get") && leftargs >= 1) {
#if __redis_unmodified_upstream // Disable the cluster API of Redis
if (server.cluster_enabled) {
addReplyError(c,"GET option of SORT denied in Cluster mode.");
syntax_error++;
break;
}
#endif
listAddNodeTail(operations,createSortOperation(
SORT_OP_GET,c->argv[j+1]));
getop++;

View File

@ -33,6 +33,10 @@
#include "server.h"
#include <math.h>
#if __redis_unmodified_upstream // Include some libs explicitly
#else
#include <string.h>
#endif
/* This is the charset used to display the graphs, but multiple rows are used
* to increase the resolution. */

View File

@ -483,8 +483,10 @@ void hashTypeConvertZiplist(robj *o, int enc) {
value = hashTypeCurrentObjectNewSds(hi,OBJ_HASH_VALUE);
ret = dictAdd(dict, key, value);
if (ret != DICT_OK) {
#if __redis_unmodified_upstream // Disable log hex dump
serverLogHexDump(LL_WARNING,"ziplist with dup elements dump",
o->ptr,ziplistBlobLen(o->ptr));
#endif
serverPanic("Ziplist corruption detected");
}
}

View File

@ -28,6 +28,10 @@
*/
#include "server.h"
#if __redis_unmodified_upstream // Include some libs explicitly
#else
#include <strings.h>
#endif
/*-----------------------------------------------------------------------------
* List API
@ -596,12 +600,15 @@ void rpoplpushCommand(client *c) {
signalModifiedKey(c->db,touchedkey);
decrRefCount(touchedkey);
server.dirty++;
#if __redis_unmodified_upstream // Disable the blocking API of Redis
if (c->cmd->proc == brpoplpushCommand) {
rewriteClientCommandVector(c,3,shared.rpoplpush,c->argv[1],c->argv[2]);
}
#endif
}
}
#if __redis_unmodified_upstream // Disable the blocking API of Redis
/*-----------------------------------------------------------------------------
* Blocking POP operations
*----------------------------------------------------------------------------*/
@ -775,3 +782,4 @@ void brpoplpushCommand(client *c) {
}
}
}
#endif

View File

@ -28,6 +28,10 @@
*/
#include "server.h"
#if __redis_unmodified_upstream // Include some libs explicitly
#else
#include <stdlib.h>
#endif
/*-----------------------------------------------------------------------------
* Set Commands

View File

@ -31,6 +31,13 @@
#include "endianconv.h"
#include "stream.h"
#if __redis_unmodified_upstream // Include some libs explicitly
#else
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#endif
#define STREAM_BYTES_PER_LISTPACK 2048
/* Every stream item inside the listpack, has a flags field that is used to
@ -1251,10 +1258,12 @@ void xaddCommand(client *c) {
rewriteClientCommandArgument(c,i,idarg);
decrRefCount(idarg);
#if __redis_unmodified_upstream // Disable the cluster API of Redis
/* We need to signal to blocked clients that there is new data on this
* stream. */
if (server.blocked_clients_by_type[BLOCKED_STREAM])
signalKeyAsReady(c->db, c->argv[1]);
#endif
}
/* XRANGE/XREVRANGE actual implementation. */
@ -1343,11 +1352,14 @@ void xreadCommand(client *c) {
for (int i = 1; i < c->argc; i++) {
int moreargs = c->argc-i-1;
char *o = c->argv[i]->ptr;
#if __redis_unmodified_upstream // Disable the blocking API of Redis
if (!strcasecmp(o,"BLOCK") && moreargs) {
i++;
if (getTimeoutFromObjectOrReply(c,c->argv[i],&timeout,
UNIT_MILLISECONDS) != C_OK) return;
} else if (!strcasecmp(o,"COUNT") && moreargs) {
} else
#endif
if (!strcasecmp(o,"COUNT") && moreargs) {
i++;
if (getLongLongFromObjectOrReply(c,c->argv[i],&count,NULL) != C_OK)
return;
@ -1536,6 +1548,7 @@ void xreadCommand(client *c) {
goto cleanup;
}
#if __redis_unmodified_upstream // Disable the blocking API of Redis
/* Block if needed. */
if (timeout != -1) {
/* If we are inside a MULTI/EXEC and the list is empty the only thing
@ -1567,6 +1580,7 @@ void xreadCommand(client *c) {
}
goto cleanup;
}
#endif
/* No BLOCK option, nor any stream we can serve. Reply as with a
* timeout happened. */

View File

@ -29,6 +29,10 @@
#include "server.h"
#include <math.h> /* isnan(), isinf() */
#if __redis_unmodified_upstream // Include some libs explicitly
#else
#include <string.h>
#endif
/*-----------------------------------------------------------------------------
* String Commands
@ -83,6 +87,7 @@ void setGenericCommand(client *c, int flags, robj *key, robj *val, robj *expire,
addReply(c, abort_reply ? abort_reply : shared.nullbulk);
return;
}
setKey(c->db,key,val);
server.dirty++;
if (expire) setExpire(c,c->db,key,mstime()+milliseconds);

View File

@ -58,6 +58,11 @@
#include "server.h"
#include <math.h>
#if __redis_unmodified_upstream // Include some libs explicitly
#else
#include <string.h>
#include <stdlib.h>
#endif
/*-----------------------------------------------------------------------------
* Skiplist implementation of the low level API
@ -3256,6 +3261,7 @@ void zpopmaxCommand(client *c) {
c->argc == 3 ? c->argv[2] : NULL);
}
#if __redis_unmodified_upstream // Disable the blocking API of Redis
/* BZPOPMIN / BZPOPMAX actual implementation. */
void blockingGenericZpopCommand(client *c, int where) {
robj *o;
@ -3305,3 +3311,4 @@ void bzpopminCommand(client *c) {
void bzpopmaxCommand(client *c) {
blockingGenericZpopCommand(c,ZSET_MAX);
}
#endif

View File

@ -34,13 +34,16 @@
#include <ctype.h>
#include <limits.h>
#include <math.h>
#if __redis_unmodified_upstream // Disable syscalls from some included libs
#include <unistd.h>
#include <sys/time.h>
#endif
#include <float.h>
#include <stdint.h>
#include <errno.h>
#if __redis_unmodified_upstream // Disable syscalls from some included libs
#include <time.h>
#endif
#include "util.h"
#include "sha1.h"
@ -549,7 +552,7 @@ int ld2string(char *buf, size_t len, long double value, int humanfriendly) {
if (*p == '.') l--;
}
} else {
l = snprintf(buf,len,"%.17Lg", value);
l = snprintf(buf,len,"%.17Lf", value);
if (l+1 > len) return 0; /* No room. */
}
buf[l] = '\0';
@ -567,6 +570,7 @@ void getRandomBytes(unsigned char *p, size_t len) {
static unsigned char seed[20]; /* The SHA1 seed, from /dev/urandom. */
static uint64_t counter = 0; /* The counter we hash with the seed. */
#if __redis_unmodified_upstream // Disable random initialization
if (!seed_initialized) {
/* Initialize a seed and use SHA1 in counter mode, where we hash
* the same seed with a progressive counter. For the goals of this
@ -587,6 +591,13 @@ void getRandomBytes(unsigned char *p, size_t len) {
}
if (fp) fclose(fp);
}
#else
if (!seed_initialized) {
for(int i = 0; i < 20; ++i) {
seed[i] = rand() & 0xFF;
}
}
#endif
while(len) {
unsigned char digest[20];
@ -617,6 +628,7 @@ void getRandomHexChars(char *p, size_t len) {
for (j = 0; j < len; j++) p[j] = charset[p[j] & 0x0F];
}
#if __redis_unmodified_upstream // Disable file API
/* Given the filename, return the absolute path as an SDS string, or NULL
* if it fails for some reason. Note that "filename" may be an absolute path
* already, this will be detected and handled correctly.
@ -668,12 +680,13 @@ sds getAbsolutePath(char *filename) {
sdsfree(relpath);
return abspath;
}
#endif
/*
* Gets the proper timezone in a more portable fashion
* i.e timezone variables are linux specific.
*/
#if __redis_unmodified_upstream // Currently it is impossible to get the current time inside a Wasm module
unsigned long getTimeZone(void) {
#ifdef __linux__
return timezone;
@ -686,6 +699,7 @@ unsigned long getTimeZone(void) {
return tz.tz_minuteswest * 60UL;
#endif
}
#endif
/* Return true if the specified path is just a file basename without any
* relative or absolute path. This function just checks that no / or \

37
src/wasm_float.h Normal file
View File

@ -0,0 +1,37 @@
#ifndef REDIS_WASM_FLOAT_H
#define REDIS_WASM_FLOAT_H
static __inline unsigned __FLOAT_BITS_(float __f)
{
union {float __f; unsigned __i;} __u;
__u.__f = __f;
return __u.__i;
}
static __inline unsigned long long __DOUBLE_BITS_(double __f)
{
union {double __f; unsigned long long __i;} __u;
__u.__f = __f;
return __u.__i;
}
#undef fpclassify
#define fpclassify(x) ( \
sizeof(x) == sizeof(float) ? __fpclassifyf(x) : __fpclassify(x))
#undef isinf
#define isinf(x) ( \
sizeof(x) == sizeof(float) ? (__FLOAT_BITS_(x) & 0x7fffffff) == 0x7f800000 : (__DOUBLE_BITS_(x) & -1ULL>>1) == 0x7ffULL<<52)
#undef isnan
#define isnan(x) ( \
sizeof(x) == sizeof(float) ? (__FLOAT_BITS_(x) & 0x7fffffff) > 0x7f800000 : (__DOUBLE_BITS_(x) & -1ULL>>1) > 0x7ffULL<<52)
#undef isnormal
#define isnormal(x) ( \
sizeof(x) == sizeof(float) ? ((__FLOAT_BITS_(x)+0x00800000) & 0x7fffffff) >= 0x01000000 : ((__DOUBLE_BITS_(x)+(1ULL<<52)) & -1ULL>>1) >= 1ULL<<53)
#undef isfinite
#define isfinite(x) ( \
sizeof(x) == sizeof(float) ? (__FLOAT_BITS_(x) & 0x7fffffff) < 0x7f800000 : (__DOUBLE_BITS_(x) & -1ULL>>1) < 0x7ffULL<<52)
#endif //REDIS_WASM_FLOAT_H

123
src/wrapper.c Normal file
View File

@ -0,0 +1,123 @@
#include <stdlib.h>
#include "server.h"
#include "atomicvar.h"
#include <stdlib.h>
#include <string.h>
client *g_client;
// TODO: add handling of the initialization process errors
void init() {
initRedis(0, NULL);
// create a main client
g_client = createClient(-1);
}
int g_isInited = 0;
void* allocate(size_t size) {
// allocate one more byte for adding the \n symbol that indicated the end of request
return zmalloc(size + 1);
}
void deallocate(void *ptr, int size) {
zfree(ptr);
}
// Cleans client output buffers to - client is blocked and
// doesn't receive requests until output buffer isn't empty.
void clean_client_buffer(client *c) {
freeClientArgv(c);
zfree(c->argv);
freeClientMultiState(c);
sdsfree(c->peerid);
c->reply_bytes = 0;
c->bufpos = 0;
c->argc = 0;
c->argv = NULL;
c->peerid = NULL;
// clear the query buffer state
sdsclear(c->querybuf);
c->qb_pos = 0;
// clear the client state
c->flags = 0;
// set reqtype to unknown to force Redis determine it on every request
c->reqtype = 0;
}
char *write_response(client *c, size_t *response_size) {
char *response = allocate(c->bufpos + c->reply_bytes + 4);
*response_size = 0;
memcpy(response + 4, c->buf, c->bufpos);
*response_size += c->bufpos;
while(listLength(c->reply)) {
clientReplyBlock *o = listNodeValue(listFirst(c->reply));
size_t objlen = o->used;
if (objlen == 0) {
listDelNode(c->reply, listFirst(c->reply));
continue;
}
memcpy(response + 4 + *response_size, o->buf, objlen);
c->reply_bytes -= o->size;
*response_size += objlen;
listDelNode(c->reply, listFirst(c->reply));
}
for(int i = 0; i < 4; ++i) {
response[i] = (*response_size >> 8*i) & 0xFF;
}
return response;
}
const char *invoke(char *request, int request_size) {
serverLog(LL_DEBUG, "invoke started\n");
if(g_isInited == 0) {
init();
serverLog(LL_DEBUG, "\nserver has been inited\n");
g_isInited = 1;
}
afterSleep();
serverLog(LL_DEBUG, "afterSleep\n");
if(request_size > 0 && request[request_size - 1] != '\n') {
// WasmVM always uses allocate function to inject requests to Wasm memory. And it always allocates one more byte
// especially for '\n' symbol
request[request_size] = '\n';
readQueryFromClient(g_client, 0, request, request_size + 1);
} else {
readQueryFromClient(g_client, 0, request, request_size);
}
deallocate(request, 0);
serverLog(LL_DEBUG, "readQueryFromClient\n");
const size_t reply_bytes_before = g_client->reply_bytes;
size_t response_size = 0;
const char *response = write_response(g_client, &response_size);
serverLog(LL_DEBUG, "write_response, bufpos = %d, reply_bytes before = %d, reply_bytes after = %d, response_size = %d\n",
g_client->bufpos,
reply_bytes_before,
g_client->reply_bytes,
response_size
);
clean_client_buffer(g_client);
serverCron();
serverLog(LL_DEBUG, "serverCron\n");
beforeSleep();
serverLog(LL_DEBUG, "beforeSleep\n");
return response;
}

View File

@ -1188,6 +1188,7 @@ size_t ziplistBlobLen(unsigned char *zl) {
}
void ziplistRepr(unsigned char *zl) {
#if __redis_unmodified_upstream // Disable the debug printing of ziplist
unsigned char *p;
int index = 0;
zlentry entry;
@ -1243,6 +1244,7 @@ void ziplistRepr(unsigned char *zl) {
index++;
}
printf("{end}\n\n");
#endif
}
#ifdef REDIS_TEST

View File

@ -41,7 +41,9 @@ void zlibc_free(void *ptr) {
}
#include <string.h>
#if __redis_unmodified_upstream // Disable syscalls from some libs
#include <pthread.h>
#endif
#include "config.h"
#include "zmalloc.h"
#include "atomicvar.h"
@ -84,13 +86,17 @@ void zlibc_free(void *ptr) {
} while(0)
static size_t used_memory = 0;
#if __redis_unmodified_upstream // Disable mutex usage
pthread_mutex_t used_memory_mutex = PTHREAD_MUTEX_INITIALIZER;
#endif
static void zmalloc_default_oom(size_t size) {
#if __redis_unmodified_upstream // Disable the debug printing of oom
fprintf(stderr, "zmalloc: Out of memory trying to allocate %zu bytes\n",
size);
fflush(stderr);
abort();
#endif
}
static void (*zmalloc_oom_handler)(size_t) = zmalloc_default_oom;