diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d6bc5d0dd29a3a643caa684bfe6b7dac805bd96..6ce6f1f52c0b1498d93361351ae9605b1e8b5fa7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 2.6) -project(tarantool) +project(tarantool C CXX) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) set(CMAKE_INCLUDE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_INCLUDE_PATH}) @@ -13,7 +13,6 @@ include(CheckCSourceRuns) include(CheckCXXSourceRuns) include(TestBigEndian) include(CheckFunctionExists) -include(CheckBuiltInFunctionExists) find_program(ECHO echo) find_program(XSLTPROC xsltproc) @@ -260,33 +259,6 @@ add_custom_target(build_bundled_libs) # include(luajit) -# -# LibOBJC -# -set (ENABLE_BUNDLED_LIBOBJC_DEFAULT ON) -if (TARGET_OS_DARWIN) - set (ENABLE_BUNDLED_LIBOBJC_DEFAULT OFF) -endif() -option(ENABLE_BUNDLED_LIBOBJC "Enable building of the bundled libobjc" ${ENABLE_BUNDLED_LIBOBJC_DEFAULT}) - -if (ENABLE_BUNDLED_LIBOBJC) - include(BuildLibOBJC) - libobjc_build() - add_dependencies(build_bundled_libs objc) - set(HAVE_LIBOBJC_BUNDLED ON) -else() - if (CMAKE_COMPILER_IS_GNUCC) - # Use compiler's objc library - add_compile_flags("OBJC;OBJCXX" "-objc") - set(LIBOBJC_LIBRARIES objc) - message(STATUS "Use gcc Objective-C runtime") - else() - set(LIBOBJC_FIND_REQUIRED ON) - find_package(LibOBJC) - endif() -endif() - - # # LibEV # @@ -413,8 +385,6 @@ message (STATUS "C_COMPILER: ${TARANTOOL_C_COMPILER}") message (STATUS "CXX_COMPILER: ${TARANTOOL_CXX_COMPILER}") message (STATUS "C_FLAGS:${TARANTOOL_C_FLAGS}") message (STATUS "CXX_FLAGS:${TARANTOOL_CXX_FLAGS}") -message (STATUS "OBJC_FLAGS:${TARANTOOL_OBJC_FLAGS}") -message (STATUS "OBJCXX_FLAGS:${TARANTOOL_OBJCXX_FLAGS}") message (STATUS "PREFIX: ${CMAKE_INSTALL_PREFIX}") message (STATUS "MODULES: ${TARANTOOL_MODULES}") message (STATUS "ENABLE_STATIC: ${ENABLE_STATIC}") diff --git a/cfg/warning.c b/cfg/warning.c index c3887e92ed848d8942b8914a77a70d9fab3bb063..8fbc242d70874ba91ca32bcad5808c957576001d 100644 --- a/cfg/warning.c +++ b/cfg/warning.c @@ -12,7 +12,7 @@ struct tbuf *cfg_out = NULL; */ void -out_warning(ConfettyError v, char *format, ...) +out_warning(ConfettyError v, const char *format, ...) { va_list ap; diff --git a/cfg/warning.h b/cfg/warning.h index 58792abe3ae53dc9bbfc967f4b0d7a6eccd162c8..646688b498fb6635a2e34616cfd463b6157531e9 100644 --- a/cfg/warning.h +++ b/cfg/warning.h @@ -5,6 +5,6 @@ extern struct tbuf *cfg_out; -void out_warning(ConfettyError r, char *format, ...); +void out_warning(ConfettyError r, const char *format, ...); #endif diff --git a/client/tarantool_checksum/tc_space.c b/client/tarantool_checksum/tc_space.c index f7697f69dceff5c2f9ad88723f341a39fb59fbd5..4d76a771ffe4829ac1faa57a7e32912d76cf878f 100644 --- a/client/tarantool_checksum/tc_space.c +++ b/client/tarantool_checksum/tc_space.c @@ -128,7 +128,7 @@ tc_space_key_init(struct tc_space *s, tarantool_cfg_space *cs) /* calculate primary key part count */ while (primary->key_field[s->pk.count]) { - typeof(primary->key_field[s->pk.count]) ck = primary->key_field[s->pk.count]; + tarantool_cfg_space_index_key_field *ck = primary->key_field[s->pk.count]; if (ck->fieldno == -1) break; s->pk.count++; @@ -147,7 +147,7 @@ tc_space_key_init(struct tc_space *s, tarantool_cfg_space *cs) int kn = 0; while (primary->key_field[kn]) { struct tc_space_key_field *k = &s->pk.fields[kn]; - typeof(primary->key_field[s->pk.count]) ck = primary->key_field[kn]; + tarantool_cfg_space_index_key_field *ck = primary->key_field[kn]; if (ck->fieldno == -1) break; k->n = ck->fieldno; diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake index a21b7f0512e06c8eb61f96db5e77d67fc8f53b9f..535cd3a8c12c69b56bffd605a878a3e41f27274d 100644 --- a/cmake/compiler.cmake +++ b/cmake/compiler.cmake @@ -1,9 +1,3 @@ -# -# Check if ObjectiveC and ObjectiveC++ compilers work -# -include(CMakeTestOBJCCompiler) -#include(CMakeTestOBJCXXCompiler) - # # Check if the same compile family is used for both C and CXX # @@ -22,20 +16,24 @@ if (CMAKE_C_COMPILER_ID STREQUAL Clang) set(CMAKE_COMPILER_IS_GNUCXX OFF) endif() -# Check GCC version: -# GCC older than 4.6 is not supported. -if (CMAKE_COMPILER_IS_GNUCC) +# TODO: clang version is not checked +if(CMAKE_COMPILER_IS_GNUCC) + # gcc and g++ >= 4.5 are supported execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE CC_VERSION) - if (CC_VERSION VERSION_GREATER 4.4.5 OR CC_VERSION VERSION_EQUAL 4.4.5) - message(STATUS - "${CMAKE_C_COMPILER} version >= 4.4.5 -- ${CC_VERSION}") - else() + if (CC_VERSION VERSION_LESS 4.5) message (FATAL_ERROR - "${CMAKE_C_COMPILER} version should be >= 4.4.5 -- ${CC_VERSION}") + "${CMAKE_C_COMPILER} version should be >= 4.5 -- ${CC_VERSION}") + endif() + execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion + OUTPUT_VARIABLE CXX_VERSION) + if (CXX_VERSION VERSION_LESS 4.5) + message (FATAL_ERROR + "${CMAKE_CXX_COMPILER} version should be >= 4.5 -- ${CXX_VERSION}") endif() endif() + # # Perform build type specific configuration. # @@ -121,8 +119,18 @@ macro(enable_tnt_compile_flags) # Additionally, compile it with more strict flags than the rest # of the code. - add_compile_flags("C;OBJC" "-std=gnu99") - add_compile_flags("CXX;OBJCXX" "-std=gnu++11 -fno-rtti") + # Set standard + if (CMAKE_COMPILER_IS_CLANG OR CC_VERSION VERSION_GREATER 4.7 OR + CC_VERSION VERSION_EQUAL 4.7) + add_compile_flags("C" "-std=c11") + add_compile_flags("CXX" "-std=c++11") + else() + add_compile_flags("C" "-std=gnu99") + add_compile_flags("CXX" "-std=c++0x") + endif() + + # Disable Run-time type information + add_compile_flags("CXX" "-fno-rtti") add_compile_flags("C;CXX" "-Wall" @@ -131,11 +139,22 @@ macro(enable_tnt_compile_flags) "-Wno-strict-aliasing" ) + if (CMAKE_COMPILER_IS_GNUCXX) + # G++ bug. http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31488 + add_compile_flags("CXX" + "-Wno-invalid-offsetof" + ) + endif() + + add_definitions("-D__STDC_FORMAT_MACROS=1") + add_definitions("-D__STDC_LIMIT_MACROS=1") + add_definitions("-D__STDC_CONSTANT_MACROS=1") + # Only add -Werror if it's a debug build, done by developers using GCC. # Community builds should not cause extra trouble. - if (${CMAKE_BUILD_TYPE} STREQUAL "Debug" AND CMAKE_COMPILER_IS_GNUCC) - add_compile_flags("C;CXX" "-Werror") - endif() + if (${CMAKE_BUILD_TYPE} STREQUAL "Debug" AND CMAKE_COMPILER_IS_GNUCC) + add_compile_flags("C;CXX" "-Werror") + endif() endmacro(enable_tnt_compile_flags) # @@ -149,3 +168,38 @@ check_c_compiler_flag("-Wno-unused-value" CC_HAS_WNO_UNUSED_VALUE) check_c_compiler_flag("-fno-strict-aliasing" CC_HAS_FNO_STRICT_ALIASING) check_c_compiler_flag("-Wno-comment" CC_HAS_WNO_COMMENT) check_c_compiler_flag("-Wno-parentheses" CC_HAS_WNO_PARENTHESES) + +if (CMAKE_COMPILER_IS_CLANG OR CMAKE_COMPILER_IS_GNUCC) + set(HAVE_BUILTIN_CTZ 1) + set(HAVE_BUILTIN_CTZLL 1) + set(HAVE_BUILTIN_CLZ 1) + set(HAVE_BUILTIN_CLZLL 1) + set(HAVE_BUILTIN_POPCOUNT 1) + set(HAVE_BUILTIN_POPCOUNTLL 1) + set(HAVE_BUILTIN_BSWAP32 1) + set(HAVE_BUILTIN_BSWAP64 1) +else() + set(HAVE_BUILTIN_CTZ 0) + set(HAVE_BUILTIN_CTZLL 0) + set(HAVE_BUILTIN_CLZ 0) + set(HAVE_BUILTIN_CLZLL 0) + set(HAVE_BUILTIN_POPCOUNT 0) + set(HAVE_BUILTIN_POPCOUNTLL 0) + set(HAVE_BUILTIN_BSWAP32 0) + set(HAVE_BUILTIN_BSWAP64 0) +endif() + +if (NOT HAVE_BUILTIN_CTZ OR NOT HAVE_BUILTIN_CTZLL) + # Check if -D_GNU_SOURCE has been defined and add this flag to + # CMAKE_REQUIRED_DEFINITIONS in order to get check_prototype_definition work + get_property(var DIRECTORY PROPERTY COMPILE_DEFINITIONS) + list(FIND var "_GNU_SOURCE" var) + if (NOT var EQUAL -1) + set(CMAKE_REQUIRED_FLAGS "-Wno-error") + set(CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE") + check_c_source_compiles("#include <string.h>\n#include <strings.h>\nint main(void) { return ffsl(0L); }" + HAVE_FFSL) + check_c_source_compiles("#include <string.h>\n#include <strings.h>\nint main(void) { return ffsll(0UL); }" + HAVE_FFSLL) + endif() +endif() diff --git a/include/assoc.h b/include/assoc.h index e5e5851fee8681ab79fdb9405108529b35602c32..fc5bb4026a3e245ef751b291766ee836a4075d20 100644 --- a/include/assoc.h +++ b/include/assoc.h @@ -39,7 +39,7 @@ */ #define mh_name _i32ptr struct mh_i32ptr_node_t { - i32 key; + u32 key; void *val; }; @@ -55,7 +55,7 @@ struct mh_i32ptr_node_t { */ #define mh_name _i64ptr struct mh_i64ptr_node_t { - i64 key; + u64 key; void *val; }; diff --git a/include/box/box.h b/include/box/box.h index f2e7d8bd993029842fdb6bc731331fa2a16be32c..08fa5ca882545f3081d6220e29b5c15302db5185 100644 --- a/include/box/box.h +++ b/include/box/box.h @@ -29,6 +29,11 @@ * SUCH DAMAGE. */ #include <util.h> + +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + /* * Box - data storage (spaces, indexes) and query * processor (INSERT, UPDATE, DELETE, SELECT, Lua) @@ -96,4 +101,8 @@ enum { BOX_FIELD_MAX = UINT32_MAX }; +#if defined(__cplusplus) +} +#endif /* defined(__cplusplus) */ + #endif /* INCLUDES_TARANTOOL_BOX_H */ diff --git a/include/crc32.h b/include/crc32.h index 1e5d0aa65e64f472d65e25d227e5e699a02e59c1..fae404eb72762cf318c59b9c4e470b7b02d8d534 100644 --- a/include/crc32.h +++ b/include/crc32.h @@ -31,6 +31,10 @@ #include <sys/types.h> #include <util.h> +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + typedef u_int32_t (*crc32_func)(u_int32_t crc, const unsigned char *buf, unsigned int len); /* @@ -41,4 +45,8 @@ extern crc32_func crc32_calc; void crc32_init(); +#if defined(__cplusplus) +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + #endif /* TARANTOOL_CRC32_H_INCLUDED */ diff --git a/include/errinj.h b/include/errinj.h index c9e13c3ee758d659bc2144397ba4438e28f228cb..28be14dc7bd94fbbb9978a847ac7d65d42bd0bca 100644 --- a/include/errinj.h +++ b/include/errinj.h @@ -32,7 +32,7 @@ #include "util.h" struct errinj { - char *name; + const char *name; bool state; }; @@ -67,7 +67,7 @@ void errinj_info(struct tbuf *out); #endif #define ERROR_INJECT_EXCEPTION(ID) \ - ERROR_INJECT(ID, tnt_raise(ErrorInjection, :#ID)) + ERROR_INJECT(ID, tnt_raise(ErrorInjection, #ID)) #define ERROR_INJECT_RETURN(ID) ERROR_INJECT(ID, return -1) diff --git a/include/exception.h b/include/exception.h index 7f23523e543b21ef8955f4ccf7018b6d8e40616a..3829d16cb5e64c03b081a61d970904861ea8c346 100644 --- a/include/exception.h +++ b/include/exception.h @@ -28,95 +28,104 @@ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#import "object.h" +#include "object.h" #include <stdarg.h> #include "errcode.h" #include "say.h" -/** The base class for all exceptions. - * - * Note: implements garbage collection (see +alloc - * implementation). - */ -@interface tnt_Exception: tnt_Object { - @public - const char *file; - unsigned line; -} -+ (id) alloc; -- (void) log; -- (const char *) errmsg; -@end - - -/** Internal error resulting from a failed system call. - */ -@interface SystemError: tnt_Exception { - @public - /* errno code */ - int errnum; - /* error description */ - char errmsg[TNT_ERRMSG_MAX]; -} - -- (id) init: (const char *)msg, ...; -- (id) init: (int)errnum_arg :(const char *)format :(va_list)ap; -- (void) log; -- (const char *) errmsg; -@end - - -/** Errors that should make it to the client. - */ -@interface ClientError: tnt_Exception { - @public - uint32_t errcode; - char errmsg[TNT_ERRMSG_MAX]; -} +class Exception: public Object { +public: + const char * + errmsg() const + { + return m_errmsg; + } -- (id) init: (uint32_t)errcode_, ...; -- (id) init: (uint32_t)errcode_ :(const char *)msg; -- (id) init: (uint32_t)errcode_ args :(va_list)ap; -- (void) log; -- (const char *) errmsg; -@end + virtual void log() const = 0; +protected: + Exception(const char *file, unsigned line); + /* The copy constructor is needed for C++ throw */ + Exception(const Exception&); -/** Additionally log this error in the log file. */ -@interface LoggedError: ClientError -- (id) init: (uint32_t)errcode, ...; -@end + /* file name */ + const char *m_file; + /* line number */ + unsigned m_line; + /* error description */ + char m_errmsg[TNT_ERRMSG_MAX]; +}; + +class SystemError: public Exception { +public: + + int + errnum() const + { + return m_errnum; + } + + virtual void log() const; + +protected: + SystemError(const char *file, unsigned line); + + void + init(const char *format, ...); + + void + init(const char *format, va_list ap); + +private: + /* system errno */ + int m_errnum; +}; + +class ClientError: public Exception { +public: + virtual void log() const; + + int + errcode() const + { + return m_errcode; + } + + ClientError(const char *file, unsigned line, uint32_t errcode, ...); + /* A special constructor for lbox_raise */ + ClientError(const char *file, unsigned line, const char *msg, + uint32_t errcode); +private: + /* client errno code */ + int m_errcode; +}; + +class LoggedError: public ClientError { +public: + template <typename ... Args> + LoggedError(const char *file, unsigned line, uint32_t errcode, Args ... args) + : ClientError(file, line, errcode, args...) + { + /* TODO: actually calls ClientError::log */ + log(); + } +}; + +class IllegalParams: public LoggedError { +public: + IllegalParams(const char *file, unsigned line, const char *msg); +}; + +class ErrorInjection: public LoggedError { +public: + ErrorInjection(const char *file, unsigned line, const char *msg); +}; -/** A handy wrapper for ER_ILLEGAL_PARAMS, which is used very - * often. - */ -@interface IllegalParams: LoggedError -- (id) init: (const char *)msg; -@end - -/** ER_INJECTION wrapper. */ -@interface ErrorInjection: LoggedError -- (id) init: (const char *)msg; -@end - -/** - * A helper macro to add __FILE__ and __LINE__ information to - * raised exceptions. - * - * Usage: - * - * tnt_raise(tnt_Exception); - * tnt_raise(LoggedError, :"invalid argument %d", argno); - */ #define tnt_raise(...) tnt_raise0(__VA_ARGS__) #define tnt_raise0(class, ...) do { \ say_debug("%s at %s:%i", #class, __FILE__, __LINE__); \ - class *exception = [class alloc]; \ - exception->file = __FILE__; \ - exception->line = __LINE__; \ - [exception init __VA_ARGS__]; \ - @throw exception; \ + throw class(__FILE__, __LINE__, ##__VA_ARGS__); \ } while (0) #endif /* TARANTOOL_EXCEPTION_H_INCLUDED */ diff --git a/include/fiber.h b/include/fiber.h index a78a677e5fc07386dd14bf800a9598a9c9fc318b..5a2c7db5e252f0cfbb296c4a8fa40254d38494a8 100644 --- a/include/fiber.h +++ b/include/fiber.h @@ -38,7 +38,9 @@ #include <util.h> #include "third_party/queue.h" +#if defined(__cplusplus) #include "exception.h" +#endif /* defined(__cplusplus) */ #include "palloc.h" #include <rlist.h> @@ -58,8 +60,19 @@ * cancelled. */ -@interface FiberCancelException: tnt_Exception -@end +#if defined(__cplusplus) +class FiberCancelException: public Exception { +public: + FiberCancelException(const char *file, unsigned line) + : Exception(file, line) { + /* Nothing */ + } + + virtual void log() const { + say_debug("FiberCancelException"); + } +}; +#endif /* defined(__cplusplus) */ struct fiber { #ifdef ENABLE_BACKTRACE @@ -85,6 +98,10 @@ struct fiber { struct rlist link; struct rlist state; + /* This struct is considered as non-POD when compiling by g++. + * You can safetly ignore all offset_of-related warnings. + * See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31488 + */ void (*f) (va_list); va_list f_data; u32 flags; @@ -124,7 +141,7 @@ void fiber_destroy_all(); void fiber_gc(void); void fiber_call(struct fiber *callee, ...); void fiber_wakeup(struct fiber *f); -struct fiber *fiber_find(int fid); +struct fiber *fiber_find(uint32_t fid); /** Cancel a fiber. A cancelled fiber will have * tnt_FiberCancelException raised in it. * diff --git a/include/fio.h b/include/fio.h index f2c2a072d6ad8fdc272fc0882b1f3210575f26f0..bbece9db8a5b789ec2da6c5977f04dba6eb600ba 100644 --- a/include/fio.h +++ b/include/fio.h @@ -37,6 +37,10 @@ #include <stdbool.h> #include <sys/uio.h> +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + struct iovec; /** * Read up to N bytes from file into the buffer, @@ -188,5 +192,9 @@ fio_batch_add(struct fio_batch *batch, void *row, ssize_t row_len); int fio_batch_write(struct fio_batch *batch, int fd); +#if defined(__cplusplus) +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + #endif /* TARANTOOL_FIO_H_INCLUDED */ diff --git a/include/iobuf.h b/include/iobuf.h index e6ee150e6f926dfa25e7e90301934e2c2c703cf4..c05a41e69e385a71e931180480156ddba5c9154e 100644 --- a/include/iobuf.h +++ b/include/iobuf.h @@ -172,10 +172,10 @@ obuf_dup(struct obuf *obuf, const void *data, size_t size); static inline struct obuf_svp obuf_create_svp(struct obuf *buf) { - struct obuf_svp svp = { - .pos = buf->pos, .iov_len = buf->iov[buf->pos].iov_len, - .size = buf->size - }; + struct obuf_svp svp; + svp.pos = buf->pos; + svp.iov_len = buf->iov[buf->pos].iov_len; + svp.size = buf->size; return svp; } @@ -183,7 +183,7 @@ obuf_create_svp(struct obuf *buf) static inline void * obuf_svp_to_ptr(struct obuf *buf, struct obuf_svp *svp) { - return buf->iov[svp->pos].iov_base + svp->iov_len; + return (char *) buf->iov[svp->pos].iov_base + svp->iov_len; } /** Forget anything added to output buffer after the savepoint. */ diff --git a/include/lib/bit/bit.h b/include/lib/bit/bit.h index 6fbdf06f00b8c7d57e69d63d4d32d0d032badb1a..08274fddfa7594c8546910639801a24991418c1c 100644 --- a/include/lib/bit/bit.h +++ b/include/lib/bit/bit.h @@ -44,6 +44,10 @@ #endif /* defined(HAVE_FFSL) || defined(HAVE_FFSLL) */ #include <limits.h> +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + /** @cond false **/ #define bit_likely(x) __builtin_expect((x),1) #define bit_unlikely(x) __builtin_expect((x),0) @@ -471,4 +475,8 @@ bit_iterator_next(struct bit_iterator *it) #undef ITER_CTZ #undef ITER_UINT +#if defined(__cplusplus) +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + #endif /* TARANTOOL_LIB_BIT_BIT_H_INCLUDED */ diff --git a/include/lib/bitset/bitset.h b/include/lib/bitset/bitset.h index 3278143c02710aeac82942e33060360c45eaa2ba..ac7b97177a359124e805fb80e46ca5a672ce9f5f 100644 --- a/include/lib/bitset/bitset.h +++ b/include/lib/bitset/bitset.h @@ -59,6 +59,10 @@ #include <lib/bit/bit.h> +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + /** @cond false */ struct bitset_page { size_t first_pos; @@ -166,4 +170,8 @@ void bitset_dump(struct bitset *bitset, int verbose, FILE *stream); #endif /* defined(DEBUG) */ +#if defined(__cplusplus) +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + #endif /* TARANTOOL_LIB_BITSET_BITSET_H_INCLUDED */ diff --git a/include/lib/bitset/expr.h b/include/lib/bitset/expr.h index ea6cb0b980798158e3d1fef5b44f5752e03bc183..8689f8c0cccd617ec803f28f0edbac10bd07b568 100644 --- a/include/lib/bitset/expr.h +++ b/include/lib/bitset/expr.h @@ -62,6 +62,10 @@ #include "bitset.h" +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + /** @cond false **/ struct bitset_expr_conj { size_t size; @@ -134,4 +138,8 @@ bitset_expr_add_conj(struct bitset_expr *expr); int bitset_expr_add_param(struct bitset_expr *expr, size_t bitset_id, bool pre_not); +#if defined(__cplusplus) +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + #endif /* TARANTOOL_LIB_BITSET_EXPR_H_INCLUDED */ diff --git a/include/lib/bitset/index.h b/include/lib/bitset/index.h index 877ff78d9a1716f1db0f7884c9401c372f2c651e..fd1ed792b7dba5d5e299342a02091213b6445dc1 100644 --- a/include/lib/bitset/index.h +++ b/include/lib/bitset/index.h @@ -114,6 +114,10 @@ #include <lib/bitset/bitset.h> #include <lib/bitset/iterator.h> +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + /** * @brief BitsetIndex */ @@ -289,7 +293,7 @@ bitset_index_contains_value(struct bitset_index *index, size_t value); * @return number of pairs in \a index */ inline size_t -bitset_index_size(struct bitset_index *index) +bitset_index_size(const struct bitset_index *index) { return bitset_cardinality(index->bitsets[0]); } @@ -299,4 +303,8 @@ void bitset_index_dump(struct bitset_index *index, int verbose, FILE *stream); #endif /* defined(DEBUG) */ +#if defined(__cplusplus) +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + #endif /* TARANTOOL_LIB_BITSET_INDEX_H_INCLUDED */ diff --git a/include/lib/bitset/iterator.h b/include/lib/bitset/iterator.h index 92c143e557996abfe0ca72cf580cc69598b88fa8..6750bbabc7348a3eea9fede6d7669de7f8d200ec 100644 --- a/include/lib/bitset/iterator.h +++ b/include/lib/bitset/iterator.h @@ -49,6 +49,10 @@ #include <lib/bitset/bitset.h> #include <lib/bitset/expr.h> +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + /** @cond false **/ struct bitset_iterator_conj; /** @endcond **/ @@ -129,4 +133,8 @@ bitset_iterator_rewind(struct bitset_iterator *it); size_t bitset_iterator_next(struct bitset_iterator *it); +#if defined(__cplusplus) +} +#endif /* defined(__cplusplus) */ + #endif /* TARANTOOL_LIB_BITSET_ITERATOR_H_INCLUDED */ diff --git a/include/mhash.h b/include/mhash.h index d34e83a3862d6648789e404eade099de2a000808..722a9dffc9e973c038a056336a9524595200e07d 100644 --- a/include/mhash.h +++ b/include/mhash.h @@ -258,6 +258,7 @@ _mh(put)(struct _mh(t) *h, const mh_node_t *node, mh_node_t **ret, mh_arg_t arg) { mh_int_t x = mh_end(h); + int exist; if (h->size == h->n_buckets) /* no one free elements in the hash table */ goto put_done; @@ -280,7 +281,7 @@ _mh(put)(struct _mh(t) *h, const mh_node_t *node, mh_node_t **ret, #endif x = put_slot(h, node, arg); - int exist = mh_exist(h, x); + exist = mh_exist(h, x); if (!exist) { /* add new */ @@ -345,12 +346,12 @@ _mh(del_resize)(struct _mh(t) *h, mh_int_t x, struct _mh(t) * _mh(new)() { - struct _mh(t) *h = calloc(1, sizeof(*h)); - h->shadow = calloc(1, sizeof(*h)); + struct _mh(t) *h = (struct _mh(t) *) calloc(1, sizeof(*h)); + h->shadow = (struct _mh(t) *) calloc(1, sizeof(*h)); h->prime = 0; h->n_buckets = __ac_prime_list[h->prime]; - h->p = calloc(h->n_buckets, sizeof(mh_node_t)); - h->b = calloc(h->n_buckets / 16 + 1, sizeof(unsigned)); + h->p = (mh_node_t *) calloc(h->n_buckets, sizeof(mh_node_t)); + h->b = (mh_int_t *) calloc(h->n_buckets / 16 + 1, sizeof(unsigned)); h->upper_bound = h->n_buckets * MH_DENSITY; return h; } @@ -361,7 +362,7 @@ _mh(clear)(struct _mh(t) *h) free(h->p); h->prime = 0; h->n_buckets = __ac_prime_list[h->prime]; - h->p = calloc(h->n_buckets, sizeof(mh_node_t)); + h->p = (mh_node_t *) calloc(h->n_buckets, sizeof(mh_node_t)); h->upper_bound = h->n_buckets * MH_DENSITY; } @@ -437,10 +438,10 @@ _mh(start_resize)(struct _mh(t) *h, mh_int_t buckets, mh_int_t batch, s->n_buckets = __ac_prime_list[h->prime]; s->upper_bound = s->n_buckets * MH_DENSITY; s->n_dirty = 0; - s->p = malloc(s->n_buckets * sizeof(mh_node_t)); + s->p = (mh_node_t *) malloc(s->n_buckets * sizeof(mh_node_t)); if (s->p == NULL) return -1; - s->b = calloc(s->n_buckets / 16 + 1, sizeof(unsigned)); + s->b = (mh_int_t *) calloc(s->n_buckets / 16 + 1, sizeof(unsigned)); if (s->b == NULL) { free(s->p); s->p = NULL; @@ -460,11 +461,11 @@ _mh(reserve)(struct _mh(t) *h, mh_int_t size, #ifndef mh_stat #define mh_stat(buf, h) ({ \ - tbuf_printf(buf, " n_buckets: %"PRIu32 CRLF \ - " n_dirty: %"PRIu32 CRLF \ - " size: %"PRIu32 CRLF \ - " resize_cnt: %"PRIu32 CRLF \ - " resize_position: %"PRIu32 CRLF, \ + tbuf_printf(buf, " n_buckets: %" PRIu32 CRLF \ + " n_dirty: %" PRIu32 CRLF \ + " size: %" PRIu32 CRLF \ + " resize_cnt: %" PRIu32 CRLF \ + " resize_position: %" PRIu32 CRLF, \ h->n_buckets, \ h->n_dirty, \ h->size, \ diff --git a/include/object.h b/include/object.h index 643980a081fa77d8dd0175196160042be7018a13..cf97d59c5c8828a5d851d4d2e8361964476c5884 100644 --- a/include/object.h +++ b/include/object.h @@ -28,14 +28,26 @@ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#include <objc/runtime.h> -@interface tnt_Object { - Class isa; -} -+ (id) alloc; -- (id) init; -- (void) free; -- (void) subclassResponsibility: (SEL) cmd; -@end +class Object { +public: + Object() { + /* Nothing */ + } + +protected: + /* + * Explicitly disable the copy constructor and the assignment operato + */ + Object(const Object&) + { + /* Nothing */ + } + + Object& operator=(const Object&) + { + return *this; + } +}; + #endif /* TARANTOOL_OBJECT_H_INCLUDED */ diff --git a/include/palloc.h b/include/palloc.h index d945aa5552116b4f81de27ee1e261a895667a8bb..0557cd620f49b867b90f2fbbea83c4d37b4bb1ca 100644 --- a/include/palloc.h +++ b/include/palloc.h @@ -32,6 +32,10 @@ #include <stdint.h> #include "util.h" +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + #define PALLOC_POOL_NAME_MAXLEN 30 struct tbuf; @@ -57,4 +61,8 @@ size_t palloc_allocated(struct palloc_pool *); void palloc_stat(struct tbuf *buf); +#if defined(__cplusplus) +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + #endif /* TARANTOOL_PALLOC_H_INCLUDED */ diff --git a/include/pickle.h b/include/pickle.h index 8f3e6340a10314bf9f5bc1eb52bae081ea8cadbf..0e35d4c9788da31d62fa6433ca3fc6f0dba48310 100644 --- a/include/pickle.h +++ b/include/pickle.h @@ -43,7 +43,7 @@ static inline uint32_t load_u32(const void **data) { - const uint32_t *b = *data; + const uint32_t *b = (const uint32_t *) *data; *data= b + 1; return *b; } @@ -52,27 +52,27 @@ static inline uint32_t load_varint32(const void **data) { assert(data != NULL && *data != NULL); - const uint8_t *b = *data; + const uint8_t *b = (const uint8_t *) *data; if (!(b[0] & 0x80)) { - *data += 1; + *data = (char *) *data + 1; return (b[0] & 0x7f); } if (!(b[1] & 0x80)) { - *data += 2; + *data = (char *) *data + 2; return (b[0] & 0x7f) << 7 | (b[1] & 0x7f); } if (!(b[2] & 0x80)) { - *data += 3; + *data = (char *) *data + 3; return (b[0] & 0x7f) << 14 | (b[1] & 0x7f) << 7 | (b[2] & 0x7f); } if (!(b[3] & 0x80)) { - *data += 4; + *data = (char *) *data + 4; return (b[0] & 0x7f) << 21 | (b[1] & 0x7f) << 14 | (b[2] & 0x7f) << 7 | (b[3] & 0x7f); } if (!(b[4] & 0x80)) { - *data += 5; + *data = (char *) *data + 5; return (b[0] & 0x7f) << 28 | (b[1] & 0x7f) << 21 | (b[2] & 0x7f) << 14 | (b[3] & 0x7f) << 7 | (b[4] & 0x7f); } @@ -84,63 +84,63 @@ static inline uint32_t pick_varint32(const void **data, const void *end) { assert(data != NULL && *data != NULL); - const uint8_t *b = *data; - ssize_t size = end - *data; + const uint8_t *b = (const uint8_t *) *data; + ssize_t size = (const char *) end - (const char * )*data; if (unlikely(size < 1)) - tnt_raise(IllegalParams, :"varint is too short (expected 1+ bytes)"); + tnt_raise(IllegalParams, "varint is too short (expected 1+ bytes)"); if (!(b[0] & 0x80)) { - *data += 1; + *data = (char *) *data + 1; return (b[0] & 0x7f); } if (unlikely(size < 2)) - tnt_raise(IllegalParams, :"varint is too short (expected 2+ bytes)"); + tnt_raise(IllegalParams, "varint is too short (expected 2+ bytes)"); if (!(b[1] & 0x80)) { - *data += 2; + *data = (char *) *data + 2; return (b[0] & 0x7f) << 7 | (b[1] & 0x7f); } if (unlikely(size < 3)) - tnt_raise(IllegalParams, :"BER int is too short (expected 3+ bytes)"); + tnt_raise(IllegalParams, "BER int is too short (expected 3+ bytes)"); if (!(b[2] & 0x80)) { - *data += 3; + *data = (char *) *data + 3; return (b[0] & 0x7f) << 14 | (b[1] & 0x7f) << 7 | (b[2] & 0x7f); } if (unlikely(size < 4)) - tnt_raise(IllegalParams, :"BER int is too short (expected 4+ bytes)"); + tnt_raise(IllegalParams, "BER int is too short (expected 4+ bytes)"); if (!(b[3] & 0x80)) { - *data += 4; + *data = (char *) *data + 4; return (b[0] & 0x7f) << 21 | (b[1] & 0x7f) << 14 | (b[2] & 0x7f) << 7 | (b[3] & 0x7f); } if (unlikely(size < 5)) - tnt_raise(IllegalParams, :"BER int is too short (expected 5+ bytes)"); + tnt_raise(IllegalParams, "BER int is too short (expected 5+ bytes)"); if (!(b[4] & 0x80)) { - *data += 5; + *data = (char *) *data + 5; return (b[0] & 0x7f) << 28 | (b[1] & 0x7f) << 21 | (b[2] & 0x7f) << 14 | (b[3] & 0x7f) << 7 | (b[4] & 0x7f); } - tnt_raise(IllegalParams, :"incorrect BER integer format"); + tnt_raise(IllegalParams, "incorrect BER integer format"); } #define pick_u(bits) \ static inline uint##bits##_t \ pick_u##bits(const void **begin, const void *end) \ { \ - if (end - *begin < (bits)/8) \ + if ((const char *) end - (const char *) *begin < (bits)/8) \ tnt_raise(IllegalParams, \ - :"packet too short (expected "#bits" bits)");\ + "packet too short (expected "#bits" bits)");\ uint##bits##_t r = *(uint##bits##_t *)*begin; \ - *begin += (bits)/8; \ + *begin = (const char *) *begin + (bits)/8; \ return r; \ } @@ -153,10 +153,10 @@ static inline const void * pick_str(const void **data, const void *end, uint32_t size) { const void *str = *data; - if (str + size > end) + if ((const char *) str + size > (const char *) end) tnt_raise(IllegalParams, - :"packet too short (expected a field)"); - *data += size; + "packet too short (expected a field)"); + *data = (char *) *data + size; return str; } @@ -183,7 +183,7 @@ pick_field_u32(const void **data, const void *end) uint32_t size = pick_varint32(data, end); if (size != sizeof(uint32_t)) tnt_raise(IllegalParams, - :"incorrect packet format (expected a 32-bit int)"); + "incorrect packet format (expected a 32-bit int)"); return *(uint32_t *) pick_str(data, end, size); } @@ -197,7 +197,7 @@ valid_tuple(const void *data, const void *end, uint32_t field_count) for (int i = 0; i < field_count; i++) pick_field(&data, end); - return data - start; + return (const char *) data - (const char *) start; } /** @@ -211,9 +211,9 @@ tuple_range_size(const void **begin, const void *end, size_t count) const void *start = *begin; while (*begin < end && count-- > 0) { size_t len = load_varint32(begin); - *begin += len; + *begin = (char *) *begin + len; } - return *begin - start; + return (const char *) *begin - (const char *) start; } static inline size_t @@ -234,7 +234,7 @@ varint32_sizeof(uint32_t value) static inline void * pack_varint32(void *buf, uint32_t value) { - uint8_t *target = buf; + uint8_t *target = (uint8_t *) buf; if (value >= (1 << 7)) { if (value >= (1 << 14)) { if (value >= (1 << 21)) { @@ -254,7 +254,7 @@ pack_varint32(void *buf, uint32_t value) static inline void * pack_lstr(void *buf, const void *str, uint32_t len) { - return memcpy(pack_varint32(buf, len), str, len) + len; + return (char *) memcpy(pack_varint32(buf, len), str, len) + len; } #endif /* TARANTOOL_PICKLE_H_INCLUDED */ diff --git a/include/recovery.h b/include/recovery.h index 11bb87090d8cfbe5e9ebadc73b59bbaf3f94f1f4..b04993b6a418d51381d2ba9b46a8313515779a1e 100644 --- a/include/recovery.h +++ b/include/recovery.h @@ -34,6 +34,10 @@ #include "util.h" #include "tarantool_ev.h" +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + struct fiber; struct tbuf; @@ -144,4 +148,8 @@ void snapshot_write_row(struct log_io *i, struct fio_batch *batch, void snapshot_save(struct recovery_state *r, void (*loop) (struct log_io *, struct fio_batch *)); +#if defined(__cplusplus) +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + #endif /* TARANTOOL_RECOVERY_H_INCLUDED */ diff --git a/include/replication.h b/include/replication.h index 48771597828a3d20f48a820513efc5192178e0ab..608cafe73d96b56084f84be0a160059bceba036c 100644 --- a/include/replication.h +++ b/include/replication.h @@ -55,7 +55,7 @@ replication_prefork(); * @return None. Panics and exits on error. */ void -replication_init(); +replication_init(const char *bind_ipaddr, int replication_port); #endif // TARANTOOL_REPLICATION_H_INCLUDED diff --git a/include/rlist.h b/include/rlist.h index a3d10d36004b24b7781b7384f5589885bf050aed..1756efb5c07bf9404d35b63371352c9dd9acd00c 100644 --- a/include/rlist.h +++ b/include/rlist.h @@ -29,6 +29,15 @@ * SUCH DAMAGE. */ +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + +#ifndef typeof +/* TODO: 'typeof' is a GNU extension */ +#define typeof __typeof__ +#endif + /** * list entry and head structure */ @@ -266,4 +275,9 @@ delete from one list and add_tail as another's head item = rlist_prev_entry((item), member)) +#if defined(__cplusplus) +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + + #endif /* TARANTOOL_RLIST_H_INCLUDED */ diff --git a/include/rope.h b/include/rope.h index 8b799afcc6b3118d71c7f5534475b215208197eb..bbebff7a02c0701d1aeb78f46fd90b1f9fce945c 100644 --- a/include/rope.h +++ b/include/rope.h @@ -31,6 +31,10 @@ #include <stddef.h> #include <stdbool.h> +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + typedef unsigned int rsize_t; typedef int rssize_t; typedef void *(*rope_split_func)(void *, size_t, size_t); @@ -45,9 +49,9 @@ struct rope_node { int height; /** Subtree size. */ rsize_t tree_size; - /* Substring size. */ + /* Substring size. */ rsize_t leaf_size; - /* Substring. */ + /* Substring. */ void *data; /* Left (0) and right (1) links */ struct rope_node *link[2]; @@ -210,8 +214,8 @@ rope_iter_create(struct rope_iter *it, struct rope *rope) static inline struct rope_iter * rope_iter_new(struct rope *rope) { - struct rope_iter *it = rope->alloc(rope->alloc_ctx, - sizeof(struct rope_iter)); + struct rope_iter *it = (struct rope_iter *) + rope->alloc(rope->alloc_ctx, sizeof(struct rope_iter)); if (it == NULL) return NULL; @@ -255,4 +259,8 @@ rope_check(struct rope *rope); void rope_pretty_print(struct rope *rope, void (*print_leaf)(void *, size_t)); +#if defined(__cplusplus) +} +#endif /* defined(__cplusplus) */ + #endif /* INCLUDES_TARANTOOL_ROPE_H */ diff --git a/include/say.h b/include/say.h index cbe97193e05051c9953b3da42f4704f2286c76cc..02df38ed0ea34db26713d7dedcda4318fa9b1ee7 100644 --- a/include/say.h +++ b/include/say.h @@ -34,6 +34,10 @@ #include <util.h> /* for FORMAT_PRINTF */ +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + enum say_level { S_FATAL, /* do not this value use directly */ S_ERROR, @@ -67,5 +71,8 @@ void _say(int level, const char *filename, int line, const char *error, #define say_debug(...) say(S_DEBUG, NULL, __VA_ARGS__) +#if defined(__cplusplus) +} /* extern "C" */ +#endif /* defined(__cplusplus) */ #endif /* TARANTOOL_SAY_H_INCLUDED */ diff --git a/include/scoped_guard.h b/include/scoped_guard.h new file mode 100644 index 0000000000000000000000000000000000000000..a141737acc915f2d5592d9d5f8984aee49cb9af6 --- /dev/null +++ b/include/scoped_guard.h @@ -0,0 +1,71 @@ +#ifndef TARANTOOL_SCOPED_GUARD_H_INCLUDED +#define TARANTOOL_SCOPED_GUARD_H_INCLUDED + +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "object.h" + +template <typename Functor> +class ScopedGuard: public Object { +public: + explicit ScopedGuard(const Functor& fun) + : m_fun(fun), m_active(true) { + /* nothing */ + } + + ScopedGuard(ScopedGuard&& guard) + : m_fun(guard.m_fun), m_active(true) { + guard.m_active = false; + } + + ~ScopedGuard() + { + if (!m_active) + return; + + m_fun(); + } + +private: + ScopedGuard(const ScopedGuard&) = delete; + ScopedGuard& operator=(const ScopedGuard&) = delete; + + const Functor& m_fun; + bool m_active; +}; + +template <typename Functor> +inline ScopedGuard<Functor> +make_scoped_guard(const Functor& guard) +{ + return ScopedGuard<Functor>(guard); +} + +#endif /* TARANTOOL_SCOPED_GUARD_H_INCLUDED */ diff --git a/include/sio.h b/include/sio.h index ba7ad0ab70132dc80b11b3429d38d56c7a68410b..e67b7dc83a12a4d419e29e0cbaf6b01524ee6038 100644 --- a/include/sio.h +++ b/include/sio.h @@ -42,10 +42,11 @@ enum { SERVICE_NAME_MAXLEN = 32 }; -@interface SocketError: SystemError -- (id) init: (int) fd in: (const char *) format: (va_list) ap; -- (id) init: (int) fd in: (const char *) format, ...; -@end +class SocketError: public SystemError { +public: + SocketError(const char *file, unsigned line, int fd, + const char *format, ...); +}; const char *sio_socketname(int fd); int sio_socket(int domain, int type, int protocol); @@ -117,7 +118,7 @@ static inline void sio_add_to_iov(struct iovec *iov, ssize_t size) { iov->iov_len += size; - iov->iov_base -= size; + iov->iov_base = (char *) iov->iov_base - size; } #endif /* TARANTOOL_SIO_H_INCLUDED */ diff --git a/include/stat.h b/include/stat.h index 191a103e32b9b0e1a3802ad5f8fd5f5da9972ed8..478eeb4f4c9f2f4dc3312d1e2b40b2533ccaf347 100644 --- a/include/stat.h +++ b/include/stat.h @@ -34,7 +34,7 @@ void stat_init(void); void stat_free(void); void stat_cleanup(int base, size_t max_idx); int stat_register(const char **name, size_t count); -int stat_max_name_len; +extern int stat_max_name_len; void stat_collect(int base, int name, i64 value); diff --git a/include/tarantool.h b/include/tarantool.h index b9eda2655216e50cdf2ad03e6ac529439826f155..c28fe745393bfd2aee4ce51c9e1ad5e80210ba60 100644 --- a/include/tarantool.h +++ b/include/tarantool.h @@ -31,6 +31,10 @@ #include <stdbool.h> #include <util.h> +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + struct tarantool_cfg; struct tbuf; @@ -52,4 +56,12 @@ char **init_set_proc_title(int argc, char **argv); void free_proc_title(int argc, char **argv); void set_proc_title(const char *format, ...); void title(const char *fmt, ...); + +#define DEFAULT_CFG_FILENAME "tarantool.cfg" +#define DEFAULT_CFG SYSCONF_DIR "/" DEFAULT_CFG_FILENAME + +#if defined(__cplusplus) +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + #endif /* TARANTOOL_H_INCLUDED */ diff --git a/include/tbuf.h b/include/tbuf.h index 50844d28ea3e29cabf9e0fa38482b658cf24c272..89f1654f18c8b24597614055ae50dc0b59347dc0 100644 --- a/include/tbuf.h +++ b/include/tbuf.h @@ -34,13 +34,17 @@ #include <util.h> +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + struct tbuf { /* Used space in the buffer. */ u32 size; /* Total allocated buffer capacity. */ u32 capacity; /* Allocated buffer. */ - void *data; + char *data; struct palloc_pool *pool; }; @@ -60,7 +64,7 @@ static inline void tbuf_append(struct tbuf *b, const void *data, size_t len) tbuf_ensure(b, len + 1); /* +1 for trailing '\0' */ memcpy(b->data + b->size, data, len); b->size += len; - *(((char *)b->data) + b->size) = '\0'; + *((b->data) + b->size) = '\0'; } static inline char * @@ -94,4 +98,9 @@ void tbuf_printf(struct tbuf *b, const char *format, ...) __attribute__ ((format(FORMAT_PRINTF, 2, 3))); char *tbuf_to_hex(const struct tbuf *x); + +#if defined(__cplusplus) +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + #endif /* TARANTOOL_TBUF_H_INCLUDED */ diff --git a/include/util.h b/include/util.h index aa78f578cf3ed418b9daa2f86da06ff1f688a309..ea73f53ac3f32865cd92d39cbb0929345fa76879 100644 --- a/include/util.h +++ b/include/util.h @@ -34,6 +34,12 @@ #include <unistd.h> #include <inttypes.h> +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + +#define restrict __restrict__ + #ifndef NDEBUG #define TRASH(ptr) memset(ptr, '#', sizeof(*ptr)) #else @@ -48,11 +54,27 @@ /* Macros to define enum and corresponding strings. */ #define ENUM0_MEMBER(s, ...) s, #define ENUM_MEMBER(s, v, ...) s = v, -#define ENUM_STRS_MEMBER(s, v, ...) [s] = #s, #define ENUM0(enum_name, enum_members) enum enum_name {enum_members(ENUM0_MEMBER) enum_name##_MAX} #define ENUM(enum_name, enum_members) enum enum_name {enum_members(ENUM_MEMBER) enum_name##_MAX} +#if defined(__cplusplus) +#define ENUM_STRS_MEMBER(s, v, ...) names[s] = #s; +/* A special hack to emulate C99 designated initializers */ +#define STRS(enum_name, enum_members) \ + const char *enum_name##_strs[enum_name##_MAX]; \ + namespace { \ + const struct enum_name##_strs_init { \ + enum_name##_strs_init(const char **names) { \ + memset(names, 0, sizeof(*names) * \ + enum_name##_MAX); \ + enum_members(ENUM_STRS_MEMBER) \ + } \ + } enum_name##_strs_init(enum_name##_strs); \ + } +#else /* !defined(__cplusplus) */ +#define ENUM_STRS_MEMBER(s, v, ...) [s] = #s, #define STRS(enum_name, enum_members) \ - const char *enum_name##_strs[enum_name##_MAX + 1] = {enum_members(ENUM_STRS_MEMBER) '\0'} + const char *enum_name##_strs[(unsigned) enum_name##_MAX + 1] = {enum_members(ENUM_STRS_MEMBER) 0} +#endif #define STR2ENUM(enum_name, str) ((enum enum_name) strindex(enum_name##_strs, str, enum_name##_MAX)) uint32_t @@ -169,4 +191,8 @@ void * memrchr(const void *s, int c, size_t n); #endif /* HAVE_MEMRCHR */ +#if defined(__cplusplus) +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + #endif /* TARANTOOL_UTIL_H_INCLUDED */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8028d32837b35d330a3a76099fd94adccb84270d..add443c2addf7cc748f6fc63f5dc25bc5ee1df9b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,41 +17,41 @@ if (CMAKE_COMPILER_IS_GNUCC) endif() # -# Build admin.m from admin.rl, but only if admin.rl was changed. -# The same applies to memcached.m/memcached.rl. -# We track admin.m and memcached.m in revision control, and thus do not +# Build admin.cc from admin.rl, but only if admin.rl was changed. +# The same applies to memcached.cc/memcached.rl. +# We track admin.cc and memcached.cc in revision control, and thus do not # require engineers who do not modify .rl files to have Ragel # installed. # -add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/src/admin.m +add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/src/admin.cc WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - COMMAND ${RAGEL} -G2 src/admin.rl -o src/admin.m + COMMAND ${RAGEL} -G2 src/admin.rl -o src/admin.cc DEPENDS ${CMAKE_SOURCE_DIR}/src/admin.rl) -add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/src/memcached-grammar.m +add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/src/memcached-grammar.cc WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND ${RAGEL} -G2 src/memcached-grammar.rl - -o src/memcached-grammar.m + -o src/memcached-grammar.cc DEPENDS ${CMAKE_SOURCE_DIR}/src/memcached-grammar.rl) -add_custom_target(generate_admin_m DEPENDS ${CMAKE_SOURCE_DIR}/src/admin.m) -add_custom_target(generate_memcached_grammar_m DEPENDS - ${CMAKE_SOURCE_DIR}/src/memcached-grammar.m) +add_custom_target(generate_admin_m DEPENDS ${CMAKE_SOURCE_DIR}/src/admin.cc) +add_custom_target(generate_memcached_grammar_cc DEPENDS + ${CMAKE_SOURCE_DIR}/src/memcached-grammar.cc) -# do not randomly try to re-generate admin.m or memcached-grammar.m +# do not randomly try to re-generate admin.cc or memcached-grammar.cc # after a fresh checkout/branch switch. execute_process(COMMAND ${CMAKE_COMMAND} -E touch_nocreate - ${CMAKE_SOURCE_DIR}/src/admin.m - ${CMAKE_SOURCE_DIR}/src/memcached-grammar.m) + ${CMAKE_SOURCE_DIR}/src/admin.cc + ${CMAKE_SOURCE_DIR}/src/memcached-grammar.cc) -set_source_files_properties(${CMAKE_SOURCE_DIR}/src/memcached-grammar.m +set_source_files_properties(${CMAKE_SOURCE_DIR}/src/memcached-grammar.cc PROPERTIES HEADER_FILE_ONLY true) -set_source_files_properties(memcached.m +set_source_files_properties(memcached.cc PROPERTIES COMPILE_FLAGS "-Wno-uninitialized") # -# Do not clean admin.m, memcached.m or other +# Do not clean admin.cc, memcached.cc or other # generated files in 'make clean' -- they are under # revision control. # @@ -61,55 +61,57 @@ set_property(DIRECTORY PROPERTY CLEAN_NO_CUSTOM true) # Used by modules. # set (recompiled_sources - ${CMAKE_SOURCE_DIR}/src/tarantool.m - ${CMAKE_SOURCE_DIR}/src/lua/init.m - ${CMAKE_SOURCE_DIR}/src/say.m - ${CMAKE_SOURCE_DIR}/src/assoc.m - ${CMAKE_SOURCE_DIR}/src/replication.m - ${CMAKE_SOURCE_DIR}/src/memcached.m - ${CMAKE_SOURCE_DIR}/src/fiber.m) + ${CMAKE_SOURCE_DIR}/src/tarantool.cc + ${CMAKE_SOURCE_DIR}/src/opts.c + ${CMAKE_SOURCE_DIR}/src/lua/init.cc + ${CMAKE_SOURCE_DIR}/src/say.cc + ${CMAKE_SOURCE_DIR}/src/assoc.cc + ${CMAKE_SOURCE_DIR}/src/replication.cc + ${CMAKE_SOURCE_DIR}/src/memcached.cc + ${CMAKE_SOURCE_DIR}/src/fiber.cc) set (common_sources - tbuf.m - palloc.m - util.m - sio.m - evio.m - coio.m - coeio.m - iobuf.m - coio_buf.m - salloc.m - pickle.m - coro.m - stat.m - log_io.m - recovery.m - admin.m - cpu_feature.m - replica.m - iproto.m - session.m - object.m - exception.m + tbuf.c + palloc.cc + util.c + scoped_guard.cc + sio.cc + evio.cc + coio.cc + coeio.cc + iobuf.cc + coio_buf.cc + salloc.cc + pickle.cc + coro.cc + stat.cc + log_io.cc + recovery.cc + admin.cc + cpu_feature.c + replica.cc + iproto.cc + session.cc + object.cc + exception.cc errcode.c - errinj.m + errinj.cc fio.c crc32.c rope.c - ipc.m - lua/info.m - lua/stat.m - lua/slab.m - lua/uuid.m - lua/lua_ipc.m - lua/lua_socket.m - lua/session.m - lua/cjson.m + ipc.cc + lua/info.cc + lua/stat.cc + lua/slab.cc + lua/uuid.cc + lua/lua_ipc.cc + lua/lua_socket.cc + lua/session.cc + lua/cjson.cc ) if (ENABLE_TRACE) - set (common_sources ${common_sources} trace.m) + set (common_sources ${common_sources} trace.c) endif() set_source_files_compile_flags(${common_sources}) @@ -125,7 +127,6 @@ list(APPEND common_libraries ${LIBGOPT_LIBRARIES} ${LIBCJSON_LIBRARIES} ${LUAJIT_LIB} - ${LIBOBJC_LIBRARIES} misc ) diff --git a/src/admin.m b/src/admin.cc similarity index 94% rename from src/admin.m rename to src/admin.cc index 361eebaa919932ce01c442cfc7c20889c4c7fadc..d0f64ebaeb589333f05f6f4b341d86694b088b0e 100644 --- a/src/admin.m +++ b/src/admin.cc @@ -47,11 +47,15 @@ #include <errinj.h> #include "coio_buf.h" -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" +extern "C" { +#include <lua.h> +#include <lauxlib.h> +#include <lualib.h> +} + #include "box/box.h" #include "session.h" +#include "scoped_guard.h" static const char *help = "available commands:" CRLF @@ -73,7 +77,7 @@ static const char *help = static const char *unknown_command = "unknown command. try typing help." CRLF; -#line 77 "src/admin.m" +#line 81 "src/admin.cc" static const int admin_start = 1; static const int admin_first_final = 135; static const int admin_error = 0; @@ -81,7 +85,7 @@ static const int admin_error = 0; static const int admin_en_main = 1; -#line 76 "src/admin.rl" +#line 80 "src/admin.rl" struct salloc_stat_admin_cb_ctx { @@ -92,7 +96,7 @@ struct salloc_stat_admin_cb_ctx { static int salloc_stat_admin_cb(const struct slab_cache_stats *cstat, void *cb_ctx) { - struct salloc_stat_admin_cb_ctx *ctx = cb_ctx; + struct salloc_stat_admin_cb_ctx *ctx = (struct salloc_stat_admin_cb_ctx *) cb_ctx; tbuf_printf(ctx->out, " - { item_size: %- 5i, slabs: %- 3i, items: %- 11" PRIi64 @@ -168,7 +172,7 @@ tarantool_info(struct tbuf *out) tbuf_printf(out, " lsn: %" PRIi64 CRLF, recovery_state->confirmed_lsn); tbuf_printf(out, " recovery_lag: %.3f" CRLF, - recovery_state->remote ? + recovery_state->remote ? recovery_state->remote->recovery_lag : 0); tbuf_printf(out, " recovery_last_update: %.3f" CRLF, recovery_state->remote ? @@ -183,7 +187,7 @@ tarantool_info(struct tbuf *out) static int show_stat_item(const char *name, int rps, i64 total, void *ctx) { - struct tbuf *buf = ctx; + struct tbuf *buf = (struct tbuf *) ctx; int name_len = strlen(name); tbuf_printf(buf, " %s:%*s{ rps: %- 6i, total: %- 12" PRIi64 " }" CRLF, @@ -209,7 +213,7 @@ admin_dispatch(struct ev_io *coio, struct iobuf *iobuf, lua_State *L) char *strstart, *strend; bool state; - while ((pe = memchr(in->pos, '\n', in->end - in->pos)) == NULL) { + while ((pe = (char *) memchr(in->pos, '\n', in->end - in->pos)) == NULL) { if (coio_bread(coio, in, 1) <= 0) return -1; } @@ -218,12 +222,12 @@ admin_dispatch(struct ev_io *coio, struct iobuf *iobuf, lua_State *L) p = in->pos; -#line 222 "src/admin.m" +#line 226 "src/admin.cc" { cs = admin_start; } -#line 227 "src/admin.m" +#line 231 "src/admin.cc" { if ( p == pe ) goto _test_eof; @@ -286,15 +290,15 @@ case 6: } goto st0; tr13: -#line 309 "src/admin.rl" +#line 313 "src/admin.rl" {slab_validate(); ok(out);} goto st135; tr20: -#line 297 "src/admin.rl" +#line 301 "src/admin.rl" {return -1;} goto st135; tr25: -#line 224 "src/admin.rl" +#line 228 "src/admin.rl" { start(out); tbuf_append(out, help, strlen(help)); @@ -302,9 +306,9 @@ case 6: } goto st135; tr36: -#line 283 "src/admin.rl" +#line 287 "src/admin.rl" {strend = p;} -#line 230 "src/admin.rl" +#line 234 "src/admin.rl" { strstart[strend-strstart]='\0'; start(out); @@ -313,7 +317,7 @@ case 6: } goto st135; tr43: -#line 237 "src/admin.rl" +#line 241 "src/admin.rl" { if (reload_cfg(err)) fail(out, err); @@ -322,11 +326,11 @@ case 6: } goto st135; tr67: -#line 307 "src/admin.rl" +#line 311 "src/admin.rl" {coredump(60); ok(out);} goto st135; tr76: -#line 244 "src/admin.rl" +#line 248 "src/admin.rl" { int ret = snapshot(); @@ -341,9 +345,9 @@ case 6: } goto st135; tr98: -#line 293 "src/admin.rl" +#line 297 "src/admin.rl" { state = false; } -#line 257 "src/admin.rl" +#line 261 "src/admin.rl" { strstart[strend-strstart] = '\0'; if (errinj_set_byname(strstart, state)) { @@ -355,9 +359,9 @@ case 6: } goto st135; tr101: -#line 292 "src/admin.rl" +#line 296 "src/admin.rl" { state = true; } -#line 257 "src/admin.rl" +#line 261 "src/admin.rl" { strstart[strend-strstart] = '\0'; if (errinj_set_byname(strstart, state)) { @@ -369,7 +373,7 @@ case 6: } goto st135; tr117: -#line 212 "src/admin.rl" +#line 216 "src/admin.rl" { start(out); show_cfg(out); @@ -377,15 +381,15 @@ case 6: } goto st135; tr131: -#line 300 "src/admin.rl" +#line 304 "src/admin.rl" {start(out); fiber_info(out); end(out);} goto st135; tr137: -#line 299 "src/admin.rl" +#line 303 "src/admin.rl" {start(out); tarantool_info(out); end(out);} goto st135; tr146: -#line 218 "src/admin.rl" +#line 222 "src/admin.rl" { start(out); errinj_info(out); @@ -393,33 +397,33 @@ case 6: } goto st135; tr152: -#line 303 "src/admin.rl" +#line 307 "src/admin.rl" {start(out); palloc_stat(out); end(out);} goto st135; tr160: -#line 302 "src/admin.rl" +#line 306 "src/admin.rl" {start(out); show_slab(out); end(out);} goto st135; tr164: -#line 304 "src/admin.rl" +#line 308 "src/admin.rl" {start(out); show_stat(out);end(out);} goto st135; st135: if ( ++p == pe ) goto _test_eof135; case 135: -#line 412 "src/admin.m" +#line 416 "src/admin.cc" goto st0; tr14: -#line 309 "src/admin.rl" +#line 313 "src/admin.rl" {slab_validate(); ok(out);} goto st7; tr21: -#line 297 "src/admin.rl" +#line 301 "src/admin.rl" {return -1;} goto st7; tr26: -#line 224 "src/admin.rl" +#line 228 "src/admin.rl" { start(out); tbuf_append(out, help, strlen(help)); @@ -427,9 +431,9 @@ case 135: } goto st7; tr37: -#line 283 "src/admin.rl" +#line 287 "src/admin.rl" {strend = p;} -#line 230 "src/admin.rl" +#line 234 "src/admin.rl" { strstart[strend-strstart]='\0'; start(out); @@ -438,7 +442,7 @@ case 135: } goto st7; tr44: -#line 237 "src/admin.rl" +#line 241 "src/admin.rl" { if (reload_cfg(err)) fail(out, err); @@ -447,11 +451,11 @@ case 135: } goto st7; tr68: -#line 307 "src/admin.rl" +#line 311 "src/admin.rl" {coredump(60); ok(out);} goto st7; tr77: -#line 244 "src/admin.rl" +#line 248 "src/admin.rl" { int ret = snapshot(); @@ -466,9 +470,9 @@ case 135: } goto st7; tr99: -#line 293 "src/admin.rl" +#line 297 "src/admin.rl" { state = false; } -#line 257 "src/admin.rl" +#line 261 "src/admin.rl" { strstart[strend-strstart] = '\0'; if (errinj_set_byname(strstart, state)) { @@ -480,9 +484,9 @@ case 135: } goto st7; tr102: -#line 292 "src/admin.rl" +#line 296 "src/admin.rl" { state = true; } -#line 257 "src/admin.rl" +#line 261 "src/admin.rl" { strstart[strend-strstart] = '\0'; if (errinj_set_byname(strstart, state)) { @@ -494,7 +498,7 @@ case 135: } goto st7; tr118: -#line 212 "src/admin.rl" +#line 216 "src/admin.rl" { start(out); show_cfg(out); @@ -502,15 +506,15 @@ case 135: } goto st7; tr132: -#line 300 "src/admin.rl" +#line 304 "src/admin.rl" {start(out); fiber_info(out); end(out);} goto st7; tr138: -#line 299 "src/admin.rl" +#line 303 "src/admin.rl" {start(out); tarantool_info(out); end(out);} goto st7; tr147: -#line 218 "src/admin.rl" +#line 222 "src/admin.rl" { start(out); errinj_info(out); @@ -518,22 +522,22 @@ case 135: } goto st7; tr153: -#line 303 "src/admin.rl" +#line 307 "src/admin.rl" {start(out); palloc_stat(out); end(out);} goto st7; tr161: -#line 302 "src/admin.rl" +#line 306 "src/admin.rl" {start(out); show_slab(out); end(out);} goto st7; tr165: -#line 304 "src/admin.rl" +#line 308 "src/admin.rl" {start(out); show_stat(out);end(out);} goto st7; st7: if ( ++p == pe ) goto _test_eof7; case 7: -#line 537 "src/admin.m" +#line 541 "src/admin.cc" if ( (*p) == 10 ) goto st135; goto st0; @@ -686,28 +690,28 @@ case 23: } goto tr33; tr33: -#line 283 "src/admin.rl" +#line 287 "src/admin.rl" {strstart = p;} goto st24; st24: if ( ++p == pe ) goto _test_eof24; case 24: -#line 697 "src/admin.m" +#line 701 "src/admin.cc" switch( (*p) ) { case 10: goto tr36; case 13: goto tr37; } goto st24; tr34: -#line 283 "src/admin.rl" +#line 287 "src/admin.rl" {strstart = p;} goto st25; st25: if ( ++p == pe ) goto _test_eof25; case 25: -#line 711 "src/admin.m" +#line 715 "src/admin.cc" switch( (*p) ) { case 10: goto tr36; case 13: goto tr37; @@ -1157,28 +1161,28 @@ case 73: goto tr91; goto st0; tr91: -#line 291 "src/admin.rl" +#line 295 "src/admin.rl" { strstart = p; } goto st74; st74: if ( ++p == pe ) goto _test_eof74; case 74: -#line 1168 "src/admin.m" +#line 1172 "src/admin.cc" if ( (*p) == 32 ) goto tr92; if ( 33 <= (*p) && (*p) <= 126 ) goto st74; goto st0; tr92: -#line 291 "src/admin.rl" +#line 295 "src/admin.rl" { strend = p; } goto st75; st75: if ( ++p == pe ) goto _test_eof75; case 75: -#line 1182 "src/admin.m" +#line 1186 "src/admin.cc" switch( (*p) ) { case 32: goto st75; case 111: goto st76; @@ -1870,7 +1874,7 @@ case 134: _out: {} } -#line 315 "src/admin.rl" +#line 319 "src/admin.rl" in->pos = pe; @@ -1892,25 +1896,26 @@ admin_handler(va_list ap) struct iobuf *iobuf = va_arg(ap, struct iobuf *); lua_State *L = lua_newthread(tarantool_L); int coro_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX); - @try { - /* - * Admin and iproto connections must have a - * session object, representing the state of - * a remote client: it's used in Lua - * stored procedures. - */ - session_create(coio.fd); - for (;;) { - if (admin_dispatch(&coio, iobuf, L) < 0) - return; - iobuf_gc(iobuf); - fiber_gc(); - } - } @finally { + + auto scoped_guard = make_scoped_guard([&] { luaL_unref(tarantool_L, LUA_REGISTRYINDEX, coro_ref); evio_close(&coio); iobuf_delete(iobuf); session_destroy(fiber->sid); + }); + + /* + * Admin and iproto connections must have a + * session object, representing the state of + * a remote client: it's used in Lua + * stored procedures. + */ + session_create(coio.fd); + for (;;) { + if (admin_dispatch(&coio, iobuf, L) < 0) + return; + iobuf_gc(iobuf); + fiber_gc(); } } diff --git a/src/admin.rl b/src/admin.rl index 5172efcfb6a69dc8a05ac6256c5441add27e9a23..4cccfb31b3ac2220603e85e9328c92f16f038bd6 100644 --- a/src/admin.rl +++ b/src/admin.rl @@ -45,11 +45,15 @@ #include <errinj.h> #include "coio_buf.h" -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" +extern "C" { +#include <lua.h> +#include <lauxlib.h> +#include <lualib.h> +} + #include "box/box.h" #include "session.h" +#include "scoped_guard.h" static const char *help = "available commands:" CRLF @@ -83,7 +87,7 @@ struct salloc_stat_admin_cb_ctx { static int salloc_stat_admin_cb(const struct slab_cache_stats *cstat, void *cb_ctx) { - struct salloc_stat_admin_cb_ctx *ctx = cb_ctx; + struct salloc_stat_admin_cb_ctx *ctx = (struct salloc_stat_admin_cb_ctx *) cb_ctx; tbuf_printf(ctx->out, " - { item_size: %- 5i, slabs: %- 3i, items: %- 11" PRIi64 @@ -159,7 +163,7 @@ tarantool_info(struct tbuf *out) tbuf_printf(out, " lsn: %" PRIi64 CRLF, recovery_state->confirmed_lsn); tbuf_printf(out, " recovery_lag: %.3f" CRLF, - recovery_state->remote ? + recovery_state->remote ? recovery_state->remote->recovery_lag : 0); tbuf_printf(out, " recovery_last_update: %.3f" CRLF, recovery_state->remote ? @@ -174,7 +178,7 @@ tarantool_info(struct tbuf *out) static int show_stat_item(const char *name, int rps, i64 total, void *ctx) { - struct tbuf *buf = ctx; + struct tbuf *buf = (struct tbuf *) ctx; int name_len = strlen(name); tbuf_printf(buf, " %s:%*s{ rps: %- 6i, total: %- 12" PRIi64 " }" CRLF, @@ -200,7 +204,7 @@ admin_dispatch(struct ev_io *coio, struct iobuf *iobuf, lua_State *L) char *strstart, *strend; bool state; - while ((pe = memchr(in->pos, '\n', in->end - in->pos)) == NULL) { + while ((pe = (char *) memchr(in->pos, '\n', in->end - in->pos)) == NULL) { if (coio_bread(coio, in, 1) <= 0) return -1; } @@ -309,7 +313,7 @@ admin_dispatch(struct ev_io *coio, struct iobuf *iobuf, lua_State *L) check " "+ slab %{slab_validate(); ok(out);} | reload " "+ configuration %reload_configuration); - main := commands eol; + main := commands eol; write init; write exec; }%% @@ -333,25 +337,26 @@ admin_handler(va_list ap) struct iobuf *iobuf = va_arg(ap, struct iobuf *); lua_State *L = lua_newthread(tarantool_L); int coro_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX); - @try { - /* - * Admin and iproto connections must have a - * session object, representing the state of - * a remote client: it's used in Lua - * stored procedures. - */ - session_create(coio.fd); - for (;;) { - if (admin_dispatch(&coio, iobuf, L) < 0) - return; - iobuf_gc(iobuf); - fiber_gc(); - } - } @finally { + + auto scoped_guard = make_scoped_guard([&] { luaL_unref(tarantool_L, LUA_REGISTRYINDEX, coro_ref); evio_close(&coio); iobuf_delete(iobuf); session_destroy(fiber->sid); + }); + + /* + * Admin and iproto connections must have a + * session object, representing the state of + * a remote client: it's used in Lua + * stored procedures. + */ + session_create(coio.fd); + for (;;) { + if (admin_dispatch(&coio, iobuf, L) < 0) + return; + iobuf_gc(iobuf); + fiber_gc(); } } diff --git a/src/assoc.m b/src/assoc.cc similarity index 100% rename from src/assoc.m rename to src/assoc.cc diff --git a/src/box/CMakeLists.txt b/src/box/CMakeLists.txt index a01ab0354125f4a9e7ed31c58a046cd98adf76d9..bed63be8447d271d5dcbd0a175dbadc99d4cee58 100644 --- a/src/box/CMakeLists.txt +++ b/src/box/CMakeLists.txt @@ -28,8 +28,8 @@ add_custom_target(generate_lua_sources} DEPENDS ${lua_sources}) set_property(DIRECTORY PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${lua_sources}) -tarantool_module("box" tuple.m index.m hash_index.m tree_index.m space.m - port.m request.m txn.m box.m ${lua_sources} box_lua.m box_lua_space.m - bitset_index.m) +tarantool_module("box" tuple.cc index.cc hash_index.cc tree_index.cc space.cc + port.cc request.cc txn.cc box.cc ${lua_sources} box_lua.cc box_lua_space.cc + bitset_index.cc) target_link_libraries(tarantool_box bitset) diff --git a/src/box/bitset_index.m b/src/box/bitset_index.cc similarity index 67% rename from src/box/bitset_index.m rename to src/box/bitset_index.cc index b4ee44723469599d3600a4cc5ca14d81d3b920ae..82e9ecedcef29932aaf88f1a271d8e95afb046d6 100644 --- a/src/box/bitset_index.m +++ b/src/box/bitset_index.cc @@ -39,7 +39,7 @@ #include <lib/bitset/index.h> static struct index_traits bitset_index_traits = { - .allows_partial_key = false, + /* .allows_partial_key = */ false, }; static inline size_t @@ -53,7 +53,7 @@ tuple_to_value(struct tuple *tuple) static inline struct tuple * value_to_tuple(size_t value) { - return salloc_ptr_from_index(value); + return (struct tuple *) salloc_ptr_from_index(value); } struct bitset_index_iterator { @@ -90,86 +90,85 @@ bitset_index_iterator_next(struct iterator *iterator) return value_to_tuple(value); } -@implementation BitsetIndex; - -+ (struct index_traits *) traits +BitsetIndex::BitsetIndex(struct key_def *key_def, struct space *space) + : Index(key_def, space) { - return &bitset_index_traits; -} - -- (id) init: (struct key_def *) key_def_arg :(struct space *) space_arg -{ - assert (!key_def_arg->is_unique); - - self = [super init: key_def_arg :space_arg]; - assert (self != NULL); + assert (!key_def->is_unique); - if (bitset_index_create(&self->index, realloc) != 0) + if (bitset_index_create(&index, realloc) != 0) panic_syserror("bitset_index_create"); - - return self; } -- (void) free +BitsetIndex::~BitsetIndex() { - bitset_index_destroy(&self->index); - [super free]; + bitset_index_destroy(&index); } -- (void) beginBuild +void +BitsetIndex::beginBuild() { - tnt_raise(ClientError, :ER_UNSUPPORTED, "BitsetIndex", "beginBuild()"); + tnt_raise(ClientError, ER_UNSUPPORTED, "BitsetIndex", "beginBuild()"); } -- (void) buildNext: (struct tuple *)tuple +void +BitsetIndex::buildNext(struct tuple *tuple) { (void) tuple; - tnt_raise(ClientError, :ER_UNSUPPORTED, "BitsetIndex", "buildNext()"); + tnt_raise(ClientError, ER_UNSUPPORTED, "BitsetIndex", "buildNext()"); } -- (void) endBuild +void +BitsetIndex::endBuild() { - tnt_raise(ClientError, :ER_UNSUPPORTED, "BitsetIndex", "endBuild()"); + tnt_raise(ClientError, ER_UNSUPPORTED, "BitsetIndex", "endBuild()"); } -- (void) build: (Index *) pk +void +BitsetIndex::build(Index *pk) { assert (!key_def->is_unique); - struct iterator *it = pk->position; + struct iterator *it = pk->primaryIterator(); struct tuple *tuple; - [pk initIterator: it :ITER_ALL :NULL :0]; + pk->initIterator(it, ITER_ALL, NULL, 0); while ((tuple = it->next(it))) - [self replace: NULL :tuple :DUP_INSERT]; + replace(NULL, tuple, DUP_INSERT); } -- (size_t) size +size_t +BitsetIndex::size() const { - return bitset_index_size(&self->index); + return bitset_index_size(&index); } -- (struct tuple *) min +struct tuple * +BitsetIndex::min() const { - tnt_raise(ClientError, :ER_UNSUPPORTED, "BitsetIndex", "min()"); + tnt_raise(ClientError, ER_UNSUPPORTED, "BitsetIndex", "min()"); return NULL; } -- (struct tuple *) max +struct tuple * +BitsetIndex::max() const { - tnt_raise(ClientError, :ER_UNSUPPORTED, "BitsetIndex", "max()"); + tnt_raise(ClientError, ER_UNSUPPORTED, "BitsetIndex", "max()"); return NULL; } -- (struct tuple *) random +struct tuple * +BitsetIndex::random(u32 rnd) const { - tnt_raise(ClientError, :ER_UNSUPPORTED, "BitsetIndex", "random()"); + (void) rnd; + tnt_raise(ClientError, ER_UNSUPPORTED, "BitsetIndex", "random()"); return NULL; } -- (struct iterator *) allocIterator +struct iterator * +BitsetIndex::allocIterator() const { - struct bitset_index_iterator *it = malloc(sizeof(*it)); + struct bitset_index_iterator *it = (struct bitset_index_iterator *) + malloc(sizeof(*it)); if (!it) return NULL; @@ -182,38 +181,40 @@ bitset_index_iterator_next(struct iterator *iterator) return (struct iterator *) it; } -- (struct tuple *) findByKey: (const void *) key :(u32) part_count +struct tuple * +BitsetIndex::findByKey(const void *key, u32 part_count) const { (void) key; (void) part_count; - tnt_raise(ClientError, :ER_UNSUPPORTED, "BitsetIndex", "findByKey()"); + tnt_raise(ClientError, ER_UNSUPPORTED, "BitsetIndex", "findByKey()"); return NULL; } -- (struct tuple *) findByTuple: (struct tuple *) tuple +struct tuple * +BitsetIndex::findByTuple(struct tuple *tuple) const { (void) tuple; - tnt_raise(ClientError, :ER_UNSUPPORTED, "BitsetIndex", "findByTuple()"); + tnt_raise(ClientError, ER_UNSUPPORTED, "BitsetIndex", "findByTuple()"); return NULL; } -- (struct tuple *) replace: (struct tuple *) old_tuple - : (struct tuple *) new_tuple - : (enum dup_replace_mode) flags +struct tuple * +BitsetIndex::replace(struct tuple *old_tuple, struct tuple *new_tuple, + enum dup_replace_mode mode) { assert(!key_def->is_unique); assert(old_tuple != NULL || new_tuple != NULL); - (void) flags; + (void) mode; struct tuple *ret = NULL; if (old_tuple != NULL) { size_t value = tuple_to_value(old_tuple); - if (bitset_index_contains_value(&self->index, value)) { + if (bitset_index_contains_value(&index, value)) { ret = old_tuple; assert (old_tuple != new_tuple); - bitset_index_remove_value(&self->index, value); + bitset_index_remove_value(&index, value); } } @@ -225,9 +226,9 @@ bitset_index_iterator_next(struct iterator *iterator) const void *bitset_key = field; size_t value = tuple_to_value(new_tuple); - if (bitset_index_insert(&self->index, bitset_key, + if (bitset_index_insert(&index, bitset_key, bitset_key_size, value) < 0) { - tnt_raise(ClientError, :ER_MEMORY_ISSUE, 0, + tnt_raise(ClientError, ER_MEMORY_ISSUE, 0, "BitsetIndex", "insert"); } } @@ -235,8 +236,9 @@ bitset_index_iterator_next(struct iterator *iterator) return ret; } -- (void) initIterator: (struct iterator *) iterator:(enum iterator_type) type - :(const void *) key :(u32) part_count +void +BitsetIndex::initIterator(struct iterator *iterator, enum iterator_type type, + const void *key, u32 part_count) const { assert(iterator->free == bitset_index_iterator_free); struct bitset_index_iterator *it = bitset_index_iterator(iterator); @@ -254,7 +256,7 @@ bitset_index_iterator_next(struct iterator *iterator) struct bitset_expr expr; bitset_expr_create(&expr, realloc); - @try { + try { int rc = 0; switch (type) { case ITER_ALL: @@ -277,23 +279,27 @@ bitset_index_iterator_next(struct iterator *iterator) bitset_key_size); break; default: - tnt_raise(ClientError, :ER_UNSUPPORTED, + tnt_raise(ClientError, ER_UNSUPPORTED, "BitsetIndex", "requested iterator type"); } if (rc != 0) { - tnt_raise(ClientError, :ER_MEMORY_ISSUE, + tnt_raise(ClientError, ER_MEMORY_ISSUE, 0, "BitsetIndex", "iterator expression"); } - if (bitset_index_init_iterator(&self->index, &it->bitset_it, + /* TODO: fix bitset_index_init_iterator to work with const obj*/ + if (bitset_index_init_iterator((bitset_index *) &index, + &it->bitset_it, &expr) != 0) { - tnt_raise(ClientError, :ER_MEMORY_ISSUE, + tnt_raise(ClientError, ER_MEMORY_ISSUE, 0, "BitsetIndex", "iterator state"); } - } @finally { + + bitset_expr_destroy(&expr); + } catch(const Exception& e) { bitset_expr_destroy(&expr); + throw; } } -@end diff --git a/src/box/bitset_index.h b/src/box/bitset_index.h index fbaf074409b3253a72dc96a24f02078591f2f5f8..b36909ce7bcffb3082c3b065f47ee06375e5e3b1 100644 --- a/src/box/bitset_index.h +++ b/src/box/bitset_index.h @@ -41,10 +41,31 @@ struct bitset_index; struct bitset_expr; -@interface BitsetIndex: Index { - @private +class BitsetIndex: public Index { +public: + BitsetIndex(struct key_def *key_def, struct space *space); + virtual ~BitsetIndex(); + + virtual void beginBuild(); + virtual void buildNext(struct tuple *tuple); + virtual void endBuild(); + virtual void build(Index *pk); + virtual size_t size() const; + virtual struct tuple *min() const; + virtual struct tuple *max() const; + virtual struct tuple *random(u32 rnd) const; + virtual struct tuple *findByKey(const void *key, u32 part_count) const; + virtual struct tuple *findByTuple(struct tuple *tuple) const; + virtual struct tuple *replace(struct tuple *old_tuple, + struct tuple *new_tuple, + enum dup_replace_mode mode); + + virtual struct iterator *allocIterator() const; + virtual void initIterator(struct iterator *iterator, + enum iterator_type type, + const void *key, u32 part_count) const; +private: struct bitset_index index; -} -@end +}; #endif /* TARANTOOL_BOX_INDEX_BITSET_H_INCLUDED */ diff --git a/src/box/box.m b/src/box/box.cc similarity index 87% rename from src/box/box.m rename to src/box/box.cc index b4e5ed11740c65f596c35617053fe4f3bab1d529..1e46786a1d996de6d71597f5d7f9d016d5397795 100644 --- a/src/box/box.m +++ b/src/box/box.cc @@ -29,7 +29,11 @@ #include "box/box.h" #include <arpa/inet.h> +extern "C" { #include <cfg/warning.h> +#include <cfg/tarantool_box_cfg.h> +} /* extern "C" */ + #include <errcode.h> #include "palloc.h" #include <recovery.h> @@ -38,8 +42,6 @@ #include <say.h> #include <stat.h> #include <tarantool.h> - -#include <cfg/tarantool_box_cfg.h> #include "tuple.h" #include "memcached.h" #include "box_lua.h" @@ -81,7 +83,7 @@ process_rw(struct port *port, u32 op, const void *reqdata, u32 reqlen) { struct txn *txn = txn_begin(); - @try { + try { struct request *request = request_create(op, reqdata, reqlen); stat_collect(stat_base, op, 1); request_execute(request, txn, port); @@ -89,9 +91,9 @@ process_rw(struct port *port, u32 op, const void *reqdata, u32 reqlen) port_send_tuple(port, txn, request->flags); port_eof(port); txn_finish(txn); - } @catch (id e) { + } catch (const Exception& e) { txn_rollback(txn); - @throw; + throw; } } @@ -99,7 +101,7 @@ static void process_replica(struct port *port, u32 op, const void *reqdata, u32 reqlen) { if (!request_is_select(op)) { - tnt_raise(ClientError, :ER_NONMASTER, + tnt_raise(ClientError, ER_NONMASTER, cfg.replication_source); } return process_rw(port, op, reqdata, reqlen); @@ -109,7 +111,7 @@ static void process_ro(struct port *port, u32 op, const void *reqdata, u32 reqlen) { if (!request_is_select(op)) - tnt_raise(LoggedError, :ER_SECONDARY); + tnt_raise(LoggedError, ER_SECONDARY); return process_rw(port, op, reqdata, reqlen); } @@ -118,7 +120,7 @@ recover_snap_row(const void *data) { assert(primary_indexes_enabled == false); - const struct box_snap_row *row = data; + const struct box_snap_row *row = (const struct box_snap_row *) data; struct tuple *tuple = tuple_alloc(row->data_size); memcpy(tuple->data, row->data, row->data_size); @@ -128,9 +130,9 @@ recover_snap_row(const void *data) Index *index = space_index(space, 0); /* Check to see if the tuple has a sufficient number of fields. */ if (unlikely(tuple->field_count < space->max_fieldno)) { - tnt_raise(IllegalParams, :"tuple must have all indexed fields"); + tnt_raise(IllegalParams, "tuple must have all indexed fields"); } - [index buildNext: tuple]; + index->buildNext(tuple); tuple_ref(tuple, 1); } @@ -144,7 +146,7 @@ recover_row(void *param __attribute__((unused)), struct tbuf *t) return -1; } - @try { + try { const void *data = t->data; const void *end = t->data + t->size; u16 tag = pick_u16(&data, end); @@ -153,15 +155,14 @@ recover_row(void *param __attribute__((unused)), struct tbuf *t) recover_snap_row(data); } else if (tag == XLOG) { u16 op = pick_u16(&data, end); - process_rw(&port_null, op, data, end - data); + process_rw(&port_null, op, data, + (const char *) end - (const char *) data); } else { say_error("unknown row tag: %i", (int)tag); return -1; } - } @catch (tnt_Exception *e) { - [e log]; - return -1; - } @catch (id e) { + } catch (const Exception& e) { + e.log(); return -1; } @@ -210,7 +211,7 @@ box_check_config(struct tarantool_cfg *conf) { /* replication & hot standby modes can not work together */ if (conf->replication_source != NULL && conf->local_hot_standby > 0) { - out_warning(0, "replication and local hot standby modes " + out_warning(CNF_OK, "replication and local hot standby modes " "can't be enabled simultaneously"); return -1; } @@ -223,11 +224,11 @@ box_check_config(struct tarantool_cfg *conf) if (sscanf(conf->replication_source, "%31[^:]:%i", ip_addr, &port) != 2) { - out_warning(0, "replication source IP address is not recognized"); + out_warning(CNF_OK, "replication source IP address is not recognized"); return -1; } if (port <= 0 || port >= USHRT_MAX) { - out_warning(0, "invalid replication source port value: %i", port); + out_warning(CNF_OK, "invalid replication source port value: %i", port); return -1; } } @@ -235,20 +236,20 @@ box_check_config(struct tarantool_cfg *conf) /* check primary port */ if (conf->primary_port != 0 && (conf->primary_port <= 0 || conf->primary_port >= USHRT_MAX)) { - out_warning(0, "invalid primary port value: %i", conf->primary_port); + out_warning(CNF_OK, "invalid primary port value: %i", conf->primary_port); return -1; } /* check secondary port */ if (conf->secondary_port != 0 && (conf->secondary_port <= 0 || conf->secondary_port >= USHRT_MAX)) { - out_warning(0, "invalid secondary port value: %i", conf->primary_port); + out_warning(CNF_OK, "invalid secondary port value: %i", conf->primary_port); return -1; } /* check if at least one space is defined */ if (conf->space == NULL && conf->memcached_port == 0) { - out_warning(0, "at least one space or memcached port must be defined"); + out_warning(CNF_OK, "at least one space or memcached port must be defined"); return -1; } @@ -276,7 +277,7 @@ box_reload_config(struct tarantool_cfg *old_conf, struct tarantool_cfg *new_conf (strcmp(old_conf->replication_source, new_conf->replication_source) != 0))) { if (recovery_state->finalize != true) { - out_warning(0, "Could not propagate %s before local recovery finished", + out_warning(CNF_OK, "Could not propagate %s before local recovery finished", old_is_replica == true ? "slave to master" : "master to slave"); @@ -358,14 +359,19 @@ snapshot_write_tuple(struct log_io *l, struct fio_batch *batch, } +struct snapshot_space_param { + struct log_io *l; + struct fio_batch *batch; +}; + static void snapshot_space(struct space *sp, void *udata) { struct tuple *tuple; - struct { struct log_io *l; struct fio_batch *batch; } *ud = udata; + struct snapshot_space_param *ud = (struct snapshot_space_param *) udata; Index *pk = space_index(sp, 0); - struct iterator *it = pk->position; - [pk initIterator: it :ITER_ALL :NULL :0]; + struct iterator *it = pk->primaryIterator();; + pk->initIterator(it, ITER_ALL, NULL, 0); while ((tuple = it->next(it))) snapshot_write_tuple(ud->l, ud->batch, space_n(sp), tuple); @@ -378,7 +384,7 @@ box_snapshot(struct log_io *l, struct fio_batch *batch) if (primary_indexes_enabled == false) return; - struct { struct log_io *l; struct fio_batch *batch; } ud = { l, batch }; + struct snapshot_space_param ud = { l, batch }; space_foreach(snapshot_space, &ud); } diff --git a/src/box/box_lua.m b/src/box/box_lua.cc similarity index 91% rename from src/box/box_lua.m rename to src/box/box_lua.cc index f62d946a7a2d8d48a2c14280f87d9ba0676e0140..9c5a286e9405f0e2b02680cd8b3b81732d45ce9b 100644 --- a/src/box/box_lua.m +++ b/src/box/box_lua.cc @@ -33,19 +33,22 @@ #include "request.h" #include "txn.h" -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" -#include "lj_obj.h" -#include "lj_ctype.h" -#include "lj_cdata.h" -#include "lj_cconv.h" +extern "C" { +#include <lua.h> +#include <lauxlib.h> +#include <lualib.h> +#include <lj_obj.h> +#include <lj_ctype.h> +#include <lj_cdata.h> +#include <lj_cconv.h> +} /* extern "C" */ #include "pickle.h" #include "tuple.h" #include "space.h" #include "port.h" #include "tbuf.h" +#include "scoped_guard.h" /* contents of box.lua, misc.lua, box.net.lua respectively */ extern char box_lua[], box_net_lua[], misc_lua[]; @@ -87,7 +90,7 @@ lua_totuple(struct lua_State *L, int index); static inline struct tuple * lua_checktuple(struct lua_State *L, int narg) { - struct tuple *t = *(void **) luaL_checkudata(L, narg, tuplelib_name); + struct tuple *t = *(struct tuple **) luaL_checkudata(L, narg, tuplelib_name); assert(t->refs); return t; } @@ -100,7 +103,7 @@ lua_istuple(struct lua_State *L, int narg) luaL_getmetatable(L, tuplelib_name); struct tuple *tuple = 0; if (lua_equal(L, -1, -2)) - tuple = * (void **) lua_touserdata(L, narg); + tuple = *(struct tuple **) lua_touserdata(L, narg); lua_pop(L, 2); return tuple; } @@ -161,12 +164,12 @@ lbox_tuple_slice(struct lua_State *L) if (end <= start) luaL_error(L, "tuple.slice(): start must be less than end"); - const void *field = tuple->data; + const char *field = (const char *) tuple->data; u32 fieldno = 0; u32 stop = end - 1; - while (field < (const void *) tuple->data + tuple->bsize) { - size_t len = load_varint32(&field); + while (field < (const char *) tuple->data + tuple->bsize) { + size_t len = load_varint32((const void **) &field); if (fieldno >= start) { lua_pushlstring(L, field, len); if (fieldno == stop) @@ -230,7 +233,7 @@ transform_calculate(struct lua_State *L, struct tuple *tuple, tuple_range_size(&tuple_field, tuple_end, len); /* calculate last part of the tuple fields */ - lr[1] = tuple_end - tuple_field; + lr[1] = (const char *) tuple_end - (const char *) tuple_field; return lr[0] + mid + lr[1]; } @@ -327,9 +330,9 @@ tuple_find(struct lua_State *L, struct tuple *tuple, size_t offset, int idx = offset; if (idx >= tuple->field_count) return 0; - const void *field = tuple_field(tuple, idx); - while (field < (const void *) tuple->data + tuple->bsize) { - size_t len = load_varint32(&field); + const char *field = (const char *) tuple_field(tuple, idx); + while (field < (const char *) tuple->data + tuple->bsize) { + size_t len = load_varint32((const void **) &field); if (len == key_size && (memcmp(field, key, len) == 0)) { lua_pushinteger(L, idx); if (!all) @@ -397,10 +400,10 @@ lbox_tuple_unpack(struct lua_State *L) struct tuple *tuple = lua_checktuple(L, 1); const void *field = tuple->data; - while (field < (const void *) tuple->data + tuple->bsize) { + while (field < (const char *) tuple->data + tuple->bsize) { size_t len = load_varint32(&field); - lua_pushlstring(L, field, len); - field += len; + lua_pushlstring(L, (const char *) field, len); + field = (const char *) field + len; } assert(lua_gettop(L) == tuple->field_count + 1); return tuple->field_count; @@ -413,12 +416,12 @@ lbox_tuple_totable(struct lua_State *L) lua_newtable(L); int index = 1; const void *field = tuple->data; - while (field < (const void *) tuple->data + tuple->bsize) { + while (field < (const char *) tuple->data + tuple->bsize) { size_t len = load_varint32(&field); lua_pushnumber(L, index++); - lua_pushlstring(L, field, len); + lua_pushlstring(L, (const char *) field, len); lua_rawset(L, -3); - field += len; + field = (const char *) field + len; } return 1; } @@ -442,7 +445,7 @@ lbox_tuple_index(struct lua_State *L) tuplelib_name, i, tuple->field_count-1); const void *field = tuple_field(tuple, i); u32 len = load_varint32(&field); - lua_pushlstring(L, field, len); + lua_pushlstring(L, (const char *) field, len); return 1; } /* If we got a string, try to find a method for it. */ @@ -467,7 +470,8 @@ static void lbox_pushtuple(struct lua_State *L, struct tuple *tuple) { if (tuple) { - void **ptr = lua_newuserdata(L, sizeof(void *)); + struct tuple **ptr = (struct tuple **) + lua_newuserdata(L, sizeof(void *)); luaL_getmetatable(L, tuplelib_name); lua_setmetatable(L, -2); *ptr = tuple; @@ -499,10 +503,10 @@ lbox_tuple_next(struct lua_State *L) (void)field; assert(field >= (const void *) tuple->data); - if (field < (const void *) tuple->data + tuple->bsize) { + if (field < (const char *) tuple->data + tuple->bsize) { len = load_varint32(&field); - lua_pushlightuserdata(L, (void *) field + len); - lua_pushlstring(L, field, len); + lua_pushlightuserdata(L, (char *) field + len); + lua_pushlstring(L, (char *) field, len); return 2; } lua_pushnil(L); @@ -566,28 +570,33 @@ static const char *iteratorlib_name = "box.index.iterator"; static struct iterator * lbox_checkiterator(struct lua_State *L, int i) { - struct iterator **it = luaL_checkudata(L, i, iteratorlib_name); + struct iterator **it = (struct iterator **) + luaL_checkudata(L, i, iteratorlib_name); assert(it != NULL); return *it; } + + static void lbox_pushiterator(struct lua_State *L, Index *index, - struct iterator *it, enum iterator_type type, - const void *key, size_t size, int part_count) + struct iterator *it, enum iterator_type type, + const void *key, size_t size, int part_count) { - struct { + struct lbox_iterator_holder { struct iterator *it; char key[]; - } *holder = lua_newuserdata(L, sizeof(void *) + size); + }; + + struct lbox_iterator_holder *holder = (struct lbox_iterator_holder *) + lua_newuserdata(L, sizeof(void *) + size); luaL_getmetatable(L, iteratorlib_name); lua_setmetatable(L, -2); holder->it = it; memcpy(holder->key, key, size); - [index initIterator: it :type :(key ? holder->key : NULL) - :part_count]; + index->initIterator(it, type, (key ? holder->key : NULL), part_count); } static int @@ -601,7 +610,7 @@ lbox_iterator_gc(struct lua_State *L) static Index * lua_checkindex(struct lua_State *L, int i) { - Index **index = luaL_checkudata(L, i, indexlib_name); + Index **index = (Index **) luaL_checkudata(L, i, indexlib_name); assert(index != NULL); return *index; } @@ -616,7 +625,7 @@ lbox_index_new(struct lua_State *L) Index *index = index_find(sp, idx); /* create a userdata object */ - void **ptr = lua_newuserdata(L, sizeof(void *)); + void **ptr = (void **) lua_newuserdata(L, sizeof(void *)); *ptr = index; /* set userdata object metatable to indexlib */ luaL_getmetatable(L, indexlib_name); @@ -638,7 +647,7 @@ static int lbox_index_len(struct lua_State *L) { Index *index = lua_checkindex(L, 1); - lua_pushinteger(L, [index size]); + lua_pushinteger(L, index->size()); return 1; } @@ -654,7 +663,7 @@ static int lbox_index_min(struct lua_State *L) { Index *index = lua_checkindex(L, 1); - lbox_pushtuple(L, [index min]); + lbox_pushtuple(L, index->min()); return 1; } @@ -662,7 +671,7 @@ static int lbox_index_max(struct lua_State *L) { Index *index = lua_checkindex(L, 1); - lbox_pushtuple(L, [index max]); + lbox_pushtuple(L, index->max()); return 1; } @@ -674,7 +683,7 @@ lbox_index_random(struct lua_State *L) Index *index = lua_checkindex(L, 1); u32 rnd = lua_tointeger(L, 2); - lbox_pushtuple(L, [index random: rnd]); + lbox_pushtuple(L, index->random(rnd)); return 1; } @@ -718,8 +727,8 @@ void append_key_part(struct lua_State *L, int i, str = luaL_checklstring(L, i, &size); } char varint_buf[sizeof(u32) + 1]; - size_t pack_len = (pack_varint32(varint_buf, size) - - (void *) varint_buf); + size_t pack_len = ((const char *) pack_varint32(varint_buf, size) - + (const char *) varint_buf); tbuf_append(tbuf, varint_buf, pack_len); tbuf_append(tbuf, str, size); } @@ -770,8 +779,8 @@ lbox_create_iterator(struct lua_State *L) * beginning (ITER_ALL). */ } else { - type = luaL_checkint(L, 2); - if (type >= iterator_type_MAX) + type = (enum iterator_type) luaL_checkint(L, 2); + if (type < ITER_ALL || type >= iterator_type_MAX) luaL_error(L, "unknown iterator type: %d", type); /* What else do we have on the stack? */ if (argc == 2 || (argc == 3 && lua_type(L, 3) == LUA_TNIL)) { @@ -806,9 +815,9 @@ lbox_create_iterator(struct lua_State *L) " is greater than index part count %d", field_count, index->key_def->part_count); } - struct iterator *it = [index allocIterator]; + struct iterator *it = index->allocIterator(); lbox_pushiterator(L, index, it, type, key, key_size, - field_count); + field_count); /* truncate memory used by key construction */ ptruncate(fiber->gc_pool, allocated_size); @@ -914,8 +923,8 @@ lbox_index_count(struct lua_State *L) } u32 count = 0; /* preparing index iterator */ - struct iterator *it = index->position; - [index initIterator: it :ITER_EQ :key :key_part_count]; + struct iterator *it = index->primaryIterator(); + index->initIterator(it, ITER_EQ, key, key_part_count); /* iterating over the index and counting tuples */ struct tuple *tuple; while ((tuple = it->next(it)) != NULL) @@ -979,10 +988,10 @@ port_lua_add_tuple(struct port *port, struct tuple *tuple, u32 flags __attribute__((unused))) { lua_State *L = port_lua(port)->L; - @try { + try { lbox_pushtuple(L, tuple); - } @catch (id allOthers) { - tnt_raise(ClientError, :ER_PROC_LUA, lua_tostring(L, -1)); + } catch (...) { + tnt_raise(ClientError, ER_PROC_LUA, lua_tostring(L, -1)); } } @@ -994,7 +1003,8 @@ struct port_vtab port_lua_vtab = { static struct port * port_lua_create(struct lua_State *L) { - struct port_lua *port = palloc(fiber->gc_pool, sizeof(struct port_lua)); + struct port_lua *port = (struct port_lua *) + palloc(fiber->gc_pool, sizeof(struct port_lua)); port->vtab = &port_lua_vtab; port->L = L; return (struct port *) port; @@ -1044,7 +1054,7 @@ lua_table_to_tuple(struct lua_State *L, int index) break; } default: - tnt_raise(ClientError, :ER_PROC_RET, + tnt_raise(ClientError, ER_PROC_RET, lua_typename(L, lua_type(L, -1))); break; } @@ -1161,7 +1171,7 @@ lua_totuple(struct lua_State *L, int index) /* * LUA_TNONE, LUA_TTABLE, LUA_THREAD, LUA_TFUNCTION */ - tnt_raise(ClientError, :ER_PROC_RET, lua_typename(L, type)); + tnt_raise(ClientError, ER_PROC_RET, lua_typename(L, type)); break; } return tuple; @@ -1171,11 +1181,16 @@ static void port_add_lua_ret(struct port *port, struct lua_State *L, int index) { struct tuple *tuple = lua_totuple(L, index); - @try { + try { port_add_tuple(port, tuple, BOX_RETURN_TUPLE); - } @finally { + if (tuple->refs == 0) tuple_free(tuple); + } catch(...) { + if (tuple->refs == 0) + tuple_free(tuple); + + throw; } } @@ -1261,14 +1276,17 @@ lbox_process(lua_State *L) size_t allocated_size = palloc_allocated(fiber->gc_pool); struct port *port_lua = port_lua_create(L); - @try { + try { box_process(port_lua, op, req, sz); - } @finally { + /* * This only works as long as port_lua doesn't * use fiber->cleanup and fiber->gc_pool. */ ptruncate(fiber->gc_pool, allocated_size); + } catch(const Exception& e) { + ptruncate(fiber->gc_pool, allocated_size); + throw; } return lua_gettop(L) - top; } @@ -1282,7 +1300,7 @@ lbox_raise(lua_State *L) if (!code) luaL_error(L, "box.raise(): unknown error code"); const char *str = lua_tostring(L, 2); - tnt_raise(ClientError, :code :str); + tnt_raise(ClientError, str, code); return 0; } @@ -1296,12 +1314,12 @@ box_lua_find(lua_State *L, const char *name, const char *name_end) int index = LUA_GLOBALSINDEX; const char *start = name, *end; - while ((end = memchr(start, '.', name_end - start))) { + while ((end = (const char *) memchr(start, '.', name_end - start))) { lua_checkstack(L, 3); lua_pushlstring(L, start, end - start); lua_gettable(L, index); if (! lua_istable(L, -1)) - tnt_raise(ClientError, :ER_NO_SUCH_PROC, + tnt_raise(ClientError, ER_NO_SUCH_PROC, name_end - name, name); start = end + 1; /* next piece of a.b.c */ index = lua_gettop(L); /* top of the stack */ @@ -1311,7 +1329,7 @@ box_lua_find(lua_State *L, const char *name, const char *name_end) if (! lua_isfunction(L, -1)) { /* lua_call or lua_gettable would raise a type error * for us, but our own message is more verbose. */ - tnt_raise(ClientError, :ER_NO_SUCH_PROC, + tnt_raise(ClientError, ER_NO_SUCH_PROC, name_end - name, name); } /* setting stack that it would contain only @@ -1348,36 +1366,40 @@ void box_lua_execute(struct request *request, struct port *port) { const void **reqpos = &request->data; - const void *reqend = request->data + request->len; + const void *reqend = (const char *) request->data + request->len; lua_State *L = lua_newthread(root_L); int coro_ref = luaL_ref(root_L, LUA_REGISTRYINDEX); /* Request flags: not used. */ (void) (pick_u32(reqpos, reqend)); - @try { + + try { + auto scoped_guard = make_scoped_guard([=] { + /* + * Allow the used coro to be garbage collected. + * @todo: cache and reuse it instead. + */ + luaL_unref(root_L, LUA_REGISTRYINDEX, coro_ref); + }); + u32 field_len; /* proc name */ const void *field = pick_field_str(reqpos, reqend, &field_len); - box_lua_find(L, field, field + field_len); + box_lua_find(L, (const char *) field, + ((const char *) field + field_len)); /* Push the rest of args (a tuple). */ u32 nargs = pick_u32(reqpos, reqend); luaL_checkstack(L, nargs, "call: out of stack"); for (int i = 0; i < nargs; i++) { field = pick_field_str(reqpos, reqend, &field_len); - lua_pushlstring(L, field, field_len); + lua_pushlstring(L, (const char *) field, field_len); } lua_call(L, nargs, LUA_MULTRET); /* Send results of the called procedure to the client. */ port_add_lua_multret(port, L); - } @catch (tnt_Exception *e) { - @throw; - } @catch (id allOthers) { - tnt_raise(ClientError, :ER_PROC_LUA, lua_tostring(L, -1)); - } @finally { - /* - * Allow the used coro to be garbage collected. - * @todo: cache and reuse it instead. - */ - luaL_unref(root_L, LUA_REGISTRYINDEX, coro_ref); + } catch (const Exception& e) { + throw; + } catch (...) { + tnt_raise(ClientError, ER_PROC_LUA, lua_tostring(L, -1)); } } @@ -1399,7 +1421,7 @@ static void luaL_addvarint32(luaL_Buffer *b, u32 value) { char buf[sizeof(u32)+1]; - char *bufend = pack_varint32(buf, value); + char *bufend = (char *) pack_varint32(buf, value); luaL_addlstring(b, buf, bufend - buf); } @@ -1706,9 +1728,9 @@ lbox_unpack(struct lua_State *L) const char *f = format; size_t str_size = 0; - const void *str = luaL_checklstring(L, 2, &str_size); - const void *end = str + str_size; - const void *s = str; + const char *str = luaL_checklstring(L, 2, &str_size); + const char *end = (const char *) str + str_size; + const char *s = str; int save_stacksize = lua_gettop(L); @@ -1748,7 +1770,7 @@ lbox_unpack(struct lua_State *L) break; case 'w': /* pick_varint32 throws exception on error. */ - u32buf = pick_varint32(&s, end); + u32buf = pick_varint32((const void **) &s, end); lua_pushnumber(L, u32buf); break; @@ -1760,7 +1782,7 @@ lbox_unpack(struct lua_State *L) case 'P': case 'p': /* pick_varint32 throws exception on error. */ - u32buf = pick_varint32(&s, end); + u32buf = pick_varint32((const void **) &s, end); CHECK_SIZE(s + u32buf - 1); lua_pushlstring(L, (const char *) s, u32buf); s += u32buf; diff --git a/src/box/box_lua_space.m b/src/box/box_lua_space.cc similarity index 93% rename from src/box/box_lua_space.m rename to src/box/box_lua_space.cc index a86fef2bb90e16e739bd138b88e81b2911e3bdc0..e70722f8565cb4d4054f47de42ba0b967e185525 100644 --- a/src/box/box_lua_space.m +++ b/src/box/box_lua_space.cc @@ -27,10 +27,14 @@ * SUCH DAMAGE. */ #include "box_lua_space.h" + +extern "C" { +#include <lua.h> +#include <lauxlib.h> +#include <lualib.h> +} /* extern "C" */ + #include "space.h" -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" #include <say.h> /** @@ -145,6 +149,12 @@ lbox_add_space(struct space *space, struct lua_State *L) lua_settable(L, -3); } +static void +lbox_add_space_wrapper(struct space *space, void *param) +{ + lbox_add_space(space, (struct lua_State *) param); +} + /** * Make all spaces available in Lua via box.space * array. @@ -155,7 +165,7 @@ box_lua_load_cfg(struct lua_State *L) lua_getfield(L, LUA_GLOBALSINDEX, "box"); lua_pushstring(L, "space"); lua_newtable(L); - space_foreach((void *)lbox_add_space, L); /* fill box.space */ + space_foreach(lbox_add_space_wrapper, L); /* fill box.space */ lua_settable(L, -3); lua_pop(L, 1); assert(lua_gettop(L) == 0); diff --git a/src/box/hash_index.m b/src/box/hash_index.cc similarity index 63% rename from src/box/hash_index.m rename to src/box/hash_index.cc index 17ef9bcb3209782e5205c1a1c8cc5533f032db0e..159e25fd64138fe960ab3ae743e8db337c52ac57 100644 --- a/src/box/hash_index.m +++ b/src/box/hash_index.cc @@ -36,7 +36,7 @@ #include "errinj.h" static struct index_traits hash_index_traits = { - .allows_partial_key = false, + /* .allows_partial_key = */ false, }; /* {{{ HashIndex Iterators ****************************************/ @@ -74,7 +74,7 @@ hash_iterator_i32_ge(struct iterator *ptr) while (it->h_pos < mh_end(it->hash)) { if (mh_exist(it->hash, it->h_pos)) - return mh_i32ptr_node(it->hash, it->h_pos++)->val; + return (struct tuple *) mh_i32ptr_node(it->hash, it->h_pos++)->val; it->h_pos++; } return NULL; @@ -88,7 +88,8 @@ hash_iterator_i64_ge(struct iterator *ptr) while (it->h_pos < mh_end(it->hash)) { if (mh_exist(it->hash, it->h_pos)) - return mh_i64ptr_node(it->hash, it->h_pos++)->val; + return (struct tuple *) mh_i64ptr_node( + it->hash,it->h_pos++)->val; it->h_pos++; } return NULL; @@ -102,7 +103,8 @@ hash_iterator_lstr_ge(struct iterator *ptr) while (it->h_pos < mh_end(it->hash)) { if (mh_exist(it->hash, it->h_pos)) - return mh_lstrptr_node(it->hash, it->h_pos++)->val; + return (struct tuple *) mh_lstrptr_node( + it->hash,it->h_pos++)->val; it->h_pos++; } return NULL; @@ -139,48 +141,112 @@ hash_iterator_lstr_eq(struct iterator *it) /* {{{ HashIndex -- base class for all hashes. ********************/ -@interface Hash32Index: HashIndex { - struct mh_i32ptr_t *int_hash; +class Hash32Index: public HashIndex { +public: + Hash32Index(struct key_def *key_def, struct space *space); + ~Hash32Index(); + + virtual size_t + size() const; + + virtual struct tuple * + random(u32 rnd) const; + + virtual struct tuple * + findByKey(const void *key, u32 part_count) const; + + virtual struct tuple * + replace(struct tuple *old_tuple, struct tuple *new_tuple, + enum dup_replace_mode mode); + + struct iterator * + allocIterator() const; + + void + initIterator(struct iterator *iterator, enum iterator_type type, + const void *key, u32 part_count) const; + + virtual void + reserve(u32 n_tuples); +private: + struct mh_i32ptr_t *int_hash; }; -- (id) init: (struct key_def *) key_def_arg :(struct space *) space_arg; -@end +class Hash64Index: public HashIndex { +public: + Hash64Index(struct key_def *key_def, struct space *space); + ~Hash64Index(); + + virtual size_t + size() const; + + virtual struct tuple * + random(u32 rnd) const; + + virtual struct tuple * + findByKey(const void *key, u32 part_count) const; + + virtual struct tuple * + replace(struct tuple *old_tuple, struct tuple *new_tuple, + enum dup_replace_mode mode); -@interface Hash64Index: HashIndex { + struct iterator * + allocIterator() const; + + void + initIterator(struct iterator *iterator, enum iterator_type type, + const void *key, u32 part_count) const; + + virtual void + reserve(u32 n_tuples); +private: struct mh_i64ptr_t *int64_hash; }; -- (id) init: (struct key_def *) key_def_arg :(struct space *) space_arg; -@end +class HashStrIndex: public HashIndex { +public: + HashStrIndex(struct key_def *key_def, struct space *space); + ~HashStrIndex(); -@interface HashStrIndex: HashIndex { - struct mh_lstrptr_t *str_hash; -}; + virtual size_t + size() const; -- (id) init: (struct key_def *) key_def_arg :(struct space *) space_arg; -@end + virtual struct tuple * + random(u32 rnd) const; -@implementation HashIndex + virtual struct tuple * + findByKey(const void *key, u32 part_count) const; -+ (struct index_traits *) traits -{ - return &hash_index_traits; -} + virtual struct tuple * + replace(struct tuple *old_tuple, struct tuple *new_tuple, + enum dup_replace_mode mode); -+ (HashIndex *) alloc: (struct key_def *) key_def :(struct space *) space -{ - (void) space; + struct iterator * + allocIterator() const; + + void + initIterator(struct iterator *iterator, enum iterator_type type, + const void *key, u32 part_count) const; + + virtual void + reserve(u32 n_tuples); +private: + struct mh_lstrptr_t *str_hash; +}; +HashIndex * +HashIndex::factory(struct key_def *key_def, struct space *space) +{ /* * Hash index always has a single-field key. */ switch (key_def->parts[0].type) { case NUM: - return [Hash32Index alloc]; /* 32-bit integer hash */ + return new Hash32Index(key_def, space); /* 32-bit integer hash */ case NUM64: - return [Hash64Index alloc]; /* 64-bit integer hash */ + return new Hash64Index(key_def, space); /* 64-bit integer hash */ case STRING: - return [HashStrIndex alloc]; /* string hash */ + return new HashStrIndex(key_def, space); /* string hash */ default: assert(false); } @@ -188,75 +254,75 @@ hash_iterator_lstr_eq(struct iterator *it) return NULL; } -- (void) reserve: (u32) n_tuples +HashIndex::HashIndex(struct key_def *key_def, struct space *space) + : Index(key_def, space) { - (void) n_tuples; - [self subclassResponsibility: _cmd]; + /* Nothing */ } -- (void) beginBuild +void +HashIndex::beginBuild() { } -- (void) buildNext: (struct tuple *)tuple +void +HashIndex::buildNext(struct tuple *tuple) { - [self replace: NULL :tuple :DUP_INSERT]; + replace(NULL, tuple, DUP_INSERT); } -- (void) endBuild +void +HashIndex::endBuild() { } -- (void) build: (Index *) pk +void +HashIndex::build(Index *pk) { - u32 n_tuples = [pk size]; + u32 n_tuples = pk->size(); if (n_tuples == 0) return; - [self reserve: n_tuples]; + reserve(n_tuples); - say_info("Adding %"PRIu32 " keys to HASH index %" - PRIu32 "...", n_tuples, index_n(self)); + say_info("Adding %" PRIu32 " keys to HASH index %" + PRIu32 "...", n_tuples, index_n(this)); - struct iterator *it = pk->position; + struct iterator *it = pk->primaryIterator(); struct tuple *tuple; - [pk initIterator: it :ITER_ALL :NULL :0]; + pk->initIterator(it, ITER_ALL, NULL, 0); while ((tuple = it->next(it))) - [self replace: NULL :tuple :DUP_INSERT]; + replace(NULL, tuple, DUP_INSERT); } -- (void) free -{ - [super free]; -} - -- (struct tuple *) min +struct tuple * +HashIndex::min() const { - tnt_raise(ClientError, :ER_UNSUPPORTED, "Hash index", "min()"); + tnt_raise(ClientError, ER_UNSUPPORTED, "Hash index", "min()"); return NULL; } -- (struct tuple *) max +struct tuple * +HashIndex::max() const { - tnt_raise(ClientError, :ER_UNSUPPORTED, "Hash index", "max()"); + tnt_raise(ClientError, ER_UNSUPPORTED, "Hash index", "max()"); return NULL; } -- (struct tuple *) findByTuple: (struct tuple *) tuple +struct tuple * +HashIndex::findByTuple(struct tuple *tuple) const { assert(key_def->is_unique); if (tuple->field_count < key_def->max_fieldno) - tnt_raise(IllegalParams, :"tuple must have all indexed fields"); + tnt_raise(IllegalParams, "tuple must have all indexed fields"); /* Hash index currently is always single-part. */ void *field = tuple_field(tuple, key_def->parts[0].fieldno); - return [self findByKey :field :1]; + return findByKey(field, 1); } -@end - /* }}} */ /* {{{ Hash32Index ************************************************/ @@ -266,8 +332,8 @@ int32_key_to_node(const void *key) { u32 key_size = load_varint32(&key); if (key_size != 4) - tnt_raise(ClientError, :ER_KEY_FIELD_TYPE, "u32"); - struct mh_i32ptr_node_t node = { .key = *(u32 *) key }; + tnt_raise(ClientError, ER_KEY_FIELD_TYPE, "u32"); + struct mh_i32ptr_node_t node = { *(u32 *) key, NULL }; return node; } @@ -280,44 +346,42 @@ int32_tuple_to_node(struct tuple *tuple, struct key_def *key_def) return node; } -@implementation Hash32Index -- (void) reserve: (u32) n_tuples +Hash32Index::Hash32Index(struct key_def *key_def, struct space *space) + : HashIndex(key_def, space) { - mh_i32ptr_reserve(int_hash, n_tuples, NULL); + int_hash = mh_i32ptr_new(); } -- (void) free +Hash32Index::~Hash32Index() { mh_i32ptr_delete(int_hash); - [super free]; } -- (id) init: (struct key_def *) key_def_arg :(struct space *) space_arg +void +Hash32Index::reserve(u32 n_tuples) { - self = [super init: key_def_arg :space_arg]; - - if (self == NULL) - return NULL; - - int_hash = mh_i32ptr_new(); - return self; + mh_i32ptr_reserve(int_hash, n_tuples, NULL); } -- (size_t) size +size_t +Hash32Index::size() const { return mh_size(int_hash); } -- (struct tuple *) random: (u32) rnd + +struct tuple * +Hash32Index::random(u32 rnd) const { mh_int_t k = mh_i32ptr_random(int_hash, rnd); if (k != mh_end(int_hash)) - return mh_i32ptr_node(int_hash, k)->val; + return (struct tuple *) mh_i32ptr_node(int_hash, k)->val; return NULL; } -- (struct tuple *) findByKey: (const void *) key :(u32) part_count +struct tuple * +Hash32Index::findByKey(const void *key, u32 part_count) const { assert(key_def->is_unique); check_key_parts(key_def, part_count, false); @@ -328,16 +392,16 @@ int32_tuple_to_node(struct tuple *tuple, struct key_def *key_def) struct mh_i32ptr_node_t node = int32_key_to_node(key); mh_int_t k = mh_i32ptr_get(int_hash, &node, NULL); if (k != mh_end(int_hash)) - ret = mh_i32ptr_node(int_hash, k)->val; + ret = (struct tuple *) mh_i32ptr_node(int_hash, k)->val; #ifdef DEBUG say_debug("Hash32Index find(self:%p, key:%i) = %p", self, node.key, ret); #endif return ret; } -- (struct tuple *) replace: (struct tuple *) old_tuple - :(struct tuple *) new_tuple - :(enum dup_replace_mode) mode +struct tuple * +Hash32Index::replace(struct tuple *old_tuple, struct tuple *new_tuple, + enum dup_replace_mode mode) { struct mh_i32ptr_node_t new_node, old_node; uint32_t errcode; @@ -355,10 +419,12 @@ int32_tuple_to_node(struct tuple *tuple, struct key_def *key_def) }); if (pos == mh_end(int_hash)) { - tnt_raise(LoggedError, :ER_MEMORY_ISSUE, (ssize_t) pos, + tnt_raise(LoggedError, ER_MEMORY_ISSUE, (ssize_t) pos, "int hash", "key"); } - struct tuple *dup_tuple = dup_node ? dup_node->val : NULL; + struct tuple *dup_tuple = dup_node + ? (struct tuple *) dup_node->val + : NULL; errcode = replace_check_dup(old_tuple, dup_tuple, mode); if (errcode) { @@ -371,7 +437,7 @@ int32_tuple_to_node(struct tuple *tuple, struct key_def *key_def) "recover of int hash"); } } - tnt_raise(ClientError, :errcode, index_n(self)); + tnt_raise(ClientError, errcode, index_n(this)); } if (dup_tuple) return dup_tuple; @@ -384,9 +450,11 @@ int32_tuple_to_node(struct tuple *tuple, struct key_def *key_def) } -- (struct iterator *) allocIterator +struct iterator * +Hash32Index::allocIterator() const { - struct hash_i32_iterator *it = malloc(sizeof(struct hash_i32_iterator)); + struct hash_i32_iterator *it = (struct hash_i32_iterator *) + malloc(sizeof(struct hash_i32_iterator)); if (it) { memset(it, 0, sizeof(*it)); it->base.next = hash_iterator_i32_ge; @@ -395,8 +463,9 @@ int32_tuple_to_node(struct tuple *tuple, struct key_def *key_def) return (struct iterator *) it; } -- (void) initIterator: (struct iterator *) ptr :(enum iterator_type) type - :(const void *) key :(u32) part_count +void +Hash32Index::initIterator(struct iterator *ptr, enum iterator_type type, + const void *key, u32 part_count) const { assert(ptr->free == hash_iterator_free); struct hash_i32_iterator *it = (struct hash_i32_iterator *) ptr; @@ -406,7 +475,7 @@ int32_tuple_to_node(struct tuple *tuple, struct key_def *key_def) case ITER_GE: if (key != NULL) { check_key_parts(key_def, part_count, - traits->allows_partial_key); + hash_index_traits.allows_partial_key); node = int32_key_to_node(key); it->h_pos = mh_i32ptr_get(int_hash, &node, NULL); it->base.next = hash_iterator_i32_ge; @@ -419,18 +488,17 @@ int32_tuple_to_node(struct tuple *tuple, struct key_def *key_def) break; case ITER_EQ: check_key_parts(key_def, part_count, - traits->allows_partial_key); + hash_index_traits.allows_partial_key); node = int32_key_to_node(key); it->h_pos = mh_i32ptr_get(int_hash, &node, NULL); it->base.next = hash_iterator_i32_eq; break; default: - tnt_raise(ClientError, :ER_UNSUPPORTED, + tnt_raise(ClientError, ER_UNSUPPORTED, "Hash index", "requested iterator type"); } it->hash = int_hash; } -@end /* }}} */ @@ -441,8 +509,8 @@ int64_key_to_node(const void *key) { u32 key_size = load_varint32(&key); if (key_size != 8) - tnt_raise(ClientError, :ER_KEY_FIELD_TYPE, "u64"); - struct mh_i64ptr_node_t node = { .key = *(u64 *) key }; + tnt_raise(ClientError, ER_KEY_FIELD_TYPE, "u64"); + struct mh_i64ptr_node_t node = { *(u64 *) key, NULL }; return node; } @@ -455,60 +523,60 @@ int64_tuple_to_node(struct tuple *tuple, struct key_def *key_def) return node; } -@implementation Hash64Index -- (void) reserve: (u32) n_tuples +Hash64Index::Hash64Index(struct key_def *key_def, struct space *space) + : HashIndex(key_def, space) { - mh_i64ptr_reserve(int64_hash, n_tuples, NULL); + int64_hash = mh_i64ptr_new(); } -- (void) free +Hash64Index::~Hash64Index() { mh_i64ptr_delete(int64_hash); - [super free]; } -- (id) init: (struct key_def *) key_def_arg :(struct space *) space_arg +void +Hash64Index::reserve(u32 n_tuples) { - self = [super init: key_def_arg :space_arg]; - if (self == NULL) - return NULL; - - int64_hash = mh_i64ptr_new(); - return self; + mh_i64ptr_reserve(int64_hash, n_tuples, NULL); } -- (size_t) size +size_t +Hash64Index::size() const { return mh_size(int64_hash); } -- (struct tuple *) random: (u32) rnd +struct tuple * +Hash64Index::random(u32 rnd) const { mh_int_t k = mh_i64ptr_random(int64_hash, rnd); if (k != mh_end(int64_hash)) - return mh_i64ptr_node(int64_hash, k)->val; + return (struct tuple *) mh_i64ptr_node(int64_hash, k)->val; return NULL; } -- (struct tuple *) findByKey: (const void *) key :(u32) part_count +struct tuple * +Hash64Index::findByKey(const void *key, u32 part_count) const { assert(key_def->is_unique); check_key_parts(key_def, part_count, false); + (void) part_count; + struct tuple *ret = NULL; struct mh_i64ptr_node_t node = int64_key_to_node(key); mh_int_t k = mh_i64ptr_get(int64_hash, &node, NULL); if (k != mh_end(int64_hash)) - ret = mh_i64ptr_node(int64_hash, k)->val; -#ifdef DEBUG - say_debug("Hash64Index find(self:%p, key:%"PRIu64") = %p", self, node.key, ret); -#endif + ret = (struct tuple *) mh_i64ptr_node(int64_hash, k)->val; + #ifdef DEBUG + say_debug("Hash64Index find(self:%p, key:%i) = %p", self, node.key, ret); + #endif return ret; } -- (struct tuple *) replace: (struct tuple *) old_tuple - :(struct tuple *) new_tuple - :(enum dup_replace_mode) mode +struct tuple * +Hash64Index::replace(struct tuple *old_tuple, struct tuple *new_tuple, + enum dup_replace_mode mode) { struct mh_i64ptr_node_t new_node, old_node; uint32_t errcode; @@ -517,59 +585,66 @@ int64_tuple_to_node(struct tuple *tuple, struct key_def *key_def) struct mh_i64ptr_node_t *dup_node = &old_node; new_node = int64_tuple_to_node(new_tuple, key_def); mh_int_t pos = mh_i64ptr_put(int64_hash, &new_node, - &dup_node, NULL); + &dup_node, NULL); ERROR_INJECT(ERRINJ_INDEX_ALLOC, { mh_i64ptr_del(int64_hash, pos, NULL); pos = mh_end(int64_hash); }); + if (pos == mh_end(int64_hash)) { - tnt_raise(LoggedError, :ER_MEMORY_ISSUE, (ssize_t) pos, - "int64 hash", "key"); + tnt_raise(LoggedError, ER_MEMORY_ISSUE, (ssize_t) pos, + "int hash", "key"); } - struct tuple *dup_tuple = dup_node ? dup_node->val : NULL; + struct tuple *dup_tuple = dup_node + ? (struct tuple *) dup_node->val + : NULL; errcode = replace_check_dup(old_tuple, dup_tuple, mode); if (errcode) { mh_i64ptr_remove(int64_hash, &new_node, NULL); if (dup_node) { - pos = mh_i64ptr_put(int64_hash, dup_node, - NULL, NULL); + pos = mh_i64ptr_put(int64_hash, dup_node, NULL, NULL); if (pos == mh_end(int64_hash)) { panic("Failed to allocate memory in " - "recover of int64 hash"); + "recover of int hash"); } } - tnt_raise(ClientError, :errcode, index_n(self)); + tnt_raise(ClientError, errcode, index_n(this)); } + if (dup_tuple) return dup_tuple; } + if (old_tuple) { old_node = int64_tuple_to_node(old_tuple, key_def); mh_i64ptr_remove(int64_hash, &old_node, NULL); } + return old_tuple; } -- (struct iterator *) allocIterator +struct iterator * +Hash64Index::allocIterator() const { - struct hash_i64_iterator *it = malloc(sizeof(struct hash_i64_iterator)); + struct hash_i64_iterator *it = (struct hash_i64_iterator *) + malloc(sizeof(struct hash_i64_iterator)); if (it) { memset(it, 0, sizeof(*it)); it->base.next = hash_iterator_i64_ge; it->base.free = hash_iterator_free; } + return (struct iterator *) it; } - -- (void) initIterator: (struct iterator *) ptr :(enum iterator_type) type - :(const void *) key :(u32) part_count +void +Hash64Index::initIterator(struct iterator *ptr, enum iterator_type type, + const void *key, u32 part_count) const { - (void) part_count; assert(ptr->free == hash_iterator_free); struct hash_i64_iterator *it = (struct hash_i64_iterator *) ptr; struct mh_i64ptr_node_t node; @@ -578,31 +653,30 @@ int64_tuple_to_node(struct tuple *tuple, struct key_def *key_def) case ITER_GE: if (key != NULL) { check_key_parts(key_def, part_count, - traits->allows_partial_key); + hash_index_traits.allows_partial_key); node = int64_key_to_node(key); it->h_pos = mh_i64ptr_get(int64_hash, &node, NULL); it->base.next = hash_iterator_i64_ge; break; } - /* Fallthrough. */ + /* Fall through. */ case ITER_ALL: + it->h_pos = mh_begin(int_hash); it->base.next = hash_iterator_i64_ge; - it->h_pos = mh_begin(int64_hash); break; case ITER_EQ: check_key_parts(key_def, part_count, - traits->allows_partial_key); + hash_index_traits.allows_partial_key); node = int64_key_to_node(key); it->h_pos = mh_i64ptr_get(int64_hash, &node, NULL); it->base.next = hash_iterator_i64_eq; break; default: - tnt_raise(ClientError, :ER_UNSUPPORTED, + tnt_raise(ClientError, ER_UNSUPPORTED, "Hash index", "requested iterator type"); } it->hash = int64_hash; } -@end /* }}} */ @@ -613,59 +687,57 @@ lstrptr_tuple_to_node(struct tuple *tuple, struct key_def *key_def) { void *field = tuple_field(tuple, key_def->parts[0].fieldno); if (field == NULL) - tnt_raise(ClientError, :ER_NO_SUCH_FIELD, + tnt_raise(ClientError, ER_NO_SUCH_FIELD, key_def->parts[0].fieldno); - struct mh_lstrptr_node_t node = { .key = field, .val = tuple }; + struct mh_lstrptr_node_t node = { field, tuple }; return node; } - -@implementation HashStrIndex -- (void) reserve: (u32) n_tuples +HashStrIndex::HashStrIndex(struct key_def *key_def, struct space *space) + : HashIndex(key_def, space) { - mh_lstrptr_reserve(str_hash, n_tuples, NULL); + str_hash = mh_lstrptr_new(); } -- (void) free +HashStrIndex::~HashStrIndex() { mh_lstrptr_delete(str_hash); - [super free]; } -- (id) init: (struct key_def *) key_def_arg :(struct space *) space_arg +void +HashStrIndex::reserve(u32 n_tuples) { - self = [super init: key_def_arg :space_arg]; - if (self == NULL) - return NULL; - - str_hash = mh_lstrptr_new(); - return self; + mh_lstrptr_reserve(str_hash, n_tuples, NULL); } -- (size_t) size + +size_t +HashStrIndex::size() const { return mh_size(str_hash); } -- (struct tuple *) random: (u32) rnd +struct tuple * +HashStrIndex::random(u32 rnd) const { mh_int_t k = mh_lstrptr_random(str_hash, rnd); if (k != mh_end(str_hash)) - return mh_lstrptr_node(str_hash, k)->val; + return (struct tuple *) mh_lstrptr_node(str_hash, k)->val; return NULL; } -- (struct tuple *) findByKey: (const void *) key :(u32) part_count +struct tuple * +HashStrIndex::findByKey(const void *key, u32 part_count) const { assert(key_def->is_unique); check_key_parts(key_def, part_count, false); struct tuple *ret = NULL; - const struct mh_lstrptr_node_t node = { .key = key }; + const struct mh_lstrptr_node_t node = { key, NULL }; mh_int_t k = mh_lstrptr_get(str_hash, &node, NULL); if (k != mh_end(str_hash)) - ret = mh_lstrptr_node(str_hash, k)->val; + ret = (struct tuple *) mh_lstrptr_node(str_hash, k)->val; #ifdef DEBUG u32 key_size = load_varint32((const void **) &key); say_debug("HashStrIndex find(self:%p, key:(%i)'%.*s') = %p", @@ -674,9 +746,9 @@ lstrptr_tuple_to_node(struct tuple *tuple, struct key_def *key_def) return ret; } -- (struct tuple *) replace: (struct tuple *) old_tuple - :(struct tuple *) new_tuple - :(enum dup_replace_mode) mode +struct tuple * +HashStrIndex::replace(struct tuple *old_tuple, struct tuple *new_tuple, + enum dup_replace_mode mode) { struct mh_lstrptr_node_t new_node, old_node; uint32_t errcode; @@ -694,10 +766,12 @@ lstrptr_tuple_to_node(struct tuple *tuple, struct key_def *key_def) }); if (pos == mh_end(str_hash)) { - tnt_raise(LoggedError, :ER_MEMORY_ISSUE, (ssize_t) pos, + tnt_raise(LoggedError, ER_MEMORY_ISSUE, (ssize_t) pos, "str hash", "key"); } - struct tuple *dup_tuple = dup_node ? dup_node->val : NULL; + struct tuple *dup_tuple = dup_node + ? (struct tuple *) dup_node->val + : NULL; errcode = replace_check_dup(old_tuple, dup_tuple, mode); if (errcode) { @@ -710,7 +784,7 @@ lstrptr_tuple_to_node(struct tuple *tuple, struct key_def *key_def) "recover of str hash"); } } - tnt_raise(ClientError, :errcode, index_n(self)); + tnt_raise(ClientError, errcode, index_n(this)); } if (dup_tuple) return dup_tuple; @@ -722,9 +796,11 @@ lstrptr_tuple_to_node(struct tuple *tuple, struct key_def *key_def) return old_tuple; } -- (struct iterator *) allocIterator +struct iterator * +HashStrIndex::allocIterator() const { - struct hash_lstr_iterator *it = malloc(sizeof(struct hash_lstr_iterator)); + struct hash_lstr_iterator *it = (struct hash_lstr_iterator *) + malloc(sizeof(struct hash_lstr_iterator)); if (it) { memset(it, 0, sizeof(*it)); it->base.next = hash_iterator_lstr_ge; @@ -733,10 +809,9 @@ lstrptr_tuple_to_node(struct tuple *tuple, struct key_def *key_def) return (struct iterator *) it; } - -- (void) initIterator: (struct iterator *) ptr - :(enum iterator_type) type - :(const void *) key :(u32) part_count +void +HashStrIndex::initIterator(struct iterator *ptr, enum iterator_type type, + const void *key, u32 part_count) const { (void) part_count; @@ -748,7 +823,7 @@ lstrptr_tuple_to_node(struct tuple *tuple, struct key_def *key_def) case ITER_GE: if (key != NULL) { check_key_parts(key_def, part_count, - traits->allows_partial_key); + hash_index_traits.allows_partial_key); node.key = key; it->h_pos = mh_lstrptr_get(str_hash, &node, NULL); it->base.next = hash_iterator_lstr_ge; @@ -761,18 +836,17 @@ lstrptr_tuple_to_node(struct tuple *tuple, struct key_def *key_def) break; case ITER_EQ: check_key_parts(key_def, part_count, - traits->allows_partial_key); + hash_index_traits.allows_partial_key); node.key = key; it->h_pos = mh_lstrptr_get(str_hash, &node, NULL); it->base.next = hash_iterator_lstr_eq; break; default: - tnt_raise(ClientError, :ER_UNSUPPORTED, + tnt_raise(ClientError, ER_UNSUPPORTED, "Hash index", "requested iterator type"); } it->hash = str_hash; } -@end /* }}} */ diff --git a/src/box/hash_index.h b/src/box/hash_index.h index 5e1fd9c4388ffba03b5e953f1f89967bb99c3672..df0c5f8e23f02543682d29b05fcc16552150dbb6 100644 --- a/src/box/hash_index.h +++ b/src/box/hash_index.h @@ -31,14 +31,34 @@ #include "index.h" -@class Index; -@interface HashIndex: Index +class HashIndex: public Index { +public: + static HashIndex * + factory(struct key_def *key_def, struct space *space); -+ (struct index_traits *) traits; -+ (HashIndex *) alloc: (struct key_def *) key_def :(struct space *) space; + HashIndex(struct key_def *key_def, struct space *space); -- (void) reserve: (u32) n_tuples; -@end + virtual void beginBuild(); + virtual void buildNext(struct tuple *tuple); + virtual void endBuild(); + virtual void build(Index *pk); + virtual size_t size() const = 0; + virtual struct tuple *min() const; + virtual struct tuple *max() const; + virtual struct tuple *random(u32 rnd) const = 0; + virtual struct tuple *findByKey(const void *key, u32 part_count) const = 0; + virtual struct tuple *findByTuple(struct tuple *tuple) const; + virtual struct tuple *replace(struct tuple *old_tuple, + struct tuple *new_tuple, + enum dup_replace_mode mode) = 0; + + virtual struct iterator *allocIterator() const = 0; + virtual void initIterator(struct iterator *iterator, + enum iterator_type type, + const void *key, u32 part_count) const = 0; + + virtual void reserve(u32 n_tuples) = 0; +}; #endif /* TARANTOOL_BOX_HASH_INDEX_H_INCLUDED */ diff --git a/src/box/index.m b/src/box/index.cc similarity index 54% rename from src/box/index.m rename to src/box/index.cc index 3e066376f2f1babe59f47eb006cc3c355bba2a2d..dfca3de0c84f4e5a3db40edc34fb165a9f39b511 100644 --- a/src/box/index.m +++ b/src/box/index.cc @@ -35,10 +35,6 @@ #include "exception.h" #include "space.h" -static struct index_traits index_traits = { - .allows_partial_key = false, -}; - const char *field_data_type_strs[] = {"UNKNOWN", "NUM", "NUM64", "STR", "\0"}; STRS(index_type, INDEX_TYPE); STRS(iterator_type, ITERATOR_TYPE); @@ -46,14 +42,14 @@ STRS(iterator_type, ITERATOR_TYPE); /* {{{ Utilities. **********************************************/ void -check_key_parts(const struct key_def *key_def, +Index::check_key_parts(const struct key_def *key_def, u32 part_count, bool partial_key_allowed) { if (part_count > key_def->part_count) - tnt_raise(ClientError, :ER_KEY_PART_COUNT, + tnt_raise(ClientError, ER_KEY_PART_COUNT, part_count, key_def->part_count); if (!partial_key_allowed && part_count < key_def->part_count) - tnt_raise(ClientError, :ER_EXACT_MATCH, + tnt_raise(ClientError, ER_EXACT_MATCH, part_count, key_def->part_count); } @@ -62,7 +58,7 @@ check_key_parts(const struct key_def *key_def, * allowed. */ uint32_t -replace_check_dup(struct tuple *old_tuple, +Index::replace_check_dup(struct tuple *old_tuple, struct tuple *dup_tuple, enum dup_replace_mode mode) { @@ -93,24 +89,16 @@ replace_check_dup(struct tuple *old_tuple, /* {{{ Index -- base class for all indexes. ********************/ -@implementation Index - -+ (struct index_traits *) traits -{ - return &index_traits; -} - -+ (Index *) alloc: (enum index_type) type - :(struct key_def *) key_def - :(struct space *) space +Index * +Index::factory(enum index_type type, struct key_def *key_def, struct space *space) { switch (type) { case HASH: - return [HashIndex alloc: key_def :space]; + return HashIndex::factory(key_def, space); case TREE: - return [TreeIndex alloc: key_def :space]; + return TreeIndex::factory(key_def, space); case BITSET: - return [BitsetIndex alloc]; + return new BitsetIndex(key_def, space); default: assert(false); } @@ -118,118 +106,28 @@ replace_check_dup(struct tuple *old_tuple, return NULL; } -- (id) init: (struct key_def *) key_def_arg :(struct space *) space_arg -{ - self = [super init]; - if (self == NULL) - return NULL; - - traits = [object_getClass(self) traits]; - key_def = key_def_arg; - space = space_arg; - position = [self allocIterator]; - - return self; -} - -- (void) free -{ - position->free(position); - [super free]; -} - -- (void) beginBuild -{ - [self subclassResponsibility: _cmd]; -} - -- (void) buildNext: (struct tuple *)tuple -{ - (void) tuple; - [self subclassResponsibility: _cmd]; -} - -- (void) endBuild -{ - [self subclassResponsibility: _cmd]; -} - -- (void) build: (Index *) pk +Index::Index(struct key_def *key_def, struct space *space) { - (void) pk; - [self subclassResponsibility: _cmd]; + this->key_def = key_def; + this->space = space; + this->position = NULL; } - -- (size_t) size +Index::~Index() { - [self subclassResponsibility: _cmd]; - return 0; -} - -- (struct tuple *) min -{ - [self subclassResponsibility: _cmd]; - return NULL; -} - -- (struct tuple *) max -{ - [self subclassResponsibility: _cmd]; - return NULL; -} - -- (struct tuple *) random: (u32) rnd -{ - (void) rnd; - [self subclassResponsibility: _cmd]; - return NULL; -} - -- (struct tuple *) findByKey: (const void *) key :(u32) part_count -{ - (void) key; - (void) part_count; - [self subclassResponsibility: _cmd]; - return NULL; -} - -- (struct tuple *) findByTuple: (struct tuple *) pattern -{ - (void) pattern; - [self subclassResponsibility: _cmd]; - return NULL; -} - -- (struct tuple *) replace: (struct tuple *) old_tuple - : (struct tuple *) new_tuple - : (enum dup_replace_mode) mode -{ - (void) old_tuple; - (void) new_tuple; - (void) mode; - [self subclassResponsibility: _cmd]; - return NULL; + if (position != NULL) { + position->free(position); + } } -- (struct iterator *) allocIterator +struct iterator * +Index::primaryIterator() { - [self subclassResponsibility: _cmd]; - return NULL; -} - + if (position == NULL) { + position = allocIterator(); + } -- (void) initIterator: (struct iterator *) iterator - :(enum iterator_type) type - :(const void *) key :(u32) part_count -{ - (void) iterator; - (void) type; - (void) key; - (void) part_count; - [self subclassResponsibility: _cmd]; + return position; } -@end - /* }}} */ diff --git a/src/box/index.h b/src/box/index.h index 9b024dc007c9d13570320c4576805450cfc9664a..f7a3ce74237de9a004b26f382fab5adcb9a79140 100644 --- a/src/box/index.h +++ b/src/box/index.h @@ -28,10 +28,11 @@ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#import "object.h" #include <stdbool.h> #include <util.h> +#include "object.h" + struct tuple; struct space; @@ -141,16 +142,16 @@ struct index_traits * possibly present in the index. */ enum dup_replace_mode { - /** + /** * If a duplicate is found, delete it and insert * a new tuple instead. Otherwise, insert a new tuple. - */ + */ DUP_REPLACE_OR_INSERT, /** * If a duplicate is found, produce an error. * I.e. require that no old key exists with the same * value. - */ + */ DUP_INSERT, /** * Unless a duplicate exists, throw an error. @@ -158,14 +159,76 @@ enum dup_replace_mode { DUP_REPLACE }; -@interface Index: tnt_Object { - /* Index features. */ - struct index_traits *traits; - @public + +class Index: public Object { +public: + /* Index owner space */ struct space *space; /* Description of a possibly multipart key. */ struct key_def *key_def; + + + /** + * Allocate index instance. + * + * @param type index type + * @param key_def key part description + * @param space space the index belongs to + */ + static Index *factory(enum index_type type, struct key_def *key_def, + struct space *space); + + /** + * Initialize index instance. + * + * @param key_def key part description + * @param space space the index belongs to + */ +protected: + Index(struct key_def *key_def, struct space *space); + +public: + virtual ~Index(); + + /** + * Two-phase index creation: begin building, add tuples, finish. + */ + virtual void beginBuild() = 0; + virtual void buildNext(struct tuple *tuple) = 0; + virtual void endBuild() = 0; + /** Build this index based on the contents of another index. */ + virtual void build(Index *pk) = 0; + virtual size_t size() const = 0; + virtual struct tuple *min() const = 0; + virtual struct tuple *max() const = 0; + virtual struct tuple *random(u32 rnd) const = 0; + virtual struct tuple *findByKey(const void *key, u32 part_count) const = 0; + virtual struct tuple *findByTuple(struct tuple *tuple) const = 0; + virtual struct tuple *replace(struct tuple *old_tuple, + struct tuple *new_tuple, + enum dup_replace_mode mode) = 0; + /** + * Create a structure to represent an iterator. Must be + * initialized separately. + */ + virtual struct iterator *allocIterator() const = 0; + virtual void initIterator(struct iterator *iterator, + enum iterator_type type, + const void *key, u32 part_count) const = 0; + + struct iterator *primaryIterator(); +protected: + static void + check_key_parts(const struct key_def *key_def, u32 part_count, + bool partial_key_allowed); + + static uint32_t + replace_check_dup(struct tuple *old_tuple, + struct tuple *dup_tuple, + enum dup_replace_mode mode); + +private: /* * Pre-allocated iterator to speed up the main case of * box_process(). Should not be used elsewhere. @@ -173,62 +236,4 @@ enum dup_replace_mode { struct iterator *position; }; -/** - * Get index traits. - */ -+ (struct index_traits *) traits; -/** - * Allocate index instance. - * - * @param type index type - * @param key_def key part description - * @param space space the index belongs to - */ -+ (Index *) alloc: (enum index_type) type :(struct key_def *) key_def - :(struct space *) space; -/** - * Initialize index instance. - * - * @param key_def key part description - * @param space space the index belongs to - */ -- (id) init: (struct key_def *) key_def_arg :(struct space *) space_arg; -/** Destroy and free index instance. */ -- (void) free; -/** - * Two-phase index creation: begin building, add tuples, finish. - */ -- (void) beginBuild; -- (void) buildNext: (struct tuple *)tuple; -- (void) endBuild; -/** Build this index based on the contents of another index. */ -- (void) build: (Index *) pk; -- (size_t) size; -- (struct tuple *) min; -- (struct tuple *) max; -- (struct tuple *) random: (u32) rnd; -- (struct tuple *) findByKey: (const void *) key :(u32) part_count; -- (struct tuple *) findByTuple: (struct tuple *) tuple; -- (struct tuple *) replace: (struct tuple *) old_tuple - :(struct tuple *) new_tuple - :(enum dup_replace_mode) mode; -/** - * Create a structure to represent an iterator. Must be - * initialized separately. - */ -- (struct iterator *) allocIterator; -- (void) initIterator: (struct iterator *) iterator - :(enum iterator_type) type - :(const void *) key :(u32) part_count; -@end - -void -check_key_parts(const struct key_def *key_def, u32 part_count, - bool partial_key_allowed); - -uint32_t -replace_check_dup(struct tuple *old_tuple, - struct tuple *dup_tuple, - enum dup_replace_mode mode); - #endif /* TARANTOOL_BOX_INDEX_H_INCLUDED */ diff --git a/src/box/port.m b/src/box/port.cc similarity index 98% rename from src/box/port.m rename to src/box/port.cc index f694530cdcac20a5bd2e4c135cc18b372fa07fbd..98a8c9654214710fc2d2b29e18579941c761988f 100644 --- a/src/box/port.m +++ b/src/box/port.cc @@ -46,6 +46,6 @@ static struct port_vtab port_null_vtab = { }; struct port port_null = { - .vtab = &port_null_vtab, + /* .vtab = */ &port_null_vtab, }; diff --git a/src/box/request.m b/src/box/request.cc similarity index 86% rename from src/box/request.m rename to src/box/request.cc index 752833f015952475c984074432cb87ba5b8298ec..f4bd73b754fae68d499565b2ece542742439b9e5 100644 --- a/src/box/request.m +++ b/src/box/request.cc @@ -72,31 +72,31 @@ execute_replace(struct request *request, struct txn *txn) { txn_add_redo(txn, request->type, request->data, request->len); const void **reqpos = &request->data; - const void *reqend = request->data + request->len; + const void *reqend = (const char *) request->data + request->len; struct space *sp = read_space(reqpos, reqend); request->flags |= (pick_u32(reqpos, reqend) & BOX_ALLOWED_REQUEST_FLAGS); size_t field_count = pick_u32(reqpos, reqend); if (field_count == 0) - tnt_raise(IllegalParams, :"tuple field count is 0"); + tnt_raise(IllegalParams, "tuple field count is 0"); - size_t tuple_len = reqend - *reqpos; + size_t tuple_len = (const char *) reqend - (const char *) *reqpos; if (tuple_len != valid_tuple(*reqpos, reqend, field_count)) - tnt_raise(IllegalParams, :"incorrect tuple length"); + tnt_raise(IllegalParams, "incorrect tuple length"); struct tuple *new_tuple = tuple_alloc(tuple_len); new_tuple->field_count = field_count; memcpy(new_tuple->data, *reqpos, tuple_len); - @try { + try { space_validate_tuple(sp, new_tuple); enum dup_replace_mode mode = dup_replace_mode(request->flags); txn_replace(txn, sp, NULL, new_tuple, mode); - } @catch (tnt_Exception *e) { + } catch (const Exception& e) { tuple_free(new_tuple); - @throw; + throw; } } @@ -236,7 +236,7 @@ struct update_field { * Length of the "tail" in the old tuple from end * of old data to the beginning of the field in the * next update_field structure. - */ + */ u32 tail_len; }; @@ -246,7 +246,7 @@ update_field_init(struct update_field *field, { STAILQ_INIT(&field->ops); field->old = old; - field->tail = old + old_len; + field->tail = (char *) old + old_len; field->tail_len = tail_len; } @@ -254,14 +254,15 @@ static inline u32 update_field_len(struct update_field *f) { struct update_op *last = STAILQ_LAST(&f->ops, update_op, next); - return last? last->new_field_len : f->tail - f->old; + return last ? last->new_field_len + : (const char *) f->tail - (const char *) f->old; } static inline void op_check_field_no(u32 field_no, u32 field_max) { if (field_no > field_max) - tnt_raise(ClientError, :ER_NO_SUCH_FIELD, field_no); + tnt_raise(ClientError, ER_NO_SUCH_FIELD, field_no); } static inline void @@ -330,10 +331,10 @@ static void do_update_op_splice(struct op_splice_arg *arg, const void *in, void *out) { memcpy(out, in, arg->offset); /* copy field head. */ - out += arg->offset; + out = (char *) out + arg->offset; memcpy(out, arg->paste, arg->paste_length); /* copy the paste */ - out += arg->paste_length; - memcpy(out, in + arg->tail_offset, arg->tail_length); /* copy tail */ + out = (char *) out + arg->paste_length; + memcpy(out, (const char *) in + arg->tail_offset, arg->tail_length); /* copy tail */ } static void @@ -348,8 +349,8 @@ static void init_update_op_insert(struct rope *rope, struct update_op *op) { op_adjust_field_no(op, rope_size(rope)); - struct update_field *field = palloc(fiber->gc_pool, - sizeof(struct update_field)); + struct update_field *field = (struct update_field *) + palloc(fiber->gc_pool, sizeof(struct update_field)); update_field_init(field, op->arg.set.value, op->arg.set.length, 0); rope_insert(rope, op->field_no, field, 1); } @@ -358,8 +359,8 @@ static void init_update_op_set(struct rope *rope, struct update_op *op) { if (op->field_no < rope_size(rope)) { - struct update_field *field = rope_extract(rope, - op->field_no); + struct update_field *field = (struct update_field *) + rope_extract(rope, op->field_no); /* Skip all previous ops. */ STAILQ_INIT(&field->ops); STAILQ_INSERT_TAIL(&field->ops, op, next); @@ -381,7 +382,8 @@ init_update_op_arith(struct rope *rope, struct update_op *op) { op_check_field_no(op->field_no, rope_size(rope) - 1); - struct update_field *field = rope_extract(rope, op->field_no); + struct update_field *field = (struct update_field *) + rope_extract(rope, op->field_no); struct op_arith_arg *arg = &op->arg.arith; u32 field_len = update_field_len(field); @@ -391,7 +393,7 @@ init_update_op_arith(struct rope *rope, struct update_op *op) /* Check the operand type. */ if (op->arg.set.length != sizeof(i32)) - tnt_raise(ClientError, :ER_ARG_TYPE, + tnt_raise(ClientError, ER_ARG_TYPE, "32-bit int"); arg->i32_val = *(i32 *)op->arg.set.value; @@ -409,12 +411,12 @@ init_update_op_arith(struct rope *rope, struct update_op *op) arg->i64_val = *(i64 *)op->arg.set.value; break; default: - tnt_raise(ClientError, :ER_ARG_TYPE, + tnt_raise(ClientError, ER_ARG_TYPE, "32-bit or 64-bit int"); } break; default: - tnt_raise(ClientError, :ER_FIELD_TYPE, + tnt_raise(ClientError, ER_FIELD_TYPE, "32-bit or 64-bit int"); } STAILQ_INSERT_TAIL(&field->ops, op, next); @@ -425,19 +427,20 @@ static void init_update_op_splice(struct rope *rope, struct update_op *op) { op_check_field_no(op->field_no, rope_size(rope) - 1); - struct update_field *field = rope_extract(rope, op->field_no); + struct update_field *field = (struct update_field *) + rope_extract(rope, op->field_no); u32 field_len = update_field_len(field); struct op_splice_arg *arg = &op->arg.splice; const void *value = op->arg.set.value; - const void *end = value + op->arg.set.length; + const void *end = (const char *) value + op->arg.set.length; /* Read the offset. */ arg->offset = pick_field_u32(&value, end); if (arg->offset < 0) { if (-arg->offset > field_len) - tnt_raise(ClientError, :ER_SPLICE, + tnt_raise(ClientError, ER_SPLICE, "offset is out of bound"); arg->offset += field_len; } else if (arg->offset > field_len) { @@ -465,7 +468,7 @@ init_update_op_splice(struct rope *rope, struct update_op *op) /* Check that the operands are fully read. */ if (value != end) - tnt_raise(IllegalParams, :"field splice format error"); + tnt_raise(IllegalParams, "field splice format error"); /* Record the new field length. */ op->new_field_len = arg->offset + arg->paste_length + arg->tail_length; @@ -487,7 +490,7 @@ static struct update_op_meta update_op_meta[UPDATE_OP_MAX + 1] = { static void * rope_alloc(void *ctx, size_t size) { - return palloc(ctx, size); + return palloc((struct palloc_pool *) ctx, size); } /** Free rope node - do nothing, since we use a pool allocator. */ @@ -502,20 +505,20 @@ static void * update_field_split(void *data, size_t size __attribute__((unused)), size_t offset) { - struct update_field *prev = data; + struct update_field *prev = (struct update_field *) data; - struct update_field *next = palloc(fiber->gc_pool, - sizeof(struct update_field)); + struct update_field *next = (struct update_field *) + palloc(fiber->gc_pool, sizeof(struct update_field)); assert(offset > 0 && prev->tail_len > 0); const void *field = prev->tail; - const void *end = field + prev->tail_len; + const void *end = (const char *) field + prev->tail_len; prev->tail_len = tuple_range_size(&field, end, offset - 1); u32 field_len = load_varint32(&field); - update_field_init(next, field, field_len, - end - field - field_len); + update_field_init(next, field, field_len, (const char *) end - + (const char *) field - field_len); return next; } @@ -533,12 +536,13 @@ update_create_rope(struct update_op *op, struct update_op *op_end, /* Initialize the rope with the old tuple. */ - struct update_field *first = palloc(fiber->gc_pool, - sizeof(struct update_field)); + struct update_field *first = (struct update_field *) + palloc(fiber->gc_pool, sizeof(struct update_field)); const void *field = tuple->data; const void *end = tuple->data + tuple->bsize; u32 field_len = load_varint32(&field); - update_field_init(first, field, field_len, end - field - field_len); + update_field_init(first, field, field_len, + (const char *) end - (const char *) field - field_len); rope_append(rope, first, tuple->field_count); @@ -557,14 +561,15 @@ update_calc_new_tuple_length(struct rope *rope) rope_iter_create(&it, rope); for (node = rope_iter_start(&it); node; node = rope_iter_next(&it)) { - struct update_field *field = rope_leaf_data(node); + struct update_field *field = + (struct update_field *) rope_leaf_data(node); u32 field_len = update_field_len(field); new_tuple_len += (varint32_sizeof(field_len) + field_len + field->tail_len); } if (new_tuple_len == 0) - tnt_raise(ClientError, :ER_TUPLE_IS_EMPTY); + tnt_raise(ClientError, ER_TUPLE_IS_EMPTY); return new_tuple_len; } @@ -572,8 +577,8 @@ update_calc_new_tuple_length(struct rope *rope) static void do_update_ops(struct rope *rope, struct tuple *new_tuple) { - void *new_data = new_tuple->data; - void *new_data_end = new_data + new_tuple->bsize; + char *new_data = (char *) new_tuple->data; + char *new_data_end = new_data + new_tuple->bsize; new_tuple->field_count = 0; @@ -583,11 +588,12 @@ do_update_ops(struct rope *rope, struct tuple *new_tuple) rope_iter_create(&it, rope); for (node = rope_iter_start(&it); node; node = rope_iter_next(&it)) { - struct update_field *field = rope_leaf_data(node); + struct update_field *field = (struct update_field *) + rope_leaf_data(node); u32 field_count = rope_leaf_size(node); u32 field_len = update_field_len(field); - new_data = pack_varint32(new_data, field_len); + new_data = (char *) pack_varint32(new_data, field_len); const void *old_field = field->old; void *new_field = (STAILQ_EMPTY(&field->ops) ? @@ -643,12 +649,12 @@ static struct update_op * update_read_ops(const void **reqpos, const void *reqend, u32 op_cnt) { if (op_cnt > BOX_UPDATE_OP_CNT_MAX) - tnt_raise(IllegalParams, :"too many operations for update"); + tnt_raise(IllegalParams, "too many operations for update"); if (op_cnt == 0) - tnt_raise(IllegalParams, :"no operations for update"); + tnt_raise(IllegalParams, "no operations for update"); /* Read update operations. */ - struct update_op *ops = palloc(fiber->gc_pool, op_cnt * - sizeof(struct update_op)); + struct update_op *ops = (struct update_op *) palloc(fiber->gc_pool, + op_cnt * sizeof(struct update_op)); struct update_op *op = ops, *ops_end = ops + op_cnt; for (; op < ops_end; op++) { /* Read operation */ @@ -656,7 +662,7 @@ update_read_ops(const void **reqpos, const void *reqend, u32 op_cnt) op->opcode = pick_u8(reqpos, reqend); if (op->opcode >= UPDATE_OP_MAX) - tnt_raise(ClientError, :ER_UNKNOWN_UPDATE_OP); + tnt_raise(ClientError, ER_UNKNOWN_UPDATE_OP); op->meta = &update_op_meta[op->opcode]; op->arg.set.value = pick_field(reqpos, reqend); @@ -664,7 +670,7 @@ update_read_ops(const void **reqpos, const void *reqend, u32 op_cnt) } /* Check the remainder length, the request must be fully read. */ if (*reqpos != reqend) - tnt_raise(IllegalParams, :"can't unpack request"); + tnt_raise(IllegalParams, "can't unpack request"); return ops; } @@ -673,7 +679,7 @@ execute_update(struct request *request, struct txn *txn) { txn_add_redo(txn, request->type, request->data, request->len); const void **reqpos = &request->data; - const void *reqend = request->data + request->len; + const void *reqend = (const char *) request->data + request->len; struct space *sp = read_space(reqpos, reqend); request->flags |= (pick_u32(reqpos, reqend) & BOX_ALLOWED_REQUEST_FLAGS); @@ -684,7 +690,7 @@ execute_update(struct request *request, struct txn *txn) Index *pk = space_index(sp, 0); /* Try to find the tuple by primary key. */ - struct tuple *old_tuple = [pk findByKey :key :key_part_count]; + struct tuple *old_tuple = pk->findByKey(key, key_part_count); if (old_tuple == NULL) return; @@ -698,14 +704,14 @@ execute_update(struct request *request, struct txn *txn) size_t new_tuple_len = update_calc_new_tuple_length(rope); struct tuple *new_tuple = tuple_alloc(new_tuple_len); - @try { + try { do_update_ops(rope, new_tuple); space_validate_tuple(sp, new_tuple); txn_replace(txn, sp, old_tuple, new_tuple, DUP_INSERT); - } @catch (tnt_Exception *e) { + } catch (const Exception& e) { tuple_free(new_tuple); - @throw; + throw; } } @@ -715,7 +721,7 @@ static void execute_select(struct request *request, struct port *port) { const void **reqpos = &request->data; - const void *reqend = request->data + request->len; + const void *reqend = (const char *) request->data + request->len; struct space *sp = read_space(reqpos, reqend); u32 index_no = pick_u32(reqpos, reqend); Index *index = index_find(sp, index_no); @@ -723,7 +729,7 @@ execute_select(struct request *request, struct port *port) u32 limit = pick_u32(reqpos, reqend); u32 count = pick_u32(reqpos, reqend); if (count == 0) - tnt_raise(IllegalParams, :"tuple count must be positive"); + tnt_raise(IllegalParams, "tuple count must be positive"); ERROR_INJECT_EXCEPTION(ERRINJ_TESTING); @@ -739,8 +745,8 @@ execute_select(struct request *request, struct port *port) u32 key_part_count; const void *key = read_key(reqpos, reqend, &key_part_count); - struct iterator *it = index->position; - [index initIterator: it :ITER_EQ :key :key_part_count]; + struct iterator *it = index->primaryIterator(); + index->initIterator(it, ITER_EQ, key, key_part_count); struct tuple *tuple; while ((tuple = it->next(it)) != NULL) { @@ -756,7 +762,7 @@ execute_select(struct request *request, struct port *port) } } if (*reqpos != reqend) - tnt_raise(IllegalParams, :"can't unpack request"); + tnt_raise(IllegalParams, "can't unpack request"); } static void @@ -765,7 +771,7 @@ execute_delete(struct request *request, struct txn *txn) u32 type = request->type; txn_add_redo(txn, type, request->data, request->len); const void **reqpos = &request->data; - const void *reqend = request->data + request->len; + const void *reqend = (const char *) request->data + request->len; struct space *sp = read_space(reqpos, reqend); if (type == DELETE) { request->flags |= pick_u32(reqpos, reqend) & @@ -776,7 +782,7 @@ execute_delete(struct request *request, struct txn *txn) const void *key = read_key(reqpos, reqend, &key_part_count); /* Try to find tuple by primary key */ Index *pk = space_index(sp, 0); - struct tuple *old_tuple = [pk findByKey :key :key_part_count]; + struct tuple *old_tuple = pk->findByKey(key, key_part_count); if (old_tuple == NULL) return; @@ -809,11 +815,12 @@ request_create(u32 type, const void *data, u32 len) { if (request_check_type(type)) { say_error("Unsupported request = %" PRIi32 "", type); - tnt_raise(IllegalParams, :"unsupported command code, " + tnt_raise(IllegalParams, "unsupported command code, " "check the error log"); } request_check_type(type); - struct request *request = palloc(fiber->gc_pool, sizeof(struct request)); + struct request *request = (struct request *) + palloc(fiber->gc_pool, sizeof(struct request)); request->type = type; request->data = data; request->len = len; diff --git a/src/box/space.m b/src/box/space.cc similarity index 81% rename from src/box/space.m rename to src/box/space.cc index ba19094523e87d2637f19fc0672c9fc840095a4b..7b531bccff49a62c341910762c5899b14fe2ea78 100644 --- a/src/box/space.m +++ b/src/box/space.cc @@ -29,8 +29,10 @@ #include "space.h" #include <stdlib.h> #include <string.h> -#include <cfg/tarantool_box_cfg.h> +extern "C" { #include <cfg/warning.h> +#include <cfg/tarantool_box_cfg.h> +} /* extern "C" */ #include <tarantool.h> #include <exception.h> #include "tuple.h" @@ -52,10 +54,10 @@ space_create(u32 space_no, struct key_def *key_defs, u32 key_count, u32 arity) struct space *space = space_by_n(space_no); if (space) panic("Space %d is already exists", space_no); - space = calloc(sizeof(struct space), 1); + space = (struct space *) calloc(sizeof(struct space), 1); space->no = space_no; - const struct mh_i32ptr_node_t node = { .key = space->no, .val = space }; + const struct mh_i32ptr_node_t node = { space->no, space }; mh_i32ptr_put(spaces, &node, NULL, NULL); space->arity = arity; @@ -70,11 +72,11 @@ space_create(u32 space_no, struct key_def *key_defs, u32 key_count, u32 arity) struct space * space_by_n(u32 n) { - const struct mh_i32ptr_node_t node = { .key = n }; + const struct mh_i32ptr_node_t node = { n, NULL }; mh_int_t space = mh_i32ptr_get(spaces, &node, NULL); if (space == mh_end(spaces)) return NULL; - return mh_i32ptr_node(spaces, space)->val; + return (struct space *) mh_i32ptr_node(spaces, space)->val; } /** Return the number of active indexes in a space. */ @@ -101,7 +103,8 @@ space_foreach(void (*func)(struct space *sp, void *udata), void *udata) { mh_int_t i; mh_foreach(spaces, i) { - struct space *space = mh_i32ptr_node(spaces, i)->val; + struct space *space = (struct space *) + mh_i32ptr_node(spaces, i)->val; func(space, udata); } } @@ -127,7 +130,7 @@ space_replace(struct space *sp, struct tuple *old_tuple, struct tuple *new_tuple, enum dup_replace_mode mode) { u32 i = 0; - @try { + try { /* Update the primary key */ Index *pk = sp->index[0]; assert(pk->key_def->is_unique); @@ -136,23 +139,23 @@ space_replace(struct space *sp, struct tuple *old_tuple, * has to find and delete it, or raise an * error. */ - old_tuple = [pk replace: old_tuple :new_tuple :mode]; + old_tuple = pk->replace(old_tuple, new_tuple, mode); assert(old_tuple || new_tuple); u32 n = index_count(sp); /* Update secondary keys */ for (i = i + 1; i < n; i++) { Index *index = sp->index[i]; - [index replace: old_tuple :new_tuple :DUP_INSERT]; + index->replace(old_tuple, new_tuple, DUP_INSERT); } return old_tuple; - } @catch (tnt_Exception *e) { + } catch (const Exception& e) { /* Rollback all changes */ for (; i > 0; i--) { Index *index = sp->index[i-1]; - [index replace: new_tuple: old_tuple: DUP_INSERT]; + index->replace(new_tuple, old_tuple, DUP_INSERT); } - @throw; + throw; } assert(false); @@ -165,11 +168,11 @@ space_validate_tuple(struct space *sp, struct tuple *new_tuple) /* Check to see if the tuple has a sufficient number of fields. */ if (new_tuple->field_count < sp->max_fieldno) tnt_raise(IllegalParams, - :"tuple must have all indexed fields"); + "tuple must have all indexed fields"); if (sp->arity > 0 && sp->arity != new_tuple->field_count) tnt_raise(IllegalParams, - :"tuple field count must match space cardinality"); + "tuple field count must match space cardinality"); /* Sweep through the tuple and check the field sizes. */ const u8 *data = new_tuple->data; @@ -183,11 +186,11 @@ space_validate_tuple(struct space *sp, struct tuple *new_tuple) */ if (sp->field_types[f] == NUM) { if (len != sizeof(u32)) - tnt_raise(ClientError, :ER_KEY_FIELD_TYPE, + tnt_raise(ClientError, ER_KEY_FIELD_TYPE, "u32"); } else if (sp->field_types[f] == NUM64) { if (len != sizeof(u64)) - tnt_raise(ClientError, :ER_KEY_FIELD_TYPE, + tnt_raise(ClientError, ER_KEY_FIELD_TYPE, "u64"); } } @@ -199,12 +202,13 @@ space_free(void) mh_int_t i; mh_foreach(spaces, i) { - struct space *space = mh_i32ptr_node(spaces, i)->val; + struct space *space = (struct space *) + mh_i32ptr_node(spaces, i)->val; mh_i32ptr_del(spaces, i, NULL); for (u32 j = 0 ; j < space->key_count; j++) { Index *index = space->index[j]; - [index free]; + delete index; key_free(&space->key_defs[j]); } @@ -227,7 +231,7 @@ key_init(struct key_def *def, struct tarantool_cfg_space_index *cfg_index) /* Calculate key part count and maximal field number. */ for (u32 k = 0; cfg_index->key_field[k] != NULL; ++k) { - typeof(cfg_index->key_field[k]) cfg_key = cfg_index->key_field[k]; + auto cfg_key = cfg_index->key_field[k]; if (cfg_key->fieldno == -1) { /* last filled key reached */ @@ -239,14 +243,15 @@ key_init(struct key_def *def, struct tarantool_cfg_space_index *cfg_index) } /* init def array */ - def->parts = malloc(sizeof(struct key_part) * def->part_count); + def->parts = (struct key_part *) malloc(sizeof(struct key_part) * + def->part_count); if (def->parts == NULL) { panic("can't allocate def parts array for index"); } /* init compare order array */ def->max_fieldno++; - def->cmp_order = malloc(def->max_fieldno * sizeof(u32)); + def->cmp_order = (u32 *) malloc(def->max_fieldno * sizeof(u32)); if (def->cmp_order == NULL) { panic("can't allocate def cmp_order array for index"); } @@ -256,7 +261,7 @@ key_init(struct key_def *def, struct tarantool_cfg_space_index *cfg_index) /* fill fields and compare order */ for (u32 k = 0; cfg_index->key_field[k] != NULL; ++k) { - typeof(cfg_index->key_field[k]) cfg_key = cfg_index->key_field[k]; + auto cfg_key = cfg_index->key_field[k]; if (cfg_key->fieldno == -1) { /* last filled key reached */ @@ -295,7 +300,8 @@ space_init_field_types(struct space *space) /* alloc & init field type info */ space->max_fieldno = max_fieldno; - space->field_types = calloc(max_fieldno, sizeof(enum field_data_type)); + space->field_types = (enum field_data_type *) + calloc(max_fieldno, sizeof(enum field_data_type)); /* extract field type info */ for (i = 0; i < key_count; i++) { @@ -340,7 +346,7 @@ space_config() if (space) panic("space %u is already exists", i); - space = calloc(sizeof(struct space), 1); + space = (struct space *) calloc(sizeof(struct space), 1); space->no = i; space->arity = (cfg_space->cardinality != -1) ? @@ -356,30 +362,29 @@ space_config() } - space->key_defs = malloc(space->key_count * - sizeof(struct key_def)); + space->key_defs = (struct key_def *) malloc(space->key_count * + sizeof(struct key_def)); if (space->key_defs == NULL) { panic("can't allocate key def array"); } for (u32 j = 0; cfg_space->index[j] != NULL; ++j) { - typeof(cfg_space->index[j]) cfg_index = cfg_space->index[j]; + auto cfg_index = cfg_space->index[j]; key_init(&space->key_defs[j], cfg_index); } space_init_field_types(space); /* fill space indexes */ for (u32 j = 0; cfg_space->index[j] != NULL; ++j) { - typeof(cfg_space->index[j]) cfg_index = cfg_space->index[j]; + auto cfg_index = cfg_space->index[j]; enum index_type type = STR2ENUM(index_type, cfg_index->type); struct key_def *key_def = &space->key_defs[j]; - Index *index = [[Index alloc :type :key_def :space] - init :key_def :space]; + Index *index = Index::factory(type, key_def, space); assert (index != NULL); space->index[j] = index; } const struct mh_i32ptr_node_t node = - { .key = space->no, .val = space }; + { space->no, space }; mh_i32ptr_put(spaces, &node, NULL, NULL); say_info("space %i successfully configured", i); } @@ -402,9 +407,10 @@ begin_build_primary_indexes(void) mh_int_t i; mh_foreach(spaces, i) { - struct space *space = mh_i32ptr_node(spaces, i)->val; + struct space *space = (struct space *) + mh_i32ptr_node(spaces, i)->val; Index *index = space->index[0]; - [index beginBuild]; + index->beginBuild(); } } @@ -413,9 +419,10 @@ end_build_primary_indexes(void) { mh_int_t i; mh_foreach(spaces, i) { - struct space *space = mh_i32ptr_node(spaces, i)->val; + struct space *space = (struct space *) + mh_i32ptr_node(spaces, i)->val; Index *index = space->index[0]; - [index endBuild]; + index->endBuild(); } primary_indexes_enabled = true; } @@ -428,7 +435,8 @@ build_secondary_indexes(void) mh_int_t i; mh_foreach(spaces, i) { - struct space *space = mh_i32ptr_node(spaces, i)->val; + struct space *space = (struct space *) + mh_i32ptr_node(spaces, i)->val; if (space->key_count <= 1) continue; /* no secondary keys */ @@ -438,7 +446,7 @@ build_secondary_indexes(void) Index *pk = space->index[0]; for (u32 j = 1; j < space->key_count; j++) { Index *index = space->index[j]; - [index build: pk]; + index->build(pk); } say_info("Space %d: done", space->no); @@ -457,10 +465,10 @@ check_spaces(struct tarantool_cfg *conf) } for (size_t i = 0; conf->space[i] != NULL; ++i) { - typeof(conf->space[i]) space = conf->space[i]; + auto space = conf->space[i]; if (i >= BOX_SPACE_MAX) { - out_warning(0, "(space = %zu) invalid id, (maximum=%u)", + out_warning(CNF_OK, "(space = %zu) invalid id, (maximum=%u)", i, BOX_SPACE_MAX); return -1; } @@ -476,7 +484,7 @@ check_spaces(struct tarantool_cfg *conf) } if (conf->memcached_port && i == conf->memcached_space) { - out_warning(0, "Space %zu is already used as " + out_warning(CNF_OK, "Space %zu is already used as " "memcached_space.", i); return -1; } @@ -484,7 +492,7 @@ check_spaces(struct tarantool_cfg *conf) /* at least one index in space must be defined * */ if (space->index == NULL) { - out_warning(0, "(space = %zu) " + out_warning(CNF_OK, "(space = %zu) " "at least one index must be defined", i); return -1; } @@ -493,21 +501,21 @@ check_spaces(struct tarantool_cfg *conf) /* check spaces indexes */ for (size_t j = 0; space->index[j] != NULL; ++j) { - typeof(space->index[j]) index = space->index[j]; + auto index = space->index[j]; u32 key_part_count = 0; enum index_type index_type; /* check index bound */ if (j >= BOX_INDEX_MAX) { /* maximum index in space reached */ - out_warning(0, "(space = %zu index = %zu) " + out_warning(CNF_OK, "(space = %zu index = %zu) " "too many indexed (%u maximum)", i, j, BOX_INDEX_MAX); return -1; } /* at least one key in index must be defined */ if (index->key_field == NULL) { - out_warning(0, "(space = %zu index = %zu) " + out_warning(CNF_OK, "(space = %zu index = %zu) " "at least one field must be defined", i, j); return -1; } @@ -515,12 +523,12 @@ check_spaces(struct tarantool_cfg *conf) /* check unique property */ if (index->unique == -1) { /* unique property undefined */ - out_warning(0, "(space = %zu index = %zu) " + out_warning(CNF_OK, "(space = %zu index = %zu) " "unique property is undefined", i, j); } for (size_t k = 0; index->key_field[k] != NULL; ++k) { - typeof(index->key_field[k]) key = index->key_field[k]; + auto key = index->key_field[k]; if (key->fieldno == -1) { /* last key reached */ @@ -529,7 +537,7 @@ check_spaces(struct tarantool_cfg *conf) if (key->fieldno >= BOX_FIELD_MAX) { /* maximum index in space reached */ - out_warning(0, "(space = %zu index = %zu) " + out_warning(CNF_OK, "(space = %zu index = %zu) " "invalid field number (%u maximum)", i, j, BOX_FIELD_MAX); return -1; @@ -537,7 +545,7 @@ check_spaces(struct tarantool_cfg *conf) /* key must has valid type */ if (STR2ENUM(field_data_type, key->type) == field_data_type_MAX) { - out_warning(0, "(space = %zu index = %zu) " + out_warning(CNF_OK, "(space = %zu index = %zu) " "unknown field data type: `%s'", i, j, key->type); return -1; } @@ -551,7 +559,7 @@ check_spaces(struct tarantool_cfg *conf) /* Check key part count. */ if (key_part_count == 0) { - out_warning(0, "(space = %zu index = %zu) " + out_warning(CNF_OK, "(space = %zu index = %zu) " "at least one field must be defined", i, j); return -1; } @@ -560,14 +568,14 @@ check_spaces(struct tarantool_cfg *conf) /* check index type */ if (index_type == index_type_MAX) { - out_warning(0, "(space = %zu index = %zu) " + out_warning(CNF_OK, "(space = %zu index = %zu) " "unknown index type '%s'", i, j, index->type); return -1; } /* First index must be unique. */ if (j == 0 && index->unique == false) { - out_warning(0, "(space = %zu) space first index must be unique", i); + out_warning(CNF_OK, "(space = %zu) space first index must be unique", i); return -1; } @@ -576,14 +584,14 @@ check_spaces(struct tarantool_cfg *conf) /* check hash index */ /* hash index must has single-field key */ if (key_part_count != 1) { - out_warning(0, "(space = %zu index = %zu) " - "hash index must has a single-field key", i, j); + out_warning(CNF_OK, "(space = %zu index = %zu) " + "hash index must has a single-field key", i, j); return -1; } /* hash index must be unique */ if (!index->unique) { - out_warning(0, "(space = %zu index = %zu) " - "hash index must be unique", i, j); + out_warning(CNF_OK, "(space = %zu index = %zu) " + "hash index must be unique", i, j); return -1; } break; @@ -594,13 +602,13 @@ check_spaces(struct tarantool_cfg *conf) /* check bitset index */ /* bitset index must has single-field key */ if (key_part_count != 1) { - out_warning(0, "(space = %zu index = %zu) " + out_warning(CNF_OK, "(space = %zu index = %zu) " "bitset index must has a single-field key", i, j); return -1; } /* bitset index must not be unique */ if (index->unique) { - out_warning(0, "(space = %zu index = %zu) " + out_warning(CNF_OK, "(space = %zu index = %zu) " "bitset index must be non-unique", i, j); return -1; } @@ -612,12 +620,12 @@ check_spaces(struct tarantool_cfg *conf) /* Check for index field type conflicts */ if (max_key_fieldno > 0) { - char *types = alloca(max_key_fieldno); + char *types = (char *) alloca(max_key_fieldno); memset(types, 0, max_key_fieldno); for (size_t j = 0; space->index[j] != NULL; ++j) { - typeof(space->index[j]) index = space->index[j]; + auto index = space->index[j]; for (size_t k = 0; index->key_field[k] != NULL; ++k) { - typeof(index->key_field[k]) key = index->key_field[k]; + auto key = index->key_field[k]; if (key->fieldno == -1) break; @@ -628,7 +636,7 @@ check_spaces(struct tarantool_cfg *conf) if (types[f] == UNKNOWN) { types[f] = t; } else { - out_warning(0, "(space = %zu fieldno = %zu) " + out_warning(CNF_OK, "(space = %zu fieldno = %zu) " "index field type mismatch", i, f); return -1; } diff --git a/src/box/space.h b/src/box/space.h index e06fbf8410e595be7f8726cd440967226ed7eaab..7f60c6913e280ab2f2790fa4bc104e732b02f88e 100644 --- a/src/box/space.h +++ b/src/box/space.h @@ -214,7 +214,7 @@ space_find(u32 space_no) if (s) return s; - tnt_raise(ClientError, :ER_NO_SUCH_SPACE, space_no); + tnt_raise(ClientError, ER_NO_SUCH_SPACE, space_no); } @@ -283,7 +283,7 @@ index_find(struct space *sp, u32 index_no) { Index *idx = space_index(sp, index_no); if (idx == NULL) - tnt_raise(LoggedError, :ER_NO_SUCH_INDEX, index_no, + tnt_raise(LoggedError, ER_NO_SUCH_INDEX, index_no, space_n(sp)); return idx; } diff --git a/src/box/tree_index.m b/src/box/tree_index.cc similarity index 75% rename from src/box/tree_index.m rename to src/box/tree_index.cc index ae76152321f946cae23801c352d21da8b58be948..c0fd07060a00a1dc91509e3116ba03b3e8f7ce5d 100644 --- a/src/box/tree_index.m +++ b/src/box/tree_index.cc @@ -36,7 +36,7 @@ /* {{{ Utilities. *************************************************/ static struct index_traits tree_index_traits = { - .allows_partial_key = true, + /* .allows_partial_key = */ true, }; /** @@ -320,12 +320,12 @@ fold_with_sparse_parts(struct key_def *key_def, struct tuple *tuple, union spars if (part != BOX_FIELD_MAX) { if (key_def->parts[part].type == NUM) { if (len != sizeof parts[part].num32) { - tnt_raise(IllegalParams, :"key is not u32"); + tnt_raise(IllegalParams, "key is not u32"); } memcpy(&parts[part].num32, data, len); } else if (key_def->parts[part].type == NUM64) { if (len != sizeof parts[part].num64) { - tnt_raise(IllegalParams, :"key is not u64"); + tnt_raise(IllegalParams, "key is not u64"); } memcpy(&parts[part].num64, data, len); } else if (len <= sizeof(parts[part].str.data)) { @@ -359,11 +359,11 @@ fold_with_key_parts(struct key_def *key_def, struct key_data *key_data) if (key_def->parts[part].type == NUM) { if (len != sizeof parts[part].num32) - tnt_raise(IllegalParams, :"key is not u32"); + tnt_raise(IllegalParams, "key is not u32"); memcpy(&parts[part].num32, data, len); } else if (key_def->parts[part].type == NUM64) { if (len != sizeof parts[part].num64) - tnt_raise(IllegalParams, :"key is not u64"); + tnt_raise(IllegalParams, "key is not u64"); memcpy(&parts[part].num64, data, len); } else if (len <= sizeof(parts[part].str.data)) { parts[part].str.length = len; @@ -556,7 +556,7 @@ dense_node_compare(struct key_def *key_def, u32 first_field, assert(first_field + part_count <= tuple_b->field_count); /* Allocate space for offsets. */ - u32 *off_a = alloca(2 * part_count * sizeof(u32)); + u32 *off_a = (u32 *) alloca(2 * part_count * sizeof(u32)); u32 *off_b = off_a + part_count; /* Find field offsets. */ @@ -580,8 +580,8 @@ dense_node_compare(struct key_def *key_def, u32 first_field, u32 field = key_def->parts[part].fieldno; u8 *ad = tuple_a->data + off_a[field - first_field]; u8 *bd = tuple_b->data + off_b[field - first_field]; - u32 al = load_varint32((void *) &ad); - u32 bl = load_varint32((void *) &bd); + u32 al = load_varint32((const void **) &ad); + u32 bl = load_varint32((const void **) &bd); int r = dense_part_compare(key_def->parts[part].type, ad, al, bd, bl); if (r) { @@ -674,7 +674,7 @@ dense_key_node_compare(struct key_def *key_def, assert(first_field + part_count <= tuple->field_count); /* Allocate space for offsets. */ - u32 *off = alloca(part_count * sizeof(u32)); + u32 *off = (u32 *) alloca(part_count * sizeof(u32)); /* Find field offsets. */ off[0] = offset; @@ -693,7 +693,7 @@ dense_key_node_compare(struct key_def *key_def, for (u32 part = 0; part < part_count; ++part) { u32 field = key_def->parts[part].fieldno; const u8 *bd = tuple->data + off[field - first_field]; - u32 bl = load_varint32((void *) &bd); + u32 bl = load_varint32((const void **) &bd); int r = dense_key_part_compare(key_def->parts[part].type, key_data->data, key_data->parts[part], @@ -723,7 +723,7 @@ linear_key_node_compare(struct key_def *key_def, part_count = key_data->part_count; u8 *bd = tuple->data + offset; for (u32 part = 0; part < part_count; ++part) { - u32 bl = load_varint32((void *) &bd); + u32 bl = load_varint32((const void **) &bd); int r = dense_key_part_compare(key_def->parts[part].type, key_data->data, key_data->parts[part], @@ -742,7 +742,7 @@ linear_key_node_compare(struct key_def *key_def, struct tree_iterator { struct iterator base; - TreeIndex *index; + const TreeIndex *index; struct sptree_index_iterator *iter; struct key_data key_data; }; @@ -771,7 +771,7 @@ tree_iterator_ge(struct iterator *iterator) { struct tree_iterator *it = tree_iterator(iterator); void *node = sptree_index_iterator_next(it->iter); - return [it->index unfold: node]; + return it->index->unfold(node); } static struct tuple * @@ -779,7 +779,7 @@ tree_iterator_le(struct iterator *iterator) { struct tree_iterator *it = tree_iterator(iterator); void *node = sptree_index_iterator_reverse_next(it->iter); - return [it->index unfold: node]; + return it->index->unfold(node); } static struct tuple * @@ -788,8 +788,9 @@ tree_iterator_eq(struct iterator *iterator) struct tree_iterator *it = tree_iterator(iterator); void *node = sptree_index_iterator_next(it->iter); - if (node && it->index->tree.compare(&it->key_data, node, it->index) == 0) - return [it->index unfold: node]; + if (node && it->index->tree.compare(&it->key_data, node, + (void *) it->index) == 0) + return it->index->unfold(node); return NULL; } @@ -801,8 +802,9 @@ tree_iterator_req(struct iterator *iterator) void *node = sptree_index_iterator_reverse_next(it->iter); if (node != NULL - && it->index->tree.compare(&it->key_data, node, it->index) == 0) { - return [it->index unfold: node]; + && it->index->tree.compare(&it->key_data, node, + (void *) it->index) == 0) { + return it->index->unfold(node); } return NULL; @@ -816,9 +818,9 @@ tree_iterator_lt(struct iterator *iterator) void *node ; while ((node = sptree_index_iterator_reverse_next(it->iter)) != NULL) { if (it->index->tree.compare(&it->key_data, node, - it->index) != 0) { + (void *) it->index) != 0) { it->base.next = tree_iterator_le; - return [it->index unfold: node]; + return it->index->unfold(node); } } @@ -833,9 +835,9 @@ tree_iterator_gt(struct iterator *iterator) void *node; while ((node = sptree_index_iterator_next(it->iter)) != NULL) { if (it->index->tree.compare(&it->key_data, node, - it->index) != 0) { + (void *) it->index) != 0) { it->base.next = tree_iterator_ge; - return [it->index unfold: node]; + return it->index->unfold(node); } } @@ -846,186 +848,266 @@ tree_iterator_gt(struct iterator *iterator) /* {{{ TreeIndex -- base tree index class *************************/ -@class SparseTreeIndex; -@class DenseTreeIndex; -@class Num32TreeIndex; -@class FixedTreeIndex; +class SparseTreeIndex: public TreeIndex { +public: + SparseTreeIndex(struct key_def *key_def, struct space *space); -@interface SparseTreeIndex: TreeIndex -@end +// protected: + size_t + node_size() const; -@interface DenseTreeIndex: TreeIndex { - @public + tree_cmp_t + node_cmp() const; + + tree_cmp_t + dup_node_cmp() const; + + tree_cmp_t + key_node_cmp() const; + + void + fold(void *node, struct tuple *tuple) const; + + struct tuple * + unfold(const void *node) const; +}; + + +class DenseTreeIndex: public TreeIndex { +public: + DenseTreeIndex(struct key_def *key_def, struct space *space); + +// protected: + size_t + node_size() const; + + tree_cmp_t + node_cmp() const; + + tree_cmp_t + dup_node_cmp() const; + + tree_cmp_t + key_node_cmp() const; + + void + fold(void *node, struct tuple *tuple) const; + + struct tuple * + unfold(const void *node) const; + +//private: u32 first_field; -} -@end +}; + +class Num32TreeIndex: public TreeIndex { +public: + Num32TreeIndex(struct key_def *key_def, struct space *space); + +// protected: + size_t + node_size() const; + + tree_cmp_t + node_cmp() const; + + tree_cmp_t + dup_node_cmp() const; -@interface Num32TreeIndex: TreeIndex -@end + tree_cmp_t + key_node_cmp() const; -@interface FixedTreeIndex: TreeIndex { - @public + void + fold(void *node, struct tuple *tuple) const; + + struct tuple * + unfold(const void *node) const; +}; + + +class FixedTreeIndex: public TreeIndex { +public: + FixedTreeIndex(struct key_def *key_def, struct space *space); + +protected: + size_t + node_size() const; + + tree_cmp_t + node_cmp() const; + + tree_cmp_t + dup_node_cmp() const; + + tree_cmp_t + key_node_cmp() const; + + void + fold(void *node, struct tuple *tuple) const; + + struct tuple * + unfold(const void *node) const; +//private: +public: u32 first_field; u32 first_offset; -} -@end - -@implementation TreeIndex +}; -+ (struct index_traits *) traits -{ - return &tree_index_traits; -} -+ (Index *) alloc: (struct key_def *) key_def :(struct space *) space +TreeIndex * +TreeIndex::factory(struct key_def *key_def, struct space *space) { enum tree_type type = find_tree_type(space, key_def); switch (type) { case TREE_SPARSE: - return [SparseTreeIndex alloc]; + return new SparseTreeIndex(key_def, space); case TREE_DENSE: - return [DenseTreeIndex alloc]; + return new DenseTreeIndex(key_def, space); case TREE_NUM32: - return [Num32TreeIndex alloc]; + return new Num32TreeIndex(key_def, space); case TREE_FIXED: - return [FixedTreeIndex alloc]; + return new FixedTreeIndex(key_def, space); default: assert(false); return 0; } } -- (void) free +TreeIndex::TreeIndex(struct key_def *key_def, struct space *space) + : Index(key_def, space) { - sptree_index_destroy(&tree); - [super free]; + memset(&tree, 0, sizeof tree); } -- (id) init: (struct key_def *) key_def_arg :(struct space *) space_arg +TreeIndex::~TreeIndex() { - self = [super init: key_def_arg :space_arg]; - if (self == NULL) - return NULL; - - memset(&tree, 0, sizeof tree); - return self; + sptree_index_destroy(&tree); } -- (size_t) size +size_t +TreeIndex::size() const { return tree.size; } -- (struct tuple *) min +struct tuple * +TreeIndex::min() const { void *node = sptree_index_first(&tree); - return [self unfold: node]; + return unfold(node); } -- (struct tuple *) max +struct tuple * +TreeIndex::max() const { void *node = sptree_index_last(&tree); - return [self unfold: node]; + return unfold(node); } -- (struct tuple *) random: (u32) rnd +struct tuple * +TreeIndex::random(u32 rnd) const { void *node = sptree_index_random(&tree, rnd); - return [self unfold: node]; + return unfold(node); } -- (struct tuple *) findByKey: (const void *) key : (u32) part_count +struct tuple * +TreeIndex::findByKey(const void *key, u32 part_count) const { assert(key_def->is_unique); check_key_parts(key_def, part_count, false); - struct key_data *key_data - = alloca(sizeof(struct key_data) + + struct key_data *key_data = (struct key_data *) + alloca(sizeof(struct key_data) + _SIZEOF_SPARSE_PARTS(part_count)); - key_data->data = key; + key_data->data = (const u8 *) key; key_data->part_count = part_count; fold_with_key_parts(key_def, key_data); void *node = sptree_index_find(&tree, key_data); - return [self unfold: node]; + return unfold(node); } -- (struct tuple *) findByTuple: (struct tuple *) tuple +struct tuple * +TreeIndex::findByTuple(struct tuple *tuple) const { assert(key_def->is_unique); if (tuple->field_count < key_def->max_fieldno) - tnt_raise(IllegalParams, :"tuple must have all indexed fields"); + tnt_raise(IllegalParams, "tuple must have all indexed fields"); - struct key_data *key_data - = alloca(sizeof(struct key_data) + _SIZEOF_SPARSE_PARTS(tuple->field_count)); + struct key_data *key_data = (struct key_data *) + alloca(sizeof(struct key_data) + + _SIZEOF_SPARSE_PARTS(tuple->field_count)); key_data->data = tuple->data; key_data->part_count = tuple->field_count; fold_with_sparse_parts(key_def, tuple, key_data->parts); void *node = sptree_index_find(&tree, key_data); - return [self unfold: node]; + return unfold(node); } -- (struct tuple *) replace: (struct tuple *) old_tuple - :(struct tuple *) new_tuple - :(enum dup_replace_mode) mode +struct tuple * +TreeIndex::replace(struct tuple *old_tuple, struct tuple *new_tuple, + enum dup_replace_mode mode) { - size_t node_size = [self node_size]; + size_t node_size = this->node_size(); void *new_node = alloca(node_size); void *old_node = alloca(node_size); uint32_t errcode; if (new_tuple) { void *dup_node = old_node; - [self fold: new_node :new_tuple]; + fold(new_node, new_tuple); /* Try to optimistically replace the new_tuple. */ sptree_index_replace(&tree, new_node, &dup_node); - struct tuple *dup_tuple = [self unfold: dup_node]; + struct tuple *dup_tuple = unfold(dup_node); errcode = replace_check_dup(old_tuple, dup_tuple, mode); if (errcode) { sptree_index_delete(&tree, new_node); if (dup_node) sptree_index_replace(&tree, dup_node, NULL); - tnt_raise(ClientError, :errcode, index_n(self)); + tnt_raise(ClientError, errcode, index_n(this)); } if (dup_tuple) return dup_tuple; } if (old_tuple) { - [self fold: old_node :old_tuple]; + fold(old_node, old_tuple); sptree_index_delete(&tree, old_node); } return old_tuple; } -- (struct iterator *) allocIterator +struct iterator * +TreeIndex::allocIterator() const { assert(key_def->part_count); - struct tree_iterator *it - = malloc(sizeof(struct tree_iterator) + SIZEOF_SPARSE_PARTS(key_def)); + struct tree_iterator *it = (struct tree_iterator *) + malloc(sizeof(struct tree_iterator) + + SIZEOF_SPARSE_PARTS(key_def)); if (it) { memset(it, 0, sizeof(struct tree_iterator)); - it->index = self; + it->index = this; it->base.free = tree_iterator_free; } return (struct iterator *) it; } -- (void) initIterator: (struct iterator *) iterator - :(enum iterator_type) type - :(const void *) key :(u32) part_count +void +TreeIndex::initIterator(struct iterator *iterator, enum iterator_type type, + const void *key, u32 part_count) const { struct tree_iterator *it = tree_iterator(iterator); if (part_count != 0) { check_key_parts(key_def, part_count, - traits->allows_partial_key); + tree_index_traits.allows_partial_key); } else { /* * If no key is specified, downgrade equality @@ -1034,7 +1116,7 @@ tree_iterator_gt(struct iterator *iterator) type = iterator_type_is_reverse(type) ? ITER_LE : ITER_GE; key = NULL; } - it->key_data.data = key; + it->key_data.data = (const u8 *) key; it->key_data.part_count = part_count; fold_with_key_parts(key_def, &it->key_data); @@ -1067,29 +1149,31 @@ tree_iterator_gt(struct iterator *iterator) it->base.next = tree_iterator_lt; break; default: - tnt_raise(ClientError, :ER_UNSUPPORTED, + tnt_raise(ClientError, ER_UNSUPPORTED, "Tree index", "requested iterator type"); } } -- (void) beginBuild +void +TreeIndex::beginBuild() { - assert(index_is_primary(self)); + assert(index_is_primary(this)); tree.size = 0; tree.max_size = 64; - size_t node_size = [self node_size]; + size_t node_size = this->node_size(); size_t sz = tree.max_size * node_size; tree.members = malloc(sz); if (tree.members == NULL) { - panic("malloc(): failed to allocate %"PRI_SZ" bytes", sz); + panic("malloc(): failed to allocate %" PRI_SZ " bytes", sz); } } -- (void) buildNext: (struct tuple *) tuple +void +TreeIndex::buildNext(struct tuple *tuple) { - size_t node_size = [self node_size]; + size_t node_size = this->node_size(); if (tree.size == tree.max_size) { tree.max_size *= 2; @@ -1097,34 +1181,36 @@ tree_iterator_gt(struct iterator *iterator) size_t sz = tree.max_size * node_size; tree.members = realloc(tree.members, sz); if (tree.members == NULL) { - panic("malloc(): failed to allocate %"PRI_SZ" bytes", sz); + panic("malloc(): failed to allocate %" PRI_SZ " bytes", sz); } } void *node = ((u8 *) tree.members + tree.size * node_size); - [self fold: node :tuple]; + fold(node, tuple); tree.size++; } -- (void) endBuild +void +TreeIndex::endBuild() { - assert(index_is_primary(self)); + assert(index_is_primary(this)); u32 n_tuples = tree.size; u32 estimated_tuples = tree.max_size; void *nodes = tree.members; sptree_index_init(&tree, - [self node_size], nodes, n_tuples, estimated_tuples, - [self key_node_cmp], [self node_cmp], - self); + node_size(), nodes, n_tuples, estimated_tuples, + key_node_cmp(), node_cmp(), + this); } -- (void) build: (Index *) pk +void +TreeIndex::build(Index *pk) { - u32 n_tuples = [pk size]; + u32 n_tuples = pk->size(); u32 estimated_tuples = n_tuples * 1.2; - size_t node_size = [self node_size]; + size_t node_size = this->node_size(); void *nodes = NULL; if (n_tuples) { @@ -1136,73 +1222,33 @@ tree_iterator_gt(struct iterator *iterator) size_t sz = estimated_tuples * node_size; nodes = malloc(sz); if (nodes == NULL) { - panic("malloc(): failed to allocate %"PRI_SZ" bytes", sz); + panic("malloc(): failed to allocate %" PRI_SZ " bytes", sz); } } - struct iterator *it = pk->position; - [pk initIterator: it :ITER_ALL :NULL :0]; + struct iterator *it = pk->primaryIterator(); + pk->initIterator(it, ITER_ALL, NULL, 0); struct tuple *tuple; for (u32 i = 0; (tuple = it->next(it)) != NULL; ++i) { void *node = ((u8 *) nodes + i * node_size); - [self fold: node :tuple]; + fold(node, tuple); } if (n_tuples) { - say_info("Sorting %"PRIu32 " keys in index %" PRIu32 "...", n_tuples, - index_n(self)); + say_info("Sorting %" PRIu32 " keys in index %" PRIu32 "...", n_tuples, + index_n(this)); } /* If n_tuples == 0 then estimated_tuples = 0, elem == NULL, tree is empty */ sptree_index_init(&tree, node_size, nodes, n_tuples, estimated_tuples, - [self key_node_cmp], - key_def->is_unique ? [self node_cmp] : [self dup_node_cmp], - self); -} - -- (size_t) node_size -{ - [self subclassResponsibility: _cmd]; - return 0; -} - -- (tree_cmp_t) node_cmp -{ - [self subclassResponsibility: _cmd]; - return 0; -} - -- (tree_cmp_t) dup_node_cmp -{ - [self subclassResponsibility: _cmd]; - return 0; -} - -- (tree_cmp_t) key_node_cmp -{ - [self subclassResponsibility: _cmd]; - return 0; -} - -- (void) fold: (void *) node :(struct tuple *) tuple -{ - (void) node; - (void) tuple; - [self subclassResponsibility: _cmd]; -} - -- (struct tuple *) unfold: (const void *) node -{ - (void) node; - [self subclassResponsibility: _cmd]; - return NULL; + key_node_cmp(), + key_def->is_unique ? node_cmp() : dup_node_cmp(), + this); } -@end - /* }}} */ /* {{{ SparseTreeIndex ********************************************/ @@ -1211,8 +1257,8 @@ static int sparse_node_cmp(const void *node_a, const void *node_b, void *arg) { SparseTreeIndex *index = (SparseTreeIndex *) arg; - const struct sparse_node *node_xa = node_a; - const struct sparse_node *node_xb = node_b; + const struct sparse_node *node_xa = (const struct sparse_node *) node_a; + const struct sparse_node *node_xb = (const struct sparse_node *) node_b; return sparse_node_compare(index->key_def, node_xa->tuple, node_xa->parts, node_xb->tuple, node_xb->parts); @@ -1223,8 +1269,10 @@ sparse_dup_node_cmp(const void *node_a, const void *node_b, void *arg) { int r = sparse_node_cmp(node_a, node_b, arg); if (r == 0) { - const struct sparse_node *node_xa = node_a; - const struct sparse_node *node_xb = node_b; + const struct sparse_node *node_xa = + (const struct sparse_node *) node_a; + const struct sparse_node *node_xb = + (const struct sparse_node *) node_b; r = ta_cmp(node_xa->tuple, node_xb->tuple); } return r; @@ -1234,49 +1282,58 @@ static int sparse_key_node_cmp(const void *key, const void *node, void *arg) { SparseTreeIndex *index = (SparseTreeIndex *) arg; - const struct key_data *key_data = key; - const struct sparse_node *node_x = node; + const struct key_data *key_data = (const struct key_data *) key; + const struct sparse_node *node_x = (const struct sparse_node *) node; return sparse_key_node_compare(index->key_def, key_data, node_x->tuple, node_x->parts); } -@implementation SparseTreeIndex +SparseTreeIndex::SparseTreeIndex(struct key_def *key_def, struct space *space) + : TreeIndex(key_def, space) +{ + /* Nothing */ +} -- (size_t) node_size +size_t +SparseTreeIndex::node_size() const { return sizeof(struct sparse_node) + SIZEOF_SPARSE_PARTS(key_def); } -- (tree_cmp_t) node_cmp + +tree_cmp_t +SparseTreeIndex::node_cmp() const { return sparse_node_cmp; } -- (tree_cmp_t) dup_node_cmp +tree_cmp_t +SparseTreeIndex::dup_node_cmp() const { return sparse_dup_node_cmp; } -- (tree_cmp_t) key_node_cmp +tree_cmp_t +SparseTreeIndex::key_node_cmp() const { return sparse_key_node_cmp; } -- (void) fold: (void *) node :(struct tuple *) tuple +void +SparseTreeIndex::fold(void *node, struct tuple *tuple) const { - struct sparse_node *node_x = node; + struct sparse_node *node_x = (struct sparse_node *) node; node_x->tuple = tuple; fold_with_sparse_parts(key_def, tuple, node_x->parts); } -- (struct tuple *) unfold: (const void *) node +struct tuple * +SparseTreeIndex::unfold(const void *node) const { - const struct sparse_node *node_x = node; + const struct sparse_node *node_x = (const struct sparse_node *) node; return node_x ? node_x->tuple : NULL; } -@end - /* }}} */ /* {{{ DenseTreeIndex *********************************************/ @@ -1285,8 +1342,8 @@ static int dense_node_cmp(const void *node_a, const void *node_b, void *arg) { DenseTreeIndex *index = (DenseTreeIndex *) arg; - const struct dense_node *node_xa = node_a; - const struct dense_node *node_xb = node_b; + const struct dense_node *node_xa = (const struct dense_node *) node_a; + const struct dense_node *node_xb = (const struct dense_node *) node_b; return dense_node_compare(index->key_def, index->first_field, node_xa->tuple, node_xa->offset, node_xb->tuple, node_xb->offset); @@ -1297,8 +1354,10 @@ dense_dup_node_cmp(const void *node_a, const void *node_b, void *arg) { int r = dense_node_cmp(node_a, node_b, arg); if (r == 0) { - const struct dense_node *node_xa = node_a; - const struct dense_node *node_xb = node_b; + const struct dense_node *node_xa = + (const struct dense_node *) node_a; + const struct dense_node *node_xb = + (const struct dense_node *) node_b; r = ta_cmp(node_xa->tuple, node_xb->tuple); } return r; @@ -1308,8 +1367,8 @@ static int dense_key_node_cmp(const void *key, const void * node, void *arg) { DenseTreeIndex *index = (DenseTreeIndex *) arg; - const struct key_data *key_data = key; - const struct dense_node *node_x = node; + const struct key_data *key_data = (const struct key_data *) key; + const struct dense_node *node_x = (const struct dense_node *) node; return dense_key_node_compare(index->key_def, key_data, index->first_field, node_x->tuple, node_x->offset); @@ -1319,8 +1378,8 @@ static int linear_dense_node_cmp(const void *node_a, const void *node_b, void *arg) { DenseTreeIndex *index = (DenseTreeIndex *) arg; - const struct dense_node *node_xa = node_a; - const struct dense_node *node_xb = node_b; + const struct dense_node *node_xa = (const struct dense_node *) node_a; + const struct dense_node *node_xb = (const struct dense_node *) node_b; return linear_node_compare(index->key_def, index->first_field, node_xa->tuple, node_xa->offset, node_xb->tuple, node_xb->offset); @@ -1331,8 +1390,10 @@ linear_dense_dup_node_cmp(const void *node_a, const void *node_b, void *arg) { int r = linear_dense_node_cmp(node_a, node_b, arg); if (r == 0) { - const struct dense_node *node_xa = node_a; - const struct dense_node *node_xb = node_b; + const struct dense_node *node_xa = + (const struct dense_node *) node_a; + const struct dense_node *node_xb = + (const struct dense_node *) node_b; r = ta_cmp(node_xa->tuple, node_xb->tuple); } return r; @@ -1342,66 +1403,65 @@ static int linear_dense_key_node_cmp(const void *key, const void * node, void *arg) { DenseTreeIndex *index = (DenseTreeIndex *) arg; - const struct key_data *key_data = key; - const struct dense_node *node_x = node; + const struct key_data *key_data = (const struct key_data *) key; + const struct dense_node *node_x = (const struct dense_node *) node; return linear_key_node_compare(index->key_def, key_data, index->first_field, node_x->tuple, node_x->offset); } -@implementation DenseTreeIndex -- (id) init: (struct key_def *) key_def_arg :(struct space *) space_arg +DenseTreeIndex::DenseTreeIndex(struct key_def *key_def, struct space *space) + : TreeIndex(key_def, space) { - self = [super init: key_def_arg :space_arg]; - if (self == NULL) - return NULL; - first_field = find_first_field(key_def); - return self; } -- (size_t) node_size +size_t +DenseTreeIndex::node_size() const { return sizeof(struct dense_node); } -- (tree_cmp_t) node_cmp +tree_cmp_t +DenseTreeIndex::node_cmp() const { return key_is_linear(key_def) ? linear_dense_node_cmp : dense_node_cmp; } -- (tree_cmp_t) dup_node_cmp +tree_cmp_t +DenseTreeIndex::dup_node_cmp() const { return key_is_linear(key_def) ? linear_dense_dup_node_cmp : dense_dup_node_cmp; } -- (tree_cmp_t) key_node_cmp +tree_cmp_t +DenseTreeIndex::key_node_cmp() const { return key_is_linear(key_def) ? linear_dense_key_node_cmp : dense_key_node_cmp; } -- (void) fold: (void *) node :(struct tuple *) tuple +void +DenseTreeIndex::fold(void *node, struct tuple *tuple) const { - struct dense_node *node_x = node; + struct dense_node *node_x = (struct dense_node *) node; node_x->tuple = tuple; node_x->offset = fold_with_dense_offset(key_def, tuple); } -- (struct tuple *) unfold: (const void *) node +struct tuple * +DenseTreeIndex::unfold(const void *node) const { - const struct dense_node *node_x = node; + const struct dense_node *node_x = (const struct dense_node *) node; return node_x ? node_x->tuple : NULL; } -@end - /* }}} */ /* {{{ Num32TreeIndex *********************************************/ @@ -1410,8 +1470,8 @@ static int num32_node_cmp(const void * node_a, const void * node_b, void *arg) { (void) arg; - const struct num32_node *node_xa = node_a; - const struct num32_node *node_xb = node_b; + const struct num32_node *node_xa = (const struct num32_node *) node_a; + const struct num32_node *node_xb = (const struct num32_node *) node_b; return u32_cmp(node_xa->value, node_xb->value); } @@ -1420,8 +1480,10 @@ num32_dup_node_cmp(const void * node_a, const void * node_b, void *arg) { int r = num32_node_cmp(node_a, node_b, arg); if (r == 0) { - const struct num32_node *node_xa = node_a; - const struct num32_node *node_xb = node_b; + const struct num32_node *node_xa = + (const struct num32_node *) node_a; + const struct num32_node *node_xb = + (const struct num32_node *) node_b; r = ta_cmp(node_xa->tuple, node_xb->tuple); } return r; @@ -1431,50 +1493,58 @@ static int num32_key_node_cmp(const void * key, const void * node, void *arg) { (void) arg; - const struct key_data *key_data = key; - const struct num32_node *node_x = node; + const struct key_data *key_data = (const struct key_data *) key; + const struct num32_node *node_x = (const struct num32_node *) node; if (key_data->part_count) return u32_cmp(key_data->parts[0].num32, node_x->value); return 0; } -@implementation Num32TreeIndex +Num32TreeIndex::Num32TreeIndex(struct key_def *key_def, struct space *space) + : TreeIndex(key_def, space) +{ + /* Nothing */ +} -- (size_t) node_size +size_t +Num32TreeIndex::node_size() const { return sizeof(struct num32_node); } -- (tree_cmp_t) node_cmp +tree_cmp_t +Num32TreeIndex::node_cmp() const { return num32_node_cmp; } -- (tree_cmp_t) dup_node_cmp +tree_cmp_t +Num32TreeIndex::dup_node_cmp() const { return num32_dup_node_cmp; } -- (tree_cmp_t) key_node_cmp +tree_cmp_t +Num32TreeIndex::key_node_cmp() const { return num32_key_node_cmp; } -- (void) fold: (void *) node :(struct tuple *) tuple +void +Num32TreeIndex::fold(void *node, struct tuple *tuple) const { struct num32_node *node_x = (struct num32_node *) node; node_x->tuple = tuple; node_x->value = fold_with_num32_value(key_def, tuple); } -- (struct tuple *) unfold: (const void *) node +struct tuple * +Num32TreeIndex::unfold(const void *node) const { - const struct num32_node *node_x = node; + const struct num32_node *node_x = (const struct num32_node *) node; return node_x ? node_x->tuple : NULL; } -@end - /* }}} */ /* {{{ FixedTreeIndex *********************************************/ @@ -1483,8 +1553,8 @@ static int fixed_node_cmp(const void *node_a, const void *node_b, void *arg) { FixedTreeIndex *index = (FixedTreeIndex *) arg; - const struct fixed_node *node_xa = node_a; - const struct fixed_node *node_xb = node_b; + const struct fixed_node *node_xa = (const struct fixed_node *) node_a; + const struct fixed_node *node_xb = (const struct fixed_node *) node_b; return dense_node_compare(index->key_def, index->first_field, node_xa->tuple, index->first_offset, node_xb->tuple, index->first_offset); @@ -1495,8 +1565,10 @@ fixed_dup_node_cmp(const void *node_a, const void *node_b, void *arg) { int r = fixed_node_cmp(node_a, node_b, arg); if (r == 0) { - const struct fixed_node *node_xa = node_a; - const struct fixed_node *node_xb = node_b; + const struct fixed_node *node_xa = + (const struct fixed_node *) node_a; + const struct fixed_node *node_xb = + (const struct fixed_node *) node_b; r = ta_cmp(node_xa->tuple, node_xb->tuple); } return r; @@ -1506,8 +1578,8 @@ static int fixed_key_node_cmp(const void *key, const void * node, void *arg) { FixedTreeIndex *index = (FixedTreeIndex *) arg; - const struct key_data *key_data = key; - const struct fixed_node *node_x = node; + const struct key_data *key_data = (const struct key_data *) key; + const struct fixed_node *node_x = (const struct fixed_node *) node; return dense_key_node_compare(index->key_def, key_data, index->first_field, node_x->tuple, index->first_offset); @@ -1517,8 +1589,8 @@ static int linear_fixed_node_cmp(const void *node_a, const void *node_b, void *arg) { FixedTreeIndex *index = (FixedTreeIndex *) arg; - const struct fixed_node *node_xa = node_a; - const struct fixed_node *node_xb = node_b; + const struct fixed_node *node_xa = (const struct fixed_node *) node_a; + const struct fixed_node *node_xb = (const struct fixed_node *) node_b; return linear_node_compare(index->key_def, index->first_field, node_xa->tuple, index->first_offset, node_xb->tuple, index->first_offset); @@ -1529,8 +1601,10 @@ linear_fixed_dup_node_cmp(const void *node_a, const void *node_b, void *arg) { int r = linear_fixed_node_cmp(node_a, node_b, arg); if (r == 0) { - const struct fixed_node *node_xa = node_a; - const struct fixed_node *node_xb = node_b; + const struct fixed_node *node_xa = + (const struct fixed_node *) node_a; + const struct fixed_node *node_xb = + (const struct fixed_node *) node_b; r = ta_cmp(node_xa->tuple, node_xb->tuple); } return r; @@ -1539,66 +1613,66 @@ linear_fixed_dup_node_cmp(const void *node_a, const void *node_b, void *arg) static int linear_fixed_key_node_cmp(const void *key, const void * node, void *arg) { - FixedTreeIndex *index = (FixedTreeIndex *) arg; - const struct key_data *key_data = key; - const struct fixed_node *node_x = node; + const FixedTreeIndex *index = (const FixedTreeIndex *) arg; + const struct key_data *key_data = (const struct key_data *) key; + const struct fixed_node *node_x = (const struct fixed_node *) node; return linear_key_node_compare(index->key_def, key_data, index->first_field, node_x->tuple, index->first_offset); } -@implementation FixedTreeIndex -- (id) init: (struct key_def *) key_def_arg :(struct space *) space_arg +FixedTreeIndex::FixedTreeIndex(struct key_def *key_def, struct space *space) + : TreeIndex(key_def, space) { - self = [super init: key_def_arg :space_arg]; - if (self == NULL) - return NULL; - first_field = find_first_field(key_def); first_offset = find_fixed_offset(space, first_field, 0); - return self; } -- (size_t) node_size + +size_t +FixedTreeIndex::node_size() const { return sizeof(struct fixed_node); } -- (tree_cmp_t) node_cmp +tree_cmp_t +FixedTreeIndex::node_cmp() const { return key_is_linear(key_def) ? linear_fixed_node_cmp : fixed_node_cmp; } -- (tree_cmp_t) dup_node_cmp +tree_cmp_t +FixedTreeIndex::dup_node_cmp() const { return key_is_linear(key_def) ? linear_fixed_dup_node_cmp : fixed_dup_node_cmp; } -- (tree_cmp_t) key_node_cmp +tree_cmp_t +FixedTreeIndex::key_node_cmp() const { return key_is_linear(key_def) ? linear_fixed_key_node_cmp : fixed_key_node_cmp; } -- (void) fold: (void *) node :(struct tuple *) tuple +void +FixedTreeIndex::fold(void *node, struct tuple *tuple) const { struct fixed_node *node_x = (struct fixed_node *) node; node_x->tuple = tuple; } -- (struct tuple *) unfold: (const void *) node +struct tuple * +FixedTreeIndex::unfold(const void *node) const { - const struct fixed_node *node_x = node; + const struct fixed_node *node_x = (const struct fixed_node *) node; return node_x ? node_x->tuple : NULL; } -@end - /* }}} */ diff --git a/src/box/tree_index.h b/src/box/tree_index.h index d1ff337d802d97e5592d16e46b3619757880cfb6..58b0829dca1ad27c29c25ff953326c5a40f5dac7 100644 --- a/src/box/tree_index.h +++ b/src/box/tree_index.h @@ -40,22 +40,45 @@ SPTREE_DEF(index, realloc); typedef int (*tree_cmp_t)(const void *, const void *, void *); -@interface TreeIndex: Index { -@public - sptree_index tree; -}; +class TreeIndex: public Index { +public: + static TreeIndex * + factory(struct key_def *key_def, struct space *space); + + virtual void beginBuild(); + virtual void buildNext(struct tuple *tuple); + virtual void endBuild(); + virtual void build(Index *pk); + virtual size_t size() const; + virtual struct tuple *min() const; + virtual struct tuple *max() const; + virtual struct tuple *random(u32 rnd) const; + virtual struct tuple *findByKey(const void *key, u32 part_count) const; + virtual struct tuple *findByTuple(struct tuple *tuple) const; + virtual struct tuple *replace(struct tuple *old_tuple, + struct tuple *new_tuple, + enum dup_replace_mode mode); + + virtual struct iterator *allocIterator() const; + virtual void initIterator(struct iterator *iterator, + enum iterator_type type, + const void *key, u32 part_count) const; -+ (struct index_traits *) traits; -+ (Index *) alloc: (struct key_def *) key_def :(struct space *) space; +// protected: + /* Needed by iterators */ + virtual size_t node_size() const = 0; + virtual tree_cmp_t node_cmp() const = 0; + virtual tree_cmp_t dup_node_cmp() const = 0; + virtual tree_cmp_t key_node_cmp() const= 0; -/** To be defined in subclasses. */ -- (size_t) node_size; -- (tree_cmp_t) node_cmp; -- (tree_cmp_t) dup_node_cmp; -- (tree_cmp_t) key_node_cmp; -- (void) fold: (void *) node :(struct tuple *) tuple; -- (struct tuple *) unfold: (const void *) node; + virtual void fold(void *node, struct tuple *tuple) const = 0; + virtual struct tuple *unfold(const void *node) const = 0; -@end + sptree_index tree; + +protected: + TreeIndex(struct key_def *key_def, struct space *space); + virtual ~TreeIndex(); +}; #endif /* TARANTOOL_BOX_TREE_INDEX_H_INCLUDED */ diff --git a/src/box/tuple.m b/src/box/tuple.cc similarity index 92% rename from src/box/tuple.m rename to src/box/tuple.cc index 4c939f0dac38adfd145dce3a8c27df18883847f4..e3e06627b70fc383350fd30788656d288935af01 100644 --- a/src/box/tuple.m +++ b/src/box/tuple.cc @@ -39,7 +39,7 @@ struct tuple * tuple_alloc(size_t size) { size_t total = sizeof(struct tuple) + size; - struct tuple *tuple = salloc(total, "tuple"); + struct tuple *tuple = (struct tuple *) salloc(total, "tuple"); tuple->flags = tuple->refs = 0; tuple->bsize = size; @@ -116,15 +116,17 @@ print_field(struct tbuf *buf, const void *f) tbuf_printf(buf, "%u", *(u32 *)f); break; case 8: - tbuf_printf(buf, "%"PRIu64, *(u64 *)f); + tbuf_printf(buf, "%" PRIu64, *(u64 *)f); break; default: tbuf_printf(buf, "'"); while (size-- > 0) { - if (0x20 <= *(u8 *)f && *(u8 *)f < 0x7f) - tbuf_printf(buf, "%c", *(u8 *)f++); - else - tbuf_printf(buf, "\\x%02X", *(u8 *)f++); + if (0x20 <= *(u8 *)f && *(u8 *)f < 0x7f) { + tbuf_printf(buf, "%c", *(u8 *) f); + } else { + tbuf_printf(buf, "\\x%02X", *(u8 *)f); + } + f = (char *) f + 1; } tbuf_printf(buf, "'"); break; diff --git a/src/box/txn.m b/src/box/txn.cc similarity index 96% rename from src/box/txn.m rename to src/box/txn.cc index 88ad42f5c3bb8c892b64a9c437c40b37bc1564c7..cc51ab86366e4d3a6a059d767ab0588f1eae9440 100644 --- a/src/box/txn.m +++ b/src/box/txn.cc @@ -67,7 +67,7 @@ txn_replace(struct txn *txn, struct space *space, struct txn * txn_begin() { - struct txn *txn = p0alloc(fiber->gc_pool, sizeof(*txn)); + struct txn *txn = (struct txn *) p0alloc(fiber->gc_pool, sizeof(*txn)); return txn; } @@ -90,7 +90,7 @@ txn_commit(struct txn *txn) confirm_lsn(recovery_state, lsn, res == 0); if (res) - tnt_raise(LoggedError, :ER_WAL_IO); + tnt_raise(LoggedError, ER_WAL_IO); } } diff --git a/src/coeio.m b/src/coeio.cc similarity index 97% rename from src/coeio.m rename to src/coeio.cc index dc46539a5e806d1116418862fc56d5c32b4df480..4dac81719cac4617802b0a4ff0188bde4e553657 100644 --- a/src/coeio.m +++ b/src/coeio.cc @@ -129,7 +129,7 @@ struct coeio_task { static void coeio_custom_cb(eio_req *req) { - struct coeio_task *task = req->data; + struct coeio_task *task = (struct coeio_task *) req->data; req->result = task->func(task->ap); } @@ -148,7 +148,7 @@ coeio_on_complete(eio_req *req) * is already woken up, avoid double wake-up. */ if (! EIO_CANCELLED(req)) { - struct coeio_task *task = req->data; + struct coeio_task *task = (struct coeio_task *) req->data; task->result = req->result; task->errorno = req->errorno; task->complete = 1; @@ -221,6 +221,7 @@ getaddrinfo_cb(va_list ap) struct addrinfo *hints = va_arg(ap, struct addrinfo *); struct addrinfo **res = va_arg(ap, struct addrinfo **); + say_warn("Host: %s Port: %s, Hints: %p, Res: %p", host, port, hints, res); int rc = getaddrinfo(host, port, hints, res); /* getaddrinfo can return EAI_ADDRFAMILY on attempt * to resolve ::1, if machine has no public ipv6 addresses diff --git a/src/coio.m b/src/coio.cc similarity index 91% rename from src/coio.m rename to src/coio.cc index 799e4c68dae12113d468b25e6bd2f5ea61552e81..a8b0ae36a74a1c5206446846a34d7de7a9112a48 100644 --- a/src/coio.m +++ b/src/coio.cc @@ -34,7 +34,13 @@ #include "fiber.h" #include "iobuf.h" #include "sio.h" +#include "scoped_guard.h" +static inline void +fiber_schedule_coio(ev_io *watcher, int event) { + say_warn("fiber schedule IO"); + return fiber_schedule((ev_watcher *) watcher, event); +} /** Note: this function does not throw */ void @@ -42,7 +48,7 @@ coio_init(struct ev_io *coio) { /* Prepare for ev events. */ coio->data = fiber; - ev_init(coio, (void *) fiber_schedule); + ev_init(coio, fiber_schedule_coio); coio->fd = -1; } @@ -108,7 +114,7 @@ coio_connect_timeout(struct ev_io *coio, struct sockaddr_in *addr, &error, &sz); if (error != 0) { errno = error; - tnt_raise(SocketError, :coio->fd in:"connect"); + tnt_raise(SocketError, coio->fd, "connect"); } return false; } @@ -133,26 +139,27 @@ coio_connect_addrinfo(struct ev_io *coio, struct addrinfo *ai, bool res = true; while (ai) { struct sockaddr_in *addr = (struct sockaddr_in *)ai->ai_addr; - @try { + try { evio_socket(coio, ai->ai_family, ai->ai_socktype, ai->ai_protocol); res = coio_connect_timeout(coio, addr, ai->ai_addrlen, delay); + if (res) + evio_close(coio); return res; - } @catch (SocketError *e) { + } catch (const SocketError& e) { + if (res) + evio_close(coio); if (ai->ai_next == NULL) - @throw; + throw; ev_now_update(); evio_timeout_update(start, &delay); - } @finally { - if (res) - evio_close(coio); } ai = ai->ai_next; } /* unreachable. */ - tnt_raise(SocketError, :coio->fd in: "connect_addrinfo()"); + tnt_raise(SocketError, coio->fd, "connect_addrinfo()"); } /** @@ -186,7 +193,7 @@ coio_accept(struct ev_io *coio, struct sockaddr_in *addr, fiber_testcancel(); if (is_timedout) { errno = ETIMEDOUT; - tnt_raise(SocketError, :coio->fd in:"accept"); + tnt_raise(SocketError, coio->fd, "accept"); } evio_timeout_update(start, &delay); } @@ -211,7 +218,12 @@ coio_read_ahead_timeout(struct ev_io *coio, void *buf, size_t sz, evio_timeout_init(&start, &delay, timeout); ssize_t to_read = (ssize_t) sz; - @try { + + { + auto scoped_guard = make_scoped_guard([=] { + ev_io_stop(coio); + }); + while (true) { /* * Sic: assume the socket is ready: since @@ -223,7 +235,7 @@ coio_read_ahead_timeout(struct ev_io *coio, void *buf, size_t sz, to_read -= nrd; if (to_read <= 0) return sz - to_read; - buf += nrd; + buf = (char *) buf + nrd; bufsiz -= nrd; } else if (nrd == 0) { errno = 0; @@ -248,8 +260,6 @@ coio_read_ahead_timeout(struct ev_io *coio, void *buf, size_t sz, } evio_timeout_update(start, &delay); } - } @finally { - ev_io_stop(coio); } } @@ -266,7 +276,7 @@ coio_readn_ahead(struct ev_io *coio, void *buf, size_t sz, size_t bufsiz) ssize_t nrd = coio_read_ahead(coio, buf, sz, bufsiz); if (nrd < sz) { errno = EPIPE; - tnt_raise(SocketError, :coio->fd in:"unexpected EOF when reading " + tnt_raise(SocketError, coio->fd, "unexpected EOF when reading " "from socket"); } return nrd; @@ -286,7 +296,7 @@ coio_readn_ahead_timeout(struct ev_io *coio, void *buf, size_t sz, size_t bufsiz ssize_t nrd = coio_read_ahead_timeout(coio, buf, sz, bufsiz, timeout); if (nrd < sz && errno == 0) { /* EOF. */ errno = EPIPE; - tnt_raise(SocketError, :coio->fd in:"unexpected EOF when reading " + tnt_raise(SocketError, coio->fd, "unexpected EOF when reading " "from socket"); } return nrd; @@ -309,7 +319,12 @@ coio_write_timeout(struct ev_io *coio, const void *buf, size_t sz, size_t towrite = sz; ev_tstamp start, delay; evio_timeout_init(&start, &delay, timeout); - @try { + + { + auto scoped_guard = make_scoped_guard([=] { + ev_io_stop(coio); + }); + while (true) { /* * Sic: write as much data as possible, @@ -321,7 +336,7 @@ coio_write_timeout(struct ev_io *coio, const void *buf, size_t sz, if (nwr >= towrite) return sz; towrite -= nwr; - buf += nwr; + buf = (char *) buf + nwr; } if (! ev_is_active(coio)) { ev_io_set(coio, coio->fd, EV_WRITE); @@ -344,8 +359,6 @@ coio_write_timeout(struct ev_io *coio, const void *buf, size_t sz, } evio_timeout_update(start, &delay); } - } @finally { - ev_io_stop(coio); } } @@ -357,11 +370,13 @@ static inline ssize_t coio_flush(int fd, struct iovec *iov, ssize_t offset, int iovcnt) { ssize_t nwr; - @try { + try { sio_add_to_iov(iov, -offset); nwr = sio_writev(fd, iov, iovcnt); - } @finally { sio_add_to_iov(iov, offset); + } catch(const Exception& e) { + sio_add_to_iov(iov, offset); + throw; } return nwr; } @@ -373,7 +388,12 @@ coio_writev(struct ev_io *coio, struct iovec *iov, int iovcnt, ssize_t total = 0; size_t iov_len = 0; struct iovec *end = iov + iovcnt; - @try { + + { + auto scoped_guard = make_scoped_guard([=] { + ev_io_stop(coio); + }); + /* Avoid a syscall in case of 0 iovcnt. */ while (iov < end) { /* Write as much data as possible. */ @@ -402,8 +422,6 @@ coio_writev(struct ev_io *coio, struct iovec *iov, int iovcnt, coio_fiber_yield(coio); fiber_testcancel(); } - } @finally { - ev_io_stop(coio); } return total; } @@ -422,7 +440,12 @@ coio_sendto_timeout(struct ev_io *coio, const void *buf, size_t sz, int flags, { ev_tstamp start, delay; evio_timeout_init(&start, &delay, timeout); - @try { + + { + auto scoped_guard = make_scoped_guard([=] { + ev_io_stop(coio); + }); + while (true) { /* * Sic: write as much data as possible, @@ -450,8 +473,6 @@ coio_sendto_timeout(struct ev_io *coio, const void *buf, size_t sz, int flags, } evio_timeout_update(start, &delay); } - } @finally { - ev_io_stop(coio); } } @@ -470,7 +491,11 @@ coio_recvfrom_timeout(struct ev_io *coio, void *buf, size_t sz, int flags, ev_tstamp start, delay; evio_timeout_init(&start, &delay, timeout); - @try { + { + auto scoped_guard = make_scoped_guard([=] { + ev_io_stop(coio); + }); + while (true) { /* * Read as much data as possible, @@ -499,8 +524,6 @@ coio_recvfrom_timeout(struct ev_io *coio, void *buf, size_t sz, int flags, } evio_timeout_update(start, &delay); } - } @finally { - ev_io_stop(coio); } } @@ -508,7 +531,8 @@ void coio_service_on_accept(struct evio_service *evio_service, int fd, struct sockaddr_in *addr) { - struct coio_service *service = evio_service->on_accept_param; + struct coio_service *service = (struct coio_service *) + evio_service->on_accept_param; struct ev_io coio; coio_init(&coio); @@ -525,15 +549,15 @@ coio_service_on_accept(struct evio_service *evio_service, struct iobuf *iobuf = NULL; struct fiber *f; - @try { + try { iobuf = iobuf_new(iobuf_name); f = fiber_new(fiber_name, service->handler); - } @catch (tnt_Exception *e) { + } catch (const Exception& e) { say_error("can't create a handler fiber, dropping client connection"); evio_close(&coio); if (iobuf) iobuf_delete(iobuf); - @throw; + throw; } /* * The coio is passed into the created fiber, reset the diff --git a/src/coio_buf.m b/src/coio_buf.cc similarity index 100% rename from src/coio_buf.m rename to src/coio_buf.cc diff --git a/src/coro.m b/src/coro.cc similarity index 94% rename from src/coro.m rename to src/coro.cc index cfaf77ca5cc37351cde4a72b7bcf64d25f448f0c..e73e0267e7b64f7866d6f75889212592f8e22e46 100644 --- a/src/coro.m +++ b/src/coro.cc @@ -50,12 +50,12 @@ tarantool_coro_create(struct tarantool_coro *coro, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); if (coro->stack == MAP_FAILED) { - tnt_raise(LoggedError, :ER_MEMORY_ISSUE, + tnt_raise(LoggedError, ER_MEMORY_ISSUE, sizeof(coro->stack_size), "mmap", "coro stack"); } - (void) VALGRIND_STACK_REGISTER(coro->stack, coro->stack + coro->stack_size); + (void) VALGRIND_STACK_REGISTER(coro->stack, (char *) coro->stack + coro->stack_size); coro_create(&coro->ctx, f, data, coro->stack, coro->stack_size); } diff --git a/src/cpu_feature.m b/src/cpu_feature.c similarity index 100% rename from src/cpu_feature.m rename to src/cpu_feature.c diff --git a/src/errinj.m b/src/errinj.cc similarity index 97% rename from src/errinj.m rename to src/errinj.cc index 3f0e34c5a6ef26cc339f66c8861b37029715163a..8884c9146b896f0a28e3a78d51e067f6b826a993 100644 --- a/src/errinj.m +++ b/src/errinj.cc @@ -37,7 +37,7 @@ #include "tbuf.h" #include "errinj.h" -#define ERRINJ_MEMBER(n, s) { .name = #n, .state = s }, +#define ERRINJ_MEMBER(n, s) { /* .name = */ #n, /* .state = */ s }, struct errinj errinjs[errinj_enum_MAX] = { ERRINJ_LIST(ERRINJ_MEMBER) diff --git a/src/evio.m b/src/evio.cc similarity index 95% rename from src/evio.m rename to src/evio.cc index c50880b0c7e2d38c46fc6cd5205af9e3585631ab..1d27ac18fc897b161507ddb27268af8e89252add 100644 --- a/src/evio.m +++ b/src/evio.cc @@ -146,7 +146,7 @@ evio_bind_addrinfo(struct ev_io *evio, struct addrinfo *ai) int fd = -1; while (ai) { struct sockaddr_in *addr = (struct sockaddr_in *)ai->ai_addr; - @try { + try { fd = sio_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); evio_setsockopt_tcpserver(fd); @@ -155,16 +155,16 @@ evio_bind_addrinfo(struct ev_io *evio, struct addrinfo *ai) return; /* success. */ } assert(errno == EADDRINUSE); - } @catch (SocketError *e) { + } catch (const SocketError& e) { if (ai->ai_next == NULL) { close(fd); - @throw; + throw; } } close(fd); ai = ai->ai_next; } - tnt_raise(SocketError, :evio->fd in:"evio_bind_addrinfo()"); + tnt_raise(SocketError, evio->fd, "evio_bind_addrinfo()"); } static inline int @@ -182,10 +182,10 @@ static void evio_service_accept_cb(ev_io *watcher, int revents __attribute__((unused))) { - struct evio_service *service = watcher->data; + struct evio_service *service = (struct evio_service *) watcher->data; int fd = -1; - @try { + try { struct sockaddr_in addr; socklen_t addrlen = sizeof(addr); fd = sio_accept(service->ev.fd, &addr, &addrlen); @@ -200,10 +200,10 @@ evio_service_accept_cb(ev_io *watcher, */ service->on_accept(service, fd, &addr); - } @catch (tnt_Exception *e) { + } catch (const Exception& e) { if (fd >= 0) close(fd); - [e log]; + e.log(); } } @@ -219,7 +219,7 @@ evio_service_bind_and_listen(struct evio_service *service) /* Create a socket. */ int fd = sio_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - @try { + try { evio_setsockopt_tcpserver(fd); if (sio_bind(fd, &service->addr, sizeof(service->addr)) || @@ -234,9 +234,9 @@ evio_service_bind_and_listen(struct evio_service *service) if (service->on_bind) service->on_bind(service->on_bind_param); - } @catch (tnt_Exception *e) { + } catch (const Exception& e) { close(fd); - @throw; + throw; } /* Register the socket in the event loop. */ ev_io_set(&service->ev, fd, EV_READ); @@ -252,7 +252,7 @@ evio_service_bind_and_listen(struct evio_service *service) static void evio_service_timer_cb(ev_timer *watcher, int revents __attribute__((unused))) { - struct evio_service *service = watcher->data; + struct evio_service *service = (struct evio_service *) watcher->data; assert(! ev_is_active(&service->ev)); if (evio_service_bind_and_listen(service) == 0) @@ -274,7 +274,7 @@ evio_service_init(struct evio_service *service, const char *name, if (strcmp(host, "INADDR_ANY") == 0) { service->addr.sin_addr.s_addr = INADDR_ANY; } else if (inet_aton(host, &service->addr.sin_addr) == 0) { - tnt_raise(SocketError, :"invalid address for bind: %s", + tnt_raise(SocketError, -1, "invalid address for bind: %s", host); } service->on_accept = on_accept; diff --git a/src/exception.cc b/src/exception.cc new file mode 100644 index 0000000000000000000000000000000000000000..2a92a1c5db16c9f36259c14ac134af99e6e7a1ba --- /dev/null +++ b/src/exception.cc @@ -0,0 +1,117 @@ +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "exception.h" +#include "say.h" + +#include <stdio.h> +#include <string.h> +#include <errno.h> + +Exception::Exception(const char *file, unsigned line) + : m_file(file), m_line(line) +{ + m_errmsg[0] = 0; +} + +Exception::Exception(const Exception& e) + : Object(e), m_file(e.m_file), m_line(e.m_line) +{ + memcpy(m_errmsg, e.m_errmsg, sizeof(m_errmsg)); +} + +SystemError::SystemError(const char *file, unsigned line) + : Exception(file, line), + m_errnum(errno) +{ + /* nothing */ +} + +void +SystemError::init(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + init(format, ap); + va_end(ap); +} + +void +SystemError::init(const char *format, va_list ap) +{ + vsnprintf(m_errmsg, sizeof(m_errmsg), format, ap); +} + +void +SystemError::log() const +{ + say(S_ERROR, strerror(m_errnum), "%s in %s", "SystemError", + m_errmsg); +} + +ClientError::ClientError(const char *file, unsigned line, uint32_t errcode, ...) + : Exception(file, line) +{ + m_errcode = errcode; + va_list ap; + va_start(ap, errcode); + vsnprintf(m_errmsg, sizeof(m_errmsg) - 1, + tnt_errcode_desc(m_errcode), ap); + m_errmsg[sizeof(m_errmsg) - 1] = 0; + va_end(ap); +} + +ClientError::ClientError(const char *file, unsigned line, const char *msg, + uint32_t errcode) + : Exception(file, line) +{ + m_errcode = errcode; + strncpy(m_errmsg, msg, sizeof(m_errmsg) - 1); + m_errmsg[sizeof(m_errmsg) - 1] = 0; +} + +void +ClientError::log() const +{ + say_error("%s at %s:%d, %s", "ClientError", + m_file, m_line, m_errmsg); +} + +IllegalParams::IllegalParams(const char *file, unsigned line, const char *msg) + : LoggedError(file, line, ER_ILLEGAL_PARAMS, msg) +{ + /* nothing */ +} + + +ErrorInjection::ErrorInjection(const char *file, unsigned line, const char *msg) + : LoggedError(file, line, ER_INJECTION, msg) +{ + /* nothing */ +} + diff --git a/src/exception.m b/src/exception.m deleted file mode 100644 index a09b6d39037a4938ca9404bf445534a80c2a1a06..0000000000000000000000000000000000000000 --- a/src/exception.m +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the - * following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -#include "exception.h" -#include "say.h" - -#include <stdio.h> -#include <string.h> - - -@implementation tnt_Exception -+ (id) alloc -{ - static __thread tnt_Exception *e = nil; - static __thread size_t sz = 0; - - if (e != nil && class_getInstanceSize(self) <= sz) { - object_setClass(e, self); - } else { - if (e != nil) - object_dispose(e); - e = class_createInstance(self, 0); - sz = class_getInstanceSize(self); - } - return e; -} - -- (void) log -{ - [self subclassResponsibility: _cmd]; -} - -- (const char *) errmsg -{ - [self subclassResponsibility: _cmd]; - return NULL; -} -@end - -@implementation SystemError - -- (id) init: (const char *) format, ... -{ - va_list ap; - va_start(ap, format); - self = [self init: errno :format :ap]; - va_end(ap); - return self; -} - -- (id) init: (int)errnum_arg :(const char *)format :(va_list)ap -{ - self = [super init]; - errnum = errnum_arg; - vsnprintf(errmsg, sizeof(errmsg), format, ap); - return self; -} - -- (void) log -{ - say(S_ERROR, strerror(errnum), "%s in %s", object_getClassName(self), errmsg); -} - -- (const char *) errmsg -{ - return errmsg; -} -@end - - -@implementation ClientError -- (id) init: (uint32_t)errcode_, ... -{ - va_list ap; - va_start(ap, errcode_); - [self init: errcode_ args: ap]; - va_end(ap); - - return self; -} - - -- (id) init: (uint32_t)errcode_ args :(va_list)ap -{ - [super init]; - errcode = errcode_; - vsnprintf(errmsg, sizeof(errmsg), tnt_errcode_desc(errcode), ap); - return self; -} - -- (id) init: (uint32_t)errcode_ :(const char *)msg -{ - [super init]; - errcode = errcode_; - snprintf(errmsg, sizeof(errmsg), "%s", msg); - return self; -} - -- (void) log -{ - say_error("%s at %s:%d, %s", object_getClassName(self), - file, line, errmsg); -} - -- (const char *) errmsg -{ - return errmsg; -} -@end - - -@implementation LoggedError -- (id) init: (uint32_t) errcode_, ... -{ - va_list ap; - va_start(ap, errcode_); - [super init: errcode_ args: ap]; - - [self log]; - - return self; -} -@end - - -@implementation IllegalParams -- (id) init: (const char*) msg -{ - return [super init: ER_ILLEGAL_PARAMS, msg]; -} -@end - -@implementation ErrorInjection -- (id) init: (const char*) msg -{ - return [super init: ER_INJECTION, msg]; -} -@end diff --git a/src/fiber.m b/src/fiber.cc similarity index 89% rename from src/fiber.m rename to src/fiber.cc index 4066cd910bb4404762b3056cd84619030de03612..8894a8b7ec0c2878256c0f01bf21962b863aeb56 100644 --- a/src/fiber.m +++ b/src/fiber.cc @@ -35,17 +35,16 @@ #include <say.h> #include <tarantool.h> -#include TARANTOOL_CONFIG +extern "C" { +#include <cfg/warning.h> +#include <cfg/tarantool_box_cfg.h> +} /* extern "C" */ #include <tbuf.h> #include <stat.h> #include <assoc.h> #include "iobuf.h" #include <rlist.h> -@implementation FiberCancelException -@end - - enum { FIBER_CALL_STACK = 16 }; static struct fiber sched; @@ -221,11 +220,19 @@ fiber_yield(void) } +struct fiber_watcher_data { + struct fiber *f; + bool timed_out; +}; + static void -fiber_schedule_timeout(ev_watcher *watcher) +fiber_schedule_timeout(ev_timer *watcher, int revents) { + (void) revents; + assert(fiber == &sched); - struct { struct fiber *f; bool timed_out; } *state = watcher->data; + struct fiber_watcher_data *state = + (struct fiber_watcher_data *) watcher->data; state->timed_out = true; fiber_call(state->f); } @@ -238,8 +245,8 @@ bool fiber_yield_timeout(ev_tstamp delay) { struct ev_timer timer; - ev_timer_init(&timer, (void *)fiber_schedule_timeout, delay, 0); - struct { struct fiber *f; bool timed_out; } state = { fiber, false }; + ev_timer_init(&timer, fiber_schedule_timeout, delay, 0); + struct fiber_watcher_data state = { fiber, false }; timer.data = &state; ev_timer_start(&timer); fiber_yield(); @@ -270,11 +277,17 @@ fiber_sleep(ev_tstamp delay) * @note: this is a cancellation point (@sa fiber_testcancel()). * @return process return status */ +void +fiber_schedule_child(ev_child *watcher, int event __attribute__((unused))) +{ + return fiber_schedule((ev_watcher *) watcher, event); +} + int wait_for_child(pid_t pid) { ev_child cw; - ev_init(&cw, (void *)fiber_schedule); + ev_init(&cw, fiber_schedule_child); ev_child_set(&cw, pid, 0); cw.data = fiber; ev_child_start(&cw); @@ -289,12 +302,15 @@ void fiber_schedule(ev_watcher *watcher, int event __attribute__((unused))) { assert(fiber == &sched); - fiber_call(watcher->data); + fiber_call((struct fiber *) watcher->data); } static void -fiber_ready_async(void) +fiber_ready_async(ev_async *watcher, int revents) { + (void) watcher; + (void) revents; + while(!rlist_empty(&ready_fibers)) { struct fiber *f = rlist_first_entry(&ready_fibers, struct fiber, state); @@ -304,27 +320,27 @@ fiber_ready_async(void) } struct fiber * -fiber_find(int fid) +fiber_find(uint32_t fid) { - struct mh_i32ptr_node_t node = { .key = fid }; + struct mh_i32ptr_node_t node = { fid, NULL }; mh_int_t k = mh_i32ptr_get(fiber_registry, &node, NULL); if (k == mh_end(fiber_registry)) return NULL; - return mh_i32ptr_node(fiber_registry, k)->val; + return (struct fiber *) mh_i32ptr_node(fiber_registry, k)->val; } static void register_fid(struct fiber *fiber) { - struct mh_i32ptr_node_t node = { .key = fiber -> fid, .val = fiber }; + struct mh_i32ptr_node_t node = { fiber -> fid, fiber }; mh_i32ptr_put(fiber_registry, &node, NULL, NULL); } static void unregister_fid(struct fiber *fiber) { - struct mh_i32ptr_node_t node = { .key = fiber->fid }; + struct mh_i32ptr_node_t node = { fiber->fid, NULL }; mh_i32ptr_remove(fiber_registry, &node, NULL); } @@ -364,16 +380,17 @@ fiber_loop(void *data __attribute__((unused))) { for (;;) { assert(fiber != NULL && fiber->f != NULL && fiber->fid != 0); - @try { + try { fiber->f(fiber->f_data); - } @catch (FiberCancelException *e) { + } catch (const FiberCancelException& e) { say_info("fiber `%s' has been cancelled", fiber_name(fiber)); say_info("fiber `%s': exiting", fiber_name(fiber)); - } @catch (tnt_Exception *e) { - [e log]; - } @catch (id e) { - say_error("fiber `%s': exception `%s'", - fiber_name(fiber), object_getClassName(e)); + } catch (const Exception& e) { + e.log(); + } catch (...) { + /* TODO: this case should never happen */ + say_error("fiber `%s': unknown exception", + fiber_name(fiber)); panic("fiber `%s': exiting", fiber_name(fiber)); } fiber_zombificate(); @@ -414,7 +431,7 @@ fiber_new(const char *name, void (*f) (va_list)) fiber = rlist_first_entry(&zombie_fibers, struct fiber, link); rlist_move_entry(&fibers, fiber, link); } else { - fiber = palloc(eter_pool, sizeof(*fiber)); + fiber = (struct fiber *) palloc(eter_pool, sizeof(*fiber)); memset(fiber, 0, sizeof(*fiber)); tarantool_coro_create(&fiber->coro, fiber_loop, NULL); @@ -474,7 +491,7 @@ fiber_destroy_all() static void fiber_info_print(struct tbuf *out, struct fiber *fiber) { - void *stack_top = fiber->coro.stack + fiber->coro.stack_size; + void *stack_top = (char *) fiber->coro.stack + fiber->coro.stack_size; tbuf_printf(out, " - fid: %4i" CRLF, fiber->fid); tbuf_printf(out, " csw: %i" CRLF, fiber->csw); @@ -519,7 +536,7 @@ fiber_init(void) iobuf_init_readahead(cfg.readahead); - ev_async_init(&ready_async, (void *)fiber_ready_async); + ev_async_init(&ready_async, fiber_ready_async); ev_async_start(&ready_async); } diff --git a/src/iobuf.m b/src/iobuf.cc similarity index 95% rename from src/iobuf.m rename to src/iobuf.cc index fbf8b696892500fb271a04004d0f3710f6734968..56ff2ea1e22c7968d3690cc9b0a8a9eb6dab606f 100644 --- a/src/iobuf.m +++ b/src/iobuf.cc @@ -73,7 +73,7 @@ ibuf_reserve(struct ibuf *ibuf, size_t size) while (new_capacity < current_size + size) new_capacity *= 2; - ibuf->buf = palloc(ibuf->pool, new_capacity); + ibuf->buf = (char *) palloc(ibuf->pool, new_capacity); memcpy(ibuf->buf, ibuf->pos, current_size); ibuf->capacity = new_capacity; } @@ -93,7 +93,7 @@ static inline void obuf_init_pos(struct obuf *buf, size_t pos) { if (pos >= IOBUF_IOV_MAX) { - tnt_raise(LoggedError, :ER_MEMORY_ISSUE, buf->pos, + tnt_raise(LoggedError, ER_MEMORY_ISSUE, buf->pos, "obuf_init_pos", "iovec"); } buf->iov[pos].iov_base = NULL; @@ -165,11 +165,11 @@ obuf_dup(struct obuf *buf, const void *data, size_t size) */ size_t fill = capacity - iov->iov_len; assert(fill < size); - memcpy(iov->iov_base + iov->iov_len, data, fill); + memcpy((char *) iov->iov_base + iov->iov_len, data, fill); iov->iov_len += fill; buf->size += fill; - data += fill; + data = (char *) data + fill; size -= fill; /* * Check if the remainder can fit @@ -193,7 +193,7 @@ obuf_dup(struct obuf *buf, const void *data, size_t size) iov = &buf->iov[buf->pos]; capacity = buf->capacity[buf->pos]; } - memcpy(iov->iov_base + iov->iov_len, data, size); + memcpy((char *) iov->iov_base + iov->iov_len, data, size); iov->iov_len += size; buf->size += size; assert(iov->iov_len <= buf->capacity[buf->pos]); @@ -221,9 +221,11 @@ obuf_book(struct obuf *buf, size_t size) obuf_alloc_pos(buf, buf->pos, size); } } - struct obuf_svp svp = { - .pos = buf->pos, .iov_len = iov->iov_len, .size = buf->size - }; + struct obuf_svp svp; + svp.pos = buf->pos; + svp.iov_len = iov->iov_len; + svp.size = buf->size; + iov->iov_len += size; buf->size += size; assert(iov->iov_len <= buf->capacity[buf->pos]); @@ -272,7 +274,7 @@ iobuf_new(const char *name) { struct iobuf *iobuf; if (SLIST_EMPTY(&iobuf_cache)) { - iobuf = palloc(eter_pool, sizeof(struct iobuf)); + iobuf = (struct iobuf *) palloc(eter_pool, sizeof(struct iobuf)); struct palloc_pool *pool = palloc_create_pool(""); /* Note: do not allocate memory upfront. */ ibuf_create(&iobuf->in, pool); diff --git a/src/ipc.m b/src/ipc.cc similarity index 99% rename from src/ipc.m rename to src/ipc.cc index 9274abdd1316aacd530b55859965687f815f5c37..41832a2bac435091c184bfecb21304799d854fc3 100644 --- a/src/ipc.m +++ b/src/ipc.cc @@ -63,7 +63,7 @@ ipc_channel_new(unsigned size) { if (!size) size = 1; - struct ipc_channel *res = + struct ipc_channel *res = (struct ipc_channel *) malloc(sizeof(struct ipc_channel) + sizeof(void *) * size); if (res == NULL) return NULL; diff --git a/src/iproto.m b/src/iproto.cc similarity index 91% rename from src/iproto.m rename to src/iproto.cc index c50a391f7d40acd1829564295a32a7c751dabf8f..86249b440d13029caa41c523834ba89b9a024da1 100644 --- a/src/iproto.m +++ b/src/iproto.cc @@ -44,6 +44,7 @@ #include "iobuf.h" #include "evio.h" #include "session.h" +#include "scoped_guard.h" enum { /** Maximal iproto package body length (2GiB) */ @@ -193,7 +194,7 @@ struct iproto_queue /** * Cache of fibers which work on requests * in this queue. - */ + */ struct rlist fiber_cache; /** * Used to trigger request processing when @@ -301,7 +302,7 @@ static void iproto_queue_schedule(struct ev_async *watcher, int events __attribute__((unused))) { - struct iproto_queue *i_queue = watcher->data; + struct iproto_queue *i_queue = (struct iproto_queue *) watcher->data; while (! iproto_queue_is_empty(i_queue)) { struct fiber *f = rlist_shift_entry(&i_queue->fiber_cache, @@ -318,7 +319,7 @@ iproto_queue_init(struct iproto_queue *i_queue, { i_queue->size = size; i_queue->begin = i_queue->end = 0; - i_queue->queue = palloc(eter_pool, size * + i_queue->queue = (struct iproto_request *) palloc(eter_pool, size * sizeof (struct iproto_request)); /** * Initialize an ev_async event which would start @@ -376,7 +377,7 @@ struct iproto_session * relative to in->end, rather than to in->pos is helpful to * make sure ibuf_reserve() or iobuf rotation don't make * the value meaningless. - */ + */ ssize_t parse_size; /** Current write position in the output buffer */ struct obuf_svp write_pos; @@ -438,7 +439,7 @@ iproto_session_create(const char *name, int fd, box_process_func *param) { struct iproto_session *session; if (SLIST_EMPTY(&iproto_session_cache)) { - session = palloc(eter_pool, sizeof(*session)); + session = (struct iproto_session *) palloc(eter_pool, sizeof(*session)); session->input.data = session->output.data = session; } else { session = SLIST_FIRST(&iproto_session_cache); @@ -488,7 +489,7 @@ iproto_session_shutdown(struct iproto_session *session) * trigger and destroy the session. * Sic: the check is mandatory to not destroy a session * twice. - */ + */ if (iproto_session_is_idle(session)) { iproto_enqueue_request(&request_queue, session, session->iobuf[0], &dummy_header, @@ -499,14 +500,13 @@ iproto_session_shutdown(struct iproto_session *session) static inline void iproto_validate_header(struct iproto_header *header, int fd) { + (void) fd; if (header->len > IPROTO_BODY_LEN_MAX) { /* * The package is too big, just close connection for now to * avoid DoS. */ - tnt_raise(SocketError, :fd in: - "received package is too big: %llu", - (unsigned long long) header->len); + tnt_raise(IllegalParams, "received package is too big"); } } @@ -536,20 +536,20 @@ iproto_validate_header(struct iproto_header *header, int fd) static struct iobuf * iproto_session_input_iobuf(struct iproto_session *session) { - struct iobuf *old = session->iobuf[0]; + struct iobuf *oldbuf = session->iobuf[0]; ssize_t to_read = sizeof(struct iproto_header) + (session->parse_size >= sizeof(struct iproto_header) ? - iproto(old->in.end - session->parse_size)->len : 0) - + iproto(oldbuf->in.end - session->parse_size)->len : 0) - session->parse_size; - if (ibuf_unused(&old->in) >= to_read) - return old; + if (ibuf_unused(&oldbuf->in) >= to_read) + return oldbuf; /** All requests are processed, reuse the buffer. */ - if (ibuf_size(&old->in) == session->parse_size) { - ibuf_reserve(&old->in, to_read); - return old; + if (ibuf_size(&oldbuf->in) == session->parse_size) { + ibuf_reserve(&oldbuf->in, to_read); + return oldbuf; } if (! iobuf_is_idle(session->iobuf[1])) { @@ -559,24 +559,24 @@ iproto_session_input_iobuf(struct iproto_session *session) */ return NULL; } - struct iobuf *new = session->iobuf[1]; + struct iobuf *newbuf = session->iobuf[1]; - ibuf_reserve(&new->in, to_read + session->parse_size); + ibuf_reserve(&newbuf->in, to_read + session->parse_size); /* * Discard unparsed data in the old buffer, otherwise it * won't be recycled when all parsed requests are processed. */ - old->in.end -= session->parse_size; + oldbuf->in.end -= session->parse_size; /* Move the cached request prefix to the new buffer. */ - memcpy(new->in.pos, old->in.end, session->parse_size); - new->in.end += session->parse_size; + memcpy(newbuf->in.pos, oldbuf->in.end, session->parse_size); + newbuf->in.end += session->parse_size; /* * Rotate buffers. Not strictly necessary, but * helps preserve response order. */ - session->iobuf[1] = old; - session->iobuf[0] = new; - return new; + session->iobuf[1] = oldbuf; + session->iobuf[0] = newbuf; + return newbuf; } /** Enqueue all requests which were read up. */ @@ -608,11 +608,11 @@ static void iproto_session_on_input(struct ev_io *watcher, int revents __attribute__((unused))) { - struct iproto_session *session = watcher->data; + struct iproto_session *session = (struct iproto_session *) watcher->data; int fd = session->input.fd; assert(fd >= 0); - @try { + try { /* Ensure we have sufficient space for the next round. */ struct iobuf *iobuf = iproto_session_input_iobuf(session); if (iobuf == NULL) { @@ -642,8 +642,8 @@ iproto_session_on_input(struct ev_io *watcher, */ if (!ev_is_active(&session->input)) ev_feed_event(&session->input, EV_READ); - } @catch (tnt_Exception *e) { - [e log]; + } catch (const Exception& e) { + e.log(); iproto_session_shutdown(session); } } @@ -675,12 +675,16 @@ iproto_flush(struct iobuf *iobuf, int fd, struct obuf_svp *svp) int iovcnt = obuf_iovcnt(&iobuf->out) - svp->pos; assert(iovcnt); ssize_t nwr; - @try { + try { sio_add_to_iov(iov, -svp->iov_len); nwr = sio_writev(fd, iov, iovcnt); - } @finally { + + sio_add_to_iov(iov, svp->iov_len); + } catch(const Exception&) { sio_add_to_iov(iov, svp->iov_len); + throw; } + if (nwr > 0) { if (svp->size + nwr == obuf_size(&iobuf->out)) { iobuf_gc(iobuf); @@ -697,11 +701,11 @@ static void iproto_session_on_output(struct ev_io *watcher, int revent __attribute__((unused))) { - struct iproto_session *session = watcher->data; + struct iproto_session *session = (struct iproto_session *) watcher->data; int fd = session->output.fd; struct obuf_svp *svp = &session->write_pos; - @try { + try { struct iobuf *iobuf; while ((iobuf = iproto_session_output_iobuf(session))) { if (iproto_flush(iobuf, fd, svp) < 0) { @@ -713,8 +717,8 @@ iproto_session_on_output(struct ev_io *watcher, } if (ev_is_active(&session->output)) ev_io_stop(&session->output); - } @catch (tnt_Exception *e) { - [e log]; + } catch (const Exception& e) { + e.log(); iproto_session_shutdown(session); } } @@ -735,15 +739,15 @@ iproto_reply_ping(struct obuf *out, struct iproto_header *req) /** Send an error packet back. */ static inline void iproto_reply_error(struct obuf *out, struct iproto_header *req, - ClientError *e) + const ClientError& e) { struct iproto_header reply = *req; - int errmsg_len = strlen(e->errmsg) + 1; - uint32_t ret_code = tnt_errcode_val(e->errcode); + int errmsg_len = strlen(e.errmsg()) + 1; + uint32_t ret_code = tnt_errcode_val(e.errcode()); reply.len = sizeof(ret_code) + errmsg_len;; obuf_dup(out, &reply, sizeof(reply)); obuf_dup(out, &ret_code, sizeof(ret_code)); - obuf_dup(out, e->errmsg, errmsg_len); + obuf_dup(out, e.errmsg(), errmsg_len); } /** Stack a reply to a single request to the fiber's io vector. */ @@ -757,10 +761,10 @@ iproto_reply(struct port_iproto *port, box_process_func callback, /* Make request body point to iproto data */ void *body = (char *) &header[1]; port_iproto_init(port, out, header); - @try { + try { callback((struct port *) port, header->msg_code, body, header->len); - } @catch (ClientError *e) { + } catch (const ClientError& e) { if (port->reply.found) obuf_rollback_to_svp(out, &port->svp); iproto_reply_error(out, header, e); @@ -774,22 +778,23 @@ iproto_process_request(struct iproto_request *request) struct iproto_header *header = request->header; struct iobuf *iobuf = request->iobuf; struct port_iproto port; - @try { - if (unlikely(! evio_is_active(&session->output))) - return; - iproto_reply(&port, *session->handler, - &iobuf->out, header); - - if (unlikely(! evio_is_active(&session->output))) - return; - if (! ev_is_active(&session->output)) - ev_feed_event(&session->output, EV_WRITE); - } @finally { + auto scope_guard = make_scoped_guard([=]{ iobuf->in.pos += sizeof(*header) + header->len; if (iproto_session_is_idle(session)) iproto_session_destroy(session); - } + }); + + if (unlikely(! evio_is_active(&session->output))) + return; + + iproto_reply(&port, *session->handler, &iobuf->out, header); + + if (unlikely(! evio_is_active(&session->output))) + return; + + if (! ev_is_active(&session->output)) + ev_feed_event(&session->output, EV_WRITE); } /** @@ -803,19 +808,19 @@ iproto_process_connect(struct iproto_request *request) struct iproto_session *session = request->session; struct iobuf *iobuf = request->iobuf; int fd = session->input.fd; - @try { /* connect. */ + try { /* connect. */ session->sid = session_create(fd); - } @catch (ClientError *e) { + } catch (const ClientError& e) { iproto_reply_error(&iobuf->out, request->header, e); - @try { + try { iproto_flush(iobuf, fd, &session->write_pos); - } @catch (tnt_Exception *e) { - [e log]; + } catch (const Exception& e) { + e.log(); } iproto_session_shutdown(session); return; - } @catch (tnt_Exception *e) { - [e log]; + } catch (const Exception& e) { + e.log(); assert(session->sid == 0); iproto_session_shutdown(session); return; @@ -852,7 +857,10 @@ iproto_on_accept(struct evio_service *service, int fd, snprintf(name, sizeof(name), "%s/%s", "iobuf", sio_strfaddr(addr)); struct iproto_session *session; - session = iproto_session_create(name, fd, service->on_accept_param); + + box_process_func *process_fun = reinterpret_cast<box_process_func*>( + service->on_accept_param); + session = iproto_session_create(name, fd, process_fun); iproto_enqueue_request(&request_queue, session, session->iobuf[0], &dummy_header, iproto_process_connect); diff --git a/src/lib/bit/CMakeLists.txt b/src/lib/bit/CMakeLists.txt index c1728e1634e2783876d0f6a4bf97245d7037246e..d30afe221644298f458de3c12d1d3705675a2a25 100644 --- a/src/lib/bit/CMakeLists.txt +++ b/src/lib/bit/CMakeLists.txt @@ -1,27 +1,3 @@ -check_builtin_function_exists("__builtin_ctz" HAVE_BUILTIN_CTZ) -check_builtin_function_exists("__builtin_ctzll" HAVE_BUILTIN_CTZLL) -check_builtin_function_exists("__builtin_clz" HAVE_BUILTIN_CLZ) -check_builtin_function_exists("__builtin_clzll" HAVE_BUILTIN_CLZLL) -check_builtin_function_exists("__builtin_popcount" HAVE_BUILTIN_POPCOUNT) -check_builtin_function_exists("__builtin_popcountll" HAVE_BUILTIN_POPCOUNTLL) -check_builtin_function_exists("__builtin_bswap32" HAVE_BUILTIN_BSWAP32) -check_builtin_function_exists("__builtin_bswap64" HAVE_BUILTIN_BSWAP64) - -if (NOT HAVE_BUILTIN_CTZ OR NOT HAVE_BUILTIN_CTZLL) - # Check if -D_GNU_SOURCE has been defined and add this flag to - # CMAKE_REQUIRED_DEFINITIONS in order to get check_prototype_definition work - get_property(var DIRECTORY PROPERTY COMPILE_DEFINITIONS) - list(FIND var "_GNU_SOURCE" var) - if (NOT var EQUAL -1) - set(CMAKE_REQUIRED_FLAGS "-Wno-error") - set(CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE") - check_c_source_compiles("#include <string.h>\n#include <strings.h>\nint main(void) { return ffsl(0L); }" - HAVE_FFSL) - check_c_source_compiles("#include <string.h>\n#include <strings.h>\nint main(void) { return ffsll(0UL); }" - HAVE_FFSLL) - endif() -endif() - if ((HAVE_BUILTIN_CTZ OR HAVE_FFSL) AND (HAVE_BUILTIN_CTZLL OR HAVE_FFSLL) AND HAVE_BUILTIN_CLZ AND HAVE_BUILTIN_CLZLL AND diff --git a/src/lib/bit/bit.c b/src/lib/bit/bit.c index f446961587f955e6464b4bfe1ac3f2d6fff764b7..c2a9b67c56495726eb31fbc649b3d0b7e819c34e 100644 --- a/src/lib/bit/bit.c +++ b/src/lib/bit/bit.c @@ -74,9 +74,9 @@ bswap_u32(uint32_t x); extern inline uint64_t bswap_u64(uint64_t x); -#define BITINDEX_NAIVE(x, bitsize) { \ +#define BITINDEX_NAIVE(type, x, bitsize) { \ /* naive generic implementation, worst case */ \ - typeof(x) bit = 1; \ + type bit = 1; \ int i = 0; \ for (int k = 0; k < bitsize; k++) { \ if (x & bit) { \ @@ -116,7 +116,7 @@ bit_index_u32(uint32_t x, int *indexes, int offset) indexes[i] = 0; return indexes + i; #else /* !defined(HAVE_BUILTIN_CTZ) */ - BITINDEX_NAIVE(x, sizeof(uint32_t) * CHAR_BIT); + BITINDEX_NAIVE(uint32_t, x, sizeof(uint32_t) * CHAR_BIT); #endif } @@ -146,7 +146,7 @@ bit_index_u64(uint64_t x, int *indexes, int offset) { indexes[i] = 0; return indexes + i; #else /* !defined(HAVE_CTZ) */ - BITINDEX_NAIVE(x, sizeof(uint64_t) * CHAR_BIT); + BITINDEX_NAIVE(uint64_t, x, sizeof(uint64_t) * CHAR_BIT); #endif } diff --git a/src/lib/bitset/index.c b/src/lib/bitset/index.c index a30c27d70dd7a2acd0be8a144d091e4181dcdf54..7250dcb5208a72295a3227d26b42a07f6ebc65e8 100644 --- a/src/lib/bitset/index.c +++ b/src/lib/bitset/index.c @@ -388,4 +388,4 @@ bitset_index_init_iterator(struct bitset_index *index, } extern inline size_t -bitset_index_size(struct bitset_index *index); +bitset_index_size(const struct bitset_index *index); diff --git a/src/lib/bitset/page.h b/src/lib/bitset/page.h index 79b4bbf4ff3f7633e5d0c943fcc94853a717bf5a..4f519b30c8183db31a7c2f156f885b92f7400c6e 100644 --- a/src/lib/bitset/page.h +++ b/src/lib/bitset/page.h @@ -47,6 +47,10 @@ #include <limits.h> #include <assert.h> +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + enum { /** How many bytes to store in one page */ BITSET_PAGE_DATA_SIZE = 160 @@ -187,4 +191,9 @@ bitset_page_dump(struct bitset_page *page, FILE *stream); rb_proto(, bitset_pages_, bitset_pages_t, struct bitset_page) + +#if defined(__cplusplus) +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + #endif /* TARANTOOL_LIB_BITSET_PAGE_H_INCLUDED */ diff --git a/src/log_io.m b/src/log_io.cc similarity index 92% rename from src/log_io.m rename to src/log_io.cc index 1eb9fd89db0dc9e240e7f8cf1a0e9476392aec9f..27fb967a75590931e131bc929921c31dc29037d6 100644 --- a/src/log_io.m +++ b/src/log_io.cc @@ -45,9 +45,9 @@ const char v11[] = "0.11\n"; void header_v11_sign(struct header_v11 *header) { - header->data_crc32c = crc32_calc(0, (void *) header + sizeof(struct + header->data_crc32c = crc32_calc(0, (const unsigned char *) header + sizeof(struct header_v11), header->len); - header->header_crc32c = crc32_calc(0, (void *) &header->lsn, + header->header_crc32c = crc32_calc(0, (const unsigned char *) &header->lsn, sizeof(struct header_v11) - sizeof(header->header_crc32c)); } @@ -66,23 +66,28 @@ row_v11_fill(struct row_v11 *row, u64 lsn, u16 tag, u64 cookie, sizeof(row->tag) + sizeof(row->cookie)); } -/* {{{ struct log_dir and related functions */ - struct log_dir snap_dir = { - .filetype = "SNAP\n", - .filename_ext = ".snap" + /* .panic_if_error = */ false, + /* .sync_is_async = */ false, + /* .open_wflags = */ 0, + /* .filetype = */ "SNAP\n", + /* .filename_ext = */ ".snap", + /* .dirname = */ NULL }; struct log_dir wal_dir = { - .sync_is_async = true, - .filetype = "XLOG\n", - .filename_ext = ".xlog" + /* .panic_if_error = */ false, + /* .sync_is_async = */ true, + /* .open_wflags = */ 0, + /* .filetype = */ "XLOG\n", + /* .filename_ext = */ ".xlog", + /* .dirname = */ NULL }; static int cmp_i64(const void *_a, const void *_b) { - const i64 *a = _a, *b = _b; + const i64 *a = (const i64 *) _a, *b = (const i64 *) _b; if (*a == *b) return 0; return (*a > *b) ? 1 : -1; @@ -94,7 +99,7 @@ scan_dir(struct log_dir *dir, i64 **ret_lsn) ssize_t result = -1; size_t i = 0, size = 1024; ssize_t ext_len = strlen(dir->filename_ext); - i64 *lsn = palloc(fiber->gc_pool, sizeof(i64) * size); + i64 *lsn = (i64 *) palloc(fiber->gc_pool, sizeof(i64) * size); DIR *dh = opendir(dir->dirname); if (lsn == NULL || dh == NULL) @@ -138,7 +143,7 @@ scan_dir(struct log_dir *dir, i64 **ret_lsn) i++; if (i == size) { - i64 *n = palloc(fiber->gc_pool, sizeof(i64) * size * 2); + i64 *n = (i64 *) palloc(fiber->gc_pool, sizeof(i64) * size * 2); if (n == NULL) goto out; memcpy(n, lsn, sizeof(i64) * size); @@ -214,7 +219,8 @@ format_filename(struct log_dir *dir, i64 lsn, enum log_suffix suffix) /* {{{ struct log_io_cursor */ -#define ROW_EOF (void *)1 +/* TODO: wtf? */ +#define ROW_EOF (struct tbuf *) 1 static struct tbuf * row_reader_v11(FILE *f, struct palloc_pool *pool) @@ -230,7 +236,7 @@ row_reader_v11(FILE *f, struct palloc_pool *pool) m->size = sizeof(struct header_v11); /* header crc32c calculated on <lsn, tm, len, data_crc32c> */ - header_crc = crc32_calc(0, m->data + offsetof(struct header_v11, lsn), + header_crc = crc32_calc(0, (const unsigned char *) m->data + offsetof(struct header_v11, lsn), sizeof(struct header_v11) - offsetof(struct header_v11, lsn)); if (header_v11(m)->header_crc32c != header_crc) { @@ -244,7 +250,7 @@ row_reader_v11(FILE *f, struct palloc_pool *pool) m->size += header_v11(m)->len; - data_crc = crc32_calc(0, m->data + sizeof(struct header_v11), header_v11(m)->len); + data_crc = crc32_calc(0, (const unsigned char *) m->data + sizeof(struct header_v11), header_v11(m)->len); if (header_v11(m)->data_crc32c != data_crc) { say_error("data crc32c mismatch"); return NULL; @@ -289,6 +295,7 @@ struct tbuf * log_io_cursor_next(struct log_io_cursor *i) { struct log_io *l = i->log; + struct tbuf *row; log_magic_t magic; off_t marker_offset = 0; @@ -327,7 +334,7 @@ log_io_cursor_next(struct log_io_cursor *i) (uintmax_t)i->good_offset); say_debug("magic found at 0x%08jx", (uintmax_t)marker_offset); - struct tbuf *row = row_reader_v11(l->f, fiber->gc_pool); + row = row_reader_v11(l->f, fiber->gc_pool); if (row == ROW_EOF) goto eof; @@ -393,7 +400,7 @@ inprogress_log_rename(struct log_io *l) assert(strcmp(suffix, inprogress_suffix) == 0); /* Create a new filename without '.inprogress' suffix. */ - new_filename = alloca(suffix - filename + 1); + new_filename = (char *) alloca(suffix - filename + 1); memcpy(new_filename, filename, suffix - filename); new_filename[suffix - filename] = '\0'; @@ -562,7 +569,7 @@ log_io_open(struct log_dir *dir, enum log_mode mode, { struct log_io *l = NULL; int save_errno; - const char *errmsg; + const char *errmsg = NULL; /* * Check fopen() result the caller first thing, to * preserve the errno. @@ -571,7 +578,7 @@ log_io_open(struct log_dir *dir, enum log_mode mode, errmsg = strerror(errno); goto error; } - l = calloc(1, sizeof(*l)); + l = (struct log_io *) calloc(1, sizeof(*l)); if (l == NULL) { errmsg = strerror(errno); goto error; @@ -619,7 +626,8 @@ struct log_io * log_io_open_for_write(struct log_dir *dir, i64 lsn, enum log_suffix suffix) { char *filename; - + FILE *f; + int fd; assert(lsn != 0); if (suffix == INPROGRESS) { @@ -638,12 +646,13 @@ log_io_open_for_write(struct log_dir *dir, i64 lsn, enum log_suffix suffix) * Open the <lsn>.<suffix>.inprogress file. If it exists, * open will fail. */ - int fd = open(filename, + + fd = open(filename, O_WRONLY | O_CREAT | O_EXCL | dir->open_wflags, 0664); if (fd < 0) goto error; say_info("creating `%s'", filename); - FILE *f = fdopen(fd, "w"); + f = fdopen(fd, "w"); return log_io_open(dir, LOG_WRITE, filename, suffix, f); error: say_syserror("%s: failed to open `%s'", __func__, filename); diff --git a/src/lua/cjson.m b/src/lua/cjson.cc similarity index 99% rename from src/lua/cjson.m rename to src/lua/cjson.cc index 112768bc97b309d54f217e95d077a2057882028e..45dd508511995d96790365d75fe555049653697d 100644 --- a/src/lua/cjson.m +++ b/src/lua/cjson.cc @@ -28,9 +28,11 @@ */ #include "lua/cjson.h" +extern "C" { #include "lua.h" #include "lauxlib.h" #include "lualib.h" +} int luaopen_cjson(lua_State *l); diff --git a/src/lua/info.m b/src/lua/info.cc similarity index 98% rename from src/lua/info.m rename to src/lua/info.cc index 03bab51ec09f31a2b54f34d947d37ca7eb943d57..a62c3be3a2240a2c605276fcb4785d18ab866927 100644 --- a/src/lua/info.m +++ b/src/lua/info.cc @@ -30,9 +30,11 @@ #include "lua/info.h" #include "lua/init.h" -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" +extern "C" { +#include <lua.h> +#include <lauxlib.h> +#include <lualib.h> +} /* extern "C" */ #include <say.h> #include <string.h> diff --git a/src/lua/init.m b/src/lua/init.cc similarity index 96% rename from src/lua/init.m rename to src/lua/init.cc index 48e03146a32501711e4a89a01e769c4c26ac5302..b2b3a72a50dbe586c84fbc4b689b9ab3ce8931c4 100644 --- a/src/lua/init.m +++ b/src/lua/init.cc @@ -31,16 +31,16 @@ #include "box/box.h" #include "tbuf.h" -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" - -#include "lj_obj.h" -#include "lj_ctype.h" -#include "lj_cdata.h" -#include "lj_cconv.h" -#include "lj_state.h" -#include <ctype.h> +extern "C" { +#include <lua.h> +#include <lauxlib.h> +#include <lualib.h> +#include <lj_obj.h> +#include <lj_ctype.h> +#include <lj_cdata.h> +#include <lj_cconv.h> +#include <lj_state.h> +} /* extern "C" */ #include "fiber.h" #include "lua_ipc.h" @@ -52,10 +52,13 @@ #include "lua/session.h" #include "lua/cjson.h" +#include <ctype.h> #include <sys/time.h> #include <sys/types.h> -#include TARANTOOL_CONFIG +extern "C" { +#include <cfg/tarantool_box_cfg.h> +} /* extern "C" */ /** * tarantool start-up file @@ -151,7 +154,7 @@ luaL_pushcdata(struct lua_State *L, CTypeID id, int bits) GCcdata *cd = lj_cdata_new(cts, id, bits); TValue *o = L->top; setcdataV(L, o, cd); - lj_cconv_ct_init(cts, ct, sz, cdataptr(cd), o, 0); + lj_cconv_ct_init(cts, ct, sz, (uint8_t *) cdataptr(cd), o, 0); incr_top(L); return cd; } @@ -300,7 +303,7 @@ lbox_pushfiber(struct lua_State *L, struct fiber *f) /* push the key back */ lua_pushlightuserdata(L, f); /* create a new userdata */ - void **ptr = lua_newuserdata(L, sizeof(void *)); + void **ptr = (void **) lua_newuserdata(L, sizeof(void *)); *ptr = f; luaL_getmetatable(L, fiberlib_name); lua_setmetatable(L, -2); @@ -324,7 +327,7 @@ lbox_pushfiber(struct lua_State *L, struct fiber *f) static struct fiber * lbox_checkfiber(struct lua_State *L, int index) { - return *(void **) luaL_checkudata(L, index, fiberlib_name); + return *(struct fiber **) luaL_checkudata(L, index, fiberlib_name); } static struct fiber * @@ -335,7 +338,7 @@ lua_isfiber(struct lua_State *L, int narg) luaL_getmetatable(L, fiberlib_name); struct fiber *f = NULL; if (lua_equal(L, -1, -2)) - f = * (void **) lua_touserdata(L, narg); + f = * (struct fiber **) lua_touserdata(L, narg); lua_pop(L, 2); return f; } @@ -401,7 +404,7 @@ box_lua_fiber_get_caller(struct lua_State *L) lua_getfield(L, -1, "callers"); lua_pushthread(L); lua_gettable(L, -2); - struct fiber *caller = lua_touserdata(L, -1); + struct fiber *caller = (struct fiber *) lua_touserdata(L, -1); /* Pop the caller, the callers table, the fiberlib metatable. */ lua_pop(L, 3); return caller; @@ -484,13 +487,23 @@ box_lua_fiber_run(va_list ap __attribute__((unused))) * completion status plus whatever the coroutine main * function returns. Follow this style here. */ - @try { + auto cleanup = [=] { + /* + * If the coroutine has detached itself, collect + * its resources here. + */ + luaL_unref(L, LUA_REGISTRYINDEX, coro_ref); + }; + + try { lua_call(L, lua_gettop(L) - 1, LUA_MULTRET); /* push completion status */ lua_pushboolean(L, true); /* move 'true' to stack start */ lua_insert(L, 1); - } @catch (FiberCancelException *e) { + + cleanup(); + } catch (const FiberCancelException& e) { box_lua_fiber_clear_coro(tarantool_L, fiber); /* * Note: FiberCancelException leaves garbage on @@ -498,20 +511,24 @@ box_lua_fiber_run(va_list ap __attribute__((unused))) * possible to cancel a fiber which is not * scheduled, and cancel() is synchronous. */ - @throw; - } @catch (tnt_Exception *e) { + + cleanup(); + throw; + } catch (const Exception& e) { /* pop any possible garbage */ lua_settop(L, 0); /* completion status */ lua_pushboolean(L, false); /* error message */ - lua_pushstring(L, [e errmsg]); + lua_pushstring(L, e.errmsg()); if (box_lua_fiber_get_coro(tarantool_L, fiber) == NULL) { /* The fiber is detached, log the error. */ - [e log]; + e.log(); } - } @catch (id allOthers) { + + cleanup(); + } catch (...) { lua_settop(L, 1); /* * The error message is already there. @@ -525,12 +542,8 @@ box_lua_fiber_run(va_list ap __attribute__((unused))) /* The fiber is detached, log the error. */ say_error("%s", lua_tostring(L, -1)); } - } @finally { - /* - * If the coroutine has detached itself, collect - * its resources here. - */ - luaL_unref(L, LUA_REGISTRYINDEX, coro_ref); + + cleanup(); } /* * L stack contains nothing but call results. @@ -622,7 +635,7 @@ lbox_fiber_resume(struct lua_State *L) assert(f->fid == fid); tarantool_lua_set_out(child_L, NULL); /* Find out the state of the child fiber. */ - enum fiber_state child_state = lua_tointeger(child_L, -1); + enum fiber_state child_state = (enum fiber_state) lua_tointeger(child_L, -1); lua_pop(child_L, 1); /* Get the results */ nargs = lua_gettop(child_L); @@ -1001,13 +1014,13 @@ lbox_pcall(struct lua_State *L) * Lua pcall() returns true/false for completion status * plus whatever the called function returns. */ - @try { + try { lua_call(L, lua_gettop(L) - 1, LUA_MULTRET); /* push completion status */ lua_pushboolean(L, true); /* move 'true' to stack start */ lua_insert(L, 1); - } @catch (ClientError *e) { + } catch (const ClientError& e) { /* * Note: FiberCancelException passes through this * catch and thus leaves garbage on coroutine @@ -1018,10 +1031,10 @@ lbox_pcall(struct lua_State *L) /* completion status */ lua_pushboolean(L, false); /* error message */ - lua_pushstring(L, e->errmsg); - } @catch (tnt_Exception *e) { - @throw; - } @catch (id allOthers) { + lua_pushstring(L, e.errmsg()); + } catch (const Exception& e) { + throw; + } catch (...) { lua_settop(L, 1); /* completion status */ lua_pushboolean(L, false); @@ -1204,14 +1217,14 @@ tarantool_lua_dostring(struct lua_State *L, const char *str) if (r) return r; } - @try { + try { lua_call(L, 0, LUA_MULTRET); - } @catch (FiberCancelException *e) { - @throw; - } @catch (tnt_Exception *e) { - lua_pushstring(L, [e errmsg]); + } catch (const FiberCancelException& e) { + throw; + } catch (const Exception& e) { + lua_pushstring(L, e.errmsg()); return 1; - } @catch (id allOthers) { + } catch (...) { return 1; } return 0; @@ -1290,7 +1303,7 @@ tarantool_lua_load_cfg(struct lua_State *L, struct tarantool_cfg *cfg) while ((key = tarantool_cfg_iterator_next(i, cfg, &value)) != NULL) { if (value == NULL) continue; - char *quote = is_string(value) ? "'" : ""; + const char *quote = is_string(value) ? "'" : ""; if (strchr(key, '.') == NULL) { lua_pushfstring(L, "box.cfg.%s = %s%s%s\n", key, quote, value, quote); diff --git a/src/lua/lua_ipc.m b/src/lua/lua_ipc.cc similarity index 96% rename from src/lua/lua_ipc.m rename to src/lua/lua_ipc.cc index 8b10960a5871c418b357d984774405eb00b0fe35..da40956ca606c96eb317436ed6e6d3dad5c8de34 100644 --- a/src/lua/lua_ipc.m +++ b/src/lua/lua_ipc.cc @@ -30,9 +30,11 @@ #include <stdlib.h> -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" +extern "C" { +#include <lua.h> +#include <lauxlib.h> +#include <lualib.h> +} /* extern "C" */ #include "ipc.h" #include "lua/init.h" @@ -58,7 +60,7 @@ lbox_ipc_channel(struct lua_State *L) if (!ch) luaL_error(L, "box.channel: Not enough memory"); - void **ptr = lua_newuserdata(L, sizeof(void *)); + void **ptr = (void **) lua_newuserdata(L, sizeof(void *)); luaL_getmetatable(L, channel_lib); lua_pushstring(L, "rid"); /* first object id */ @@ -73,7 +75,7 @@ lbox_ipc_channel(struct lua_State *L) static inline struct ipc_channel * lbox_check_channel(struct lua_State *L, int narg) { - return * (void **) luaL_checkudata(L, narg, channel_lib); + return *(struct ipc_channel **) luaL_checkudata(L, narg, channel_lib); } static int diff --git a/src/lua/lua_socket.m b/src/lua/lua_socket.cc similarity index 93% rename from src/lua/lua_socket.m rename to src/lua/lua_socket.cc index c341be5ed9095839e73e89e0ee806e6e2de53854..c855eda4c72c5d0b3f21475e5d1f93c0a438c649 100644 --- a/src/lua/lua_socket.m +++ b/src/lua/lua_socket.cc @@ -27,9 +27,12 @@ * SUCH DAMAGE. */ #include "lua_socket.h" -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" + +extern "C" { +#include <lua.h> +#include <lauxlib.h> +#include <lualib.h> +} /* extern "C" */ #include "sio.h" #include "evio.h" @@ -80,7 +83,8 @@ struct bio_socket { static int bio_pushsocket(struct lua_State *L, int socktype) { - struct bio_socket *s = lua_newuserdata(L, sizeof(struct bio_socket)); + struct bio_socket *s = (struct bio_socket *) + lua_newuserdata(L, sizeof(struct bio_socket)); luaL_getmetatable(L, socketlib_name); lua_setmetatable(L, -2); coio_init(&s->io_r); @@ -104,7 +108,7 @@ bio_checksocket(struct lua_State *L, int narg) /* avoiding unnecessary luajit assert */ if (lua_gettop(L) < narg) luaL_error(L, "box.socket: incorrect method call"); - return luaL_checkudata(L, narg, socketlib_name); + return (struct bio_socket *) luaL_checkudata(L, narg, socketlib_name); } static inline struct bio_socket * @@ -142,7 +146,7 @@ bio_initbuf(struct bio_socket *s) static inline int bio_pushstatus(struct lua_State *L, enum bio_status s) { - static char *status_strs[] = {"error", "timeout", "eof", "limit"}; + static const char *status_strs[] = {"error", "timeout", "eof", "limit"}; lua_pushstring(L, status_strs[s]); return 1; } @@ -319,17 +323,22 @@ lbox_socket_connect(struct lua_State *L) return bio_pushsockerror(L, s, errno); evio_timeout_update(start, &delay); - @try { + try { /* connect to a first available host */ - if (coio_connect_addrinfo(&s->io_w, ai, delay)) + int r = coio_connect_addrinfo(&s->io_w, ai, delay); + freeaddrinfo(ai); + if (r) return bio_pushsockerror(L, s, ETIMEDOUT); + /* set coio reader socket */ s->io_r.fd = s->io_w.fd; - } @catch (SocketError *e) { - return bio_pushsockerror(L, s, errno); - } @finally { + } catch (const SocketError& e) { + say_error("catch(SocketError&)"); freeaddrinfo(ai); + + return bio_pushsockerror(L, s, errno); } + bio_initbuf(s); /* Success */ lua_settop(L, 1); @@ -372,19 +381,26 @@ lbox_socket_send(struct lua_State *L) evio_timeout_update(start, &delay); int rc; - @try { + try { ssize_t nwr = coio_write_timeout(&s->io_w, buf, buf_size, delay); if (nwr < buf_size) { rc = bio_pushsenderror(L, s, nwr, ETIMEDOUT); + mutex_unlock(&s->io_w_mutex); return rc; } - } @catch (SocketError *e) { + + mutex_unlock(&s->io_w_mutex); + } catch (const SocketError& e) { + mutex_unlock(&s->io_w_mutex); + rc = bio_pushsenderror(L, s, 0, errno); return rc; - } @finally { + } catch (const Exception& e) { mutex_unlock(&s->io_w_mutex); + throw; } + /* case #1: Success */ lua_pushinteger(L, buf_size); return 1; @@ -439,15 +455,20 @@ lbox_socket_recv(struct lua_State *L) to_read = sz - ibuf_size(in); ssize_t nrd; - @try { + try { nrd = coio_bread_timeout(&s->io_r, in, to_read, delay); - } @catch (SocketError *e) { + mutex_unlock(&s->io_r_mutex); + } catch (const SocketError& e) { + mutex_unlock(&s->io_r_mutex); + rc = bio_pushrecverror(L, s, errno); return rc; - } @finally { + } catch (const Exception& e) { mutex_unlock(&s->io_r_mutex); + throw; } + if (nrd < to_read) { /* timeout or EOF. */ if (errno == ETIMEDOUT) @@ -633,11 +654,11 @@ lbox_socket_readline(struct lua_State *L) struct ibuf *in = &s->iob->in; int rc; - @try { + try { /* readline implementation uses a simple state machine * to determine current position of a possible * separator. */ - struct readline_state *rs = + struct readline_state *rs = (struct readline_state *) palloc(in->pool, sizeof(struct readline_state) * rs_size); readline_state_init(L, rs, seplist); @@ -647,6 +668,7 @@ lbox_socket_readline(struct lua_State *L) lua_pushlstring(L, in->pos, bottom); s->iob->in.pos += bottom; bio_pushstatus(L, BIO_LIMIT); + mutex_unlock(&s->io_r_mutex); return 2; } @@ -662,6 +684,7 @@ lbox_socket_readline(struct lua_State *L) rc = bio_pushrecverror(L, s, ETIMEDOUT); else rc = bio_pusheof(L, s); + mutex_unlock(&s->io_r_mutex); return rc; } } @@ -673,11 +696,15 @@ lbox_socket_readline(struct lua_State *L) evio_timeout_update(start, &delay); } - } @catch (SocketError *e) { + + mutex_unlock(&s->io_r_mutex); + } catch (const SocketError& e) { + mutex_unlock(&s->io_r_mutex); rc = bio_pushrecverror(L, s, errno); return rc; - } @finally { + } catch (const Exception& e) { mutex_unlock(&s->io_r_mutex); + throw; } /* case #1: success, separator matched */ @@ -713,14 +740,16 @@ lbox_socket_bind(struct lua_State *L) struct addrinfo *ai = coeio_resolve(s->socktype, host, port, timeout); if (ai == NULL) return bio_pusherror(L, s, errno); - @try { + try { evio_bind_addrinfo(&s->io_w, ai); - } @catch (SocketError *e) { + freeaddrinfo(ai); + } catch (const SocketError& e) { /* case #2: error */ - return bio_pusherror(L, s, errno); - } @finally { freeaddrinfo(ai); + say_error("socket SocketError&"); + return bio_pusherror(L, s, errno); } + /* case #1: Success */ lua_settop(L, 1); return 1; @@ -768,12 +797,12 @@ lbox_socket_accept(struct lua_State *L) struct sockaddr_storage addr; /* push client socket */ bio_pushsocket(L, SOCK_STREAM); - struct bio_socket *client = lua_touserdata(L, -1); - @try { + struct bio_socket *client = (struct bio_socket *) lua_touserdata(L, -1); + try { client->io_w.fd = coio_accept(&s->io_w, (struct sockaddr_in*)&addr, - sizeof(addr), timeout); + sizeof(addr), timeout); client->io_r.fd = client->io_w.fd; - } @catch (SocketError *e) { + } catch (const SocketError& e) { return bio_pusherror(L, s, errno); } /* get user host and port */ @@ -837,20 +866,24 @@ lbox_socket_sendto(struct lua_State *L) } size_t nwr; - @try { + try { /* maybe init the socket */ if (! evio_is_active(&s->io_w)) evio_socket(&s->io_w, addr->sa_family, s->socktype, 0); nwr = coio_sendto_timeout(&s->io_w, buf, buf_size, 0, (struct sockaddr_in*)addr, addrlen, delay); - } @catch (SocketError *e) { + if (a) { + freeaddrinfo(a); + } + } catch (const SocketError& e) { /* case #2-3: error or timeout */ - return bio_pushsenderror(L, s, 0, errno); - } @finally { if (a) { freeaddrinfo(a); } + say_error("catch(SocketError&)"); + return bio_pushsenderror(L, s, 0, errno); } + if (nwr == 0) { assert(errno == ETIMEDOUT); return bio_pushsenderror(L, s, 0, ETIMEDOUT); @@ -886,12 +919,12 @@ lbox_socket_recvfrom(struct lua_State *L) struct sockaddr_storage addr; struct ibuf *in = &s->iob->in; size_t nrd; - @try { + try { ibuf_reserve(in, buf_size); nrd = coio_recvfrom_timeout(&s->io_w, in->pos, buf_size, 0, - (struct sockaddr_in*)&addr, - sizeof(addr), timeout); - } @catch (SocketError *e) { + (struct sockaddr_in*)&addr, + sizeof(addr), timeout); + } catch (const SocketError& e) { return bio_pushrecverror(L, s, errno); } if (nrd == 0) { diff --git a/src/lua/session.m b/src/lua/session.cc similarity index 93% rename from src/lua/session.m rename to src/lua/session.cc index 3f007b13d7e93a80c2a9b140b45d359df8a111ab..508c34247cbd689a78bc0d9fd9113d94090e57fe 100644 --- a/src/lua/session.m +++ b/src/lua/session.cc @@ -29,9 +29,11 @@ #include "lua/session.h" #include "lua/init.h" +extern "C" { #include <lua.h> #include <lauxlib.h> #include <lualib.h> +} #include "fiber.h" #include "session.h" @@ -102,7 +104,8 @@ static struct lbox_session_trigger on_disconnect = static void lbox_session_run_trigger(void *param) { - struct lbox_session_trigger *trigger = param; + struct lbox_session_trigger *trigger = + (struct lbox_session_trigger *) param; /* Copy the referenced callable object object stack. */ lua_State *L = lua_newthread(tarantool_L); int coro_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX); @@ -110,15 +113,15 @@ lbox_session_run_trigger(void *param) /** Move the function to be called to the new coro. */ lua_xmove(tarantool_L, L, 1); - @try { + try { lua_call(L, 0, 0); - } @catch (tnt_Exception *e) { - @throw; - } @catch ( id allOthers ) { - tnt_raise(ClientError, :ER_PROC_LUA, - lua_tostring(L, -1)); - } @finally { luaL_unref(tarantool_L, LUA_REGISTRYINDEX, coro_ref); + } catch (const Exception& e) { + luaL_unref(tarantool_L, LUA_REGISTRYINDEX, coro_ref); + throw; + } catch (...) { + luaL_unref(tarantool_L, LUA_REGISTRYINDEX, coro_ref); + tnt_raise(ClientError, ER_PROC_LUA, lua_tostring(L, -1)); } } diff --git a/src/lua/slab.m b/src/lua/slab.cc similarity index 96% rename from src/lua/slab.m rename to src/lua/slab.cc index 538e747c30794d9b2fcf9a6bd78711666237af2a..ccffceeb0daceefbb792076a944c01bfb7f553a3 100644 --- a/src/lua/slab.m +++ b/src/lua/slab.cc @@ -27,17 +27,21 @@ * SUCH DAMAGE. */ #include "lua/slab.h" + +extern "C" { +#include <lua.h> +#include <lauxlib.h> +#include <lualib.h> +} /* extern "C" */ + #include "lua/init.h" -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" #include <salloc.h> /** A callback passed into salloc_stat() and invoked for every slab class. */ static int salloc_stat_lua_cb(const struct slab_cache_stats *cstat, void *cb_ctx) { - struct lua_State *L = cb_ctx; + struct lua_State *L = (struct lua_State *) cb_ctx; /* * Create a Lua table for every slab class. A class is diff --git a/src/lua/stat.m b/src/lua/stat.cc similarity index 93% rename from src/lua/stat.m rename to src/lua/stat.cc index f0652327905d1221bf1479da51d22e1c55f712e0..5fdfe919d1e0ee0e7b7aa0de02576734340f1397 100644 --- a/src/lua/stat.m +++ b/src/lua/stat.cc @@ -1,4 +1,5 @@ /* + * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: @@ -27,12 +28,15 @@ * SUCH DAMAGE. */ #include "lua/stat.h" -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" + #include <string.h> #include <stat.h> +extern "C" { +#include <lua.h> +#include <lauxlib.h> +#include <lualib.h> +} /* extern "C" */ static void fill_stat_item(struct lua_State *L, int rps, i64 total) @@ -49,7 +53,7 @@ fill_stat_item(struct lua_State *L, int rps, i64 total) static int set_stat_item(const char *name, int rps, i64 total, void *cb_ctx) { - struct lua_State *L = cb_ctx; + struct lua_State *L = (struct lua_State *) cb_ctx; lua_pushstring(L, name); lua_newtable(L); @@ -68,7 +72,7 @@ set_stat_item(const char *name, int rps, i64 total, void *cb_ctx) static int seek_stat_item(const char *name, int rps, i64 total, void *cb_ctx) { - struct lua_State *L = cb_ctx; + struct lua_State *L = (struct lua_State *) cb_ctx; if (strcmp(name, lua_tostring(L, -1)) != 0) return 0; diff --git a/src/lua/uuid.m b/src/lua/uuid.cc similarity index 95% rename from src/lua/uuid.m rename to src/lua/uuid.cc index 3b495e8c2e7720cd1e9d79cc2f47a0c1f305eaf7..9c2e3d4eacfb883583aafde91bd982f993bbb923 100644 --- a/src/lua/uuid.m +++ b/src/lua/uuid.cc @@ -31,9 +31,12 @@ #include <stdio.h> #include <string.h> #include <dlfcn.h> -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" + +extern "C" { +#include <lua.h> +#include <lauxlib.h> +#include <lualib.h> +} /* extern "C" */ /** libuuid API */ typedef unsigned char uuid_t[16]; @@ -70,7 +73,7 @@ loaddl_and_call(struct lua_State *L, box_function f) if (!libuuid) return luaL_error(L, "box.uuid(): %s", dlerror()); - uuid_generate = dlsym(libuuid, "uuid_generate"); + uuid_generate = (decltype(uuid_generate)) dlsym(libuuid, "uuid_generate"); if (!uuid_generate) { lua_pushfstring(L, "box.uuid(): %s", dlerror()); dlclose(libuuid); diff --git a/src/memcached-grammar.m b/src/memcached-grammar.cc similarity index 87% rename from src/memcached-grammar.m rename to src/memcached-grammar.cc index e79e7e187367096acf651ea42c56adedf79ba7a1..7b177d3c14b5a3a5e3ceb7c872416ea7281db76a 100644 --- a/src/memcached-grammar.m +++ b/src/memcached-grammar.cc @@ -30,7 +30,7 @@ */ -#line 34 "src/memcached-grammar.m" +#line 34 "src/memcached-grammar.cc" static const int memcached_start = 1; static const int memcached_first_final = 197; static const int memcached_error = 0; @@ -69,12 +69,12 @@ memcached_dispatch(struct ev_io *coio, struct iobuf *iobuf) say_debug("memcached_dispatch '%.*s'", MIN((int)(pe - p), 40) , p); -#line 73 "src/memcached-grammar.m" +#line 73 "src/memcached-grammar.cc" { cs = memcached_start; } -#line 78 "src/memcached-grammar.m" +#line 78 "src/memcached-grammar.cc" { if ( p == pe ) goto _test_eof; @@ -146,7 +146,7 @@ case 5: goto st0; goto tr15; tr15: -#line 223 "src/memcached-grammar.rl" +#line 222 "src/memcached-grammar.rl" { fstart = p; for (; p < pe && *p != ' ' && *p != '\r' && *p != '\n'; p++); @@ -162,7 +162,7 @@ case 5: if ( ++p == pe ) goto _test_eof6; case 6: -#line 166 "src/memcached-grammar.m" +#line 166 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto st7; goto st0; @@ -176,49 +176,49 @@ case 7: goto tr17; goto st0; tr17: -#line 222 "src/memcached-grammar.rl" +#line 221 "src/memcached-grammar.rl" { fstart = p; } goto st8; st8: if ( ++p == pe ) goto _test_eof8; case 8: -#line 187 "src/memcached-grammar.m" +#line 187 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto tr18; if ( 48 <= (*p) && (*p) <= 57 ) goto st8; goto st0; tr18: -#line 245 "src/memcached-grammar.rl" +#line 244 "src/memcached-grammar.rl" {flags = natoq(fstart, p);} goto st9; st9: if ( ++p == pe ) goto _test_eof9; case 9: -#line 201 "src/memcached-grammar.m" +#line 201 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto st9; if ( 48 <= (*p) && (*p) <= 57 ) goto tr21; goto st0; tr21: -#line 222 "src/memcached-grammar.rl" +#line 221 "src/memcached-grammar.rl" { fstart = p; } goto st10; st10: if ( ++p == pe ) goto _test_eof10; case 10: -#line 215 "src/memcached-grammar.m" +#line 215 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto tr22; if ( 48 <= (*p) && (*p) <= 57 ) goto st10; goto st0; tr22: -#line 238 "src/memcached-grammar.rl" +#line 237 "src/memcached-grammar.rl" { exptime = natoq(fstart, p); if (exptime > 0 && exptime <= 60*60*24*30) @@ -229,21 +229,21 @@ case 10: if ( ++p == pe ) goto _test_eof11; case 11: -#line 233 "src/memcached-grammar.m" +#line 233 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto st11; if ( 48 <= (*p) && (*p) <= 57 ) goto tr25; goto st0; tr25: -#line 222 "src/memcached-grammar.rl" +#line 221 "src/memcached-grammar.rl" { fstart = p; } goto st12; st12: if ( ++p == pe ) goto _test_eof12; case 12: -#line 247 "src/memcached-grammar.m" +#line 247 "src/memcached-grammar.cc" switch( (*p) ) { case 10: goto tr26; case 13: goto tr27; @@ -253,11 +253,11 @@ case 12: goto st12; goto st0; tr26: -#line 246 "src/memcached-grammar.rl" +#line 245 "src/memcached-grammar.rl" {bytes = natoq(fstart, p);} -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 251 "src/memcached-grammar.rl" +#line 250 "src/memcached-grammar.rl" { size_t parsed = p - in->pos; while (ibuf_size(in) - parsed < bytes + 2) { @@ -280,7 +280,7 @@ case 12: goto exit; } } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; @@ -297,9 +297,9 @@ case 12: } goto st197; tr30: -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 251 "src/memcached-grammar.rl" +#line 250 "src/memcached-grammar.rl" { size_t parsed = p - in->pos; while (ibuf_size(in) - parsed < bytes + 2) { @@ -322,7 +322,7 @@ case 12: goto exit; } } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; @@ -339,11 +339,11 @@ case 12: } goto st197; tr39: -#line 282 "src/memcached-grammar.rl" +#line 281 "src/memcached-grammar.rl" { noreply = true; } -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 251 "src/memcached-grammar.rl" +#line 250 "src/memcached-grammar.rl" { size_t parsed = p - in->pos; while (ibuf_size(in) - parsed < bytes + 2) { @@ -366,7 +366,7 @@ case 12: goto exit; } } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; @@ -383,11 +383,11 @@ case 12: } goto st197; tr58: -#line 246 "src/memcached-grammar.rl" +#line 245 "src/memcached-grammar.rl" {bytes = natoq(fstart, p);} -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 251 "src/memcached-grammar.rl" +#line 250 "src/memcached-grammar.rl" { size_t parsed = p - in->pos; while (ibuf_size(in) - parsed < bytes + 2) { @@ -410,7 +410,7 @@ case 12: goto exit; } } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; @@ -445,9 +445,9 @@ case 12: } goto st197; tr62: -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 251 "src/memcached-grammar.rl" +#line 250 "src/memcached-grammar.rl" { size_t parsed = p - in->pos; while (ibuf_size(in) - parsed < bytes + 2) { @@ -470,7 +470,7 @@ case 12: goto exit; } } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; @@ -505,11 +505,11 @@ case 12: } goto st197; tr71: -#line 282 "src/memcached-grammar.rl" +#line 281 "src/memcached-grammar.rl" { noreply = true; } -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 251 "src/memcached-grammar.rl" +#line 250 "src/memcached-grammar.rl" { size_t parsed = p - in->pos; while (ibuf_size(in) - parsed < bytes + 2) { @@ -532,7 +532,7 @@ case 12: goto exit; } } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; @@ -567,11 +567,11 @@ case 12: } goto st197; tr91: -#line 247 "src/memcached-grammar.rl" +#line 246 "src/memcached-grammar.rl" {cas = natoq(fstart, p);} -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 251 "src/memcached-grammar.rl" +#line 250 "src/memcached-grammar.rl" { size_t parsed = p - in->pos; while (ibuf_size(in) - parsed < bytes + 2) { @@ -594,7 +594,7 @@ case 12: goto exit; } } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; @@ -613,9 +613,9 @@ case 12: } goto st197; tr95: -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 251 "src/memcached-grammar.rl" +#line 250 "src/memcached-grammar.rl" { size_t parsed = p - in->pos; while (ibuf_size(in) - parsed < bytes + 2) { @@ -638,7 +638,7 @@ case 12: goto exit; } } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; @@ -657,11 +657,11 @@ case 12: } goto st197; tr105: -#line 282 "src/memcached-grammar.rl" +#line 281 "src/memcached-grammar.rl" { noreply = true; } -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 251 "src/memcached-grammar.rl" +#line 250 "src/memcached-grammar.rl" { size_t parsed = p - in->pos; while (ibuf_size(in) - parsed < bytes + 2) { @@ -684,7 +684,7 @@ case 12: goto exit; } } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; @@ -703,11 +703,11 @@ case 12: } goto st197; tr118: -#line 248 "src/memcached-grammar.rl" +#line 247 "src/memcached-grammar.rl" {incr = natoq(fstart, p);} -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; @@ -731,7 +731,7 @@ case 12: value_len = load_varint32(&field); if (is_numeric(field, value_len)) { - value = natoq(field, field + value_len); + value = natoq((char *) field, (char *) field + value_len); if (incr_sign > 0) { value += incr; @@ -746,20 +746,19 @@ case 12: flags = m->flags; b = tbuf_new(fiber->gc_pool); - tbuf_printf(b, "%"PRIu64, value); + tbuf_printf(b, "%" PRIu64, value); data = b->data; bytes = b->size; stats.cmd_set++; - @try { + try { store(key, exptime, flags, bytes, data); stats.total_items++; obuf_dup(out, b->data, b->size); obuf_dup(out, "\r\n", 2); - } - @catch (ClientError *e) { + } catch (const ClientError& e) { obuf_dup(out, "SERVER_ERROR ", 13); - obuf_dup(out, e->errmsg, strlen(e->errmsg)); + obuf_dup(out, e.errmsg(), strlen(e.errmsg())); obuf_dup(out, "\r\n", 2); } } else { @@ -770,9 +769,9 @@ case 12: } goto st197; tr122: -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; @@ -796,7 +795,7 @@ case 12: value_len = load_varint32(&field); if (is_numeric(field, value_len)) { - value = natoq(field, field + value_len); + value = natoq((char *) field, (char *) field + value_len); if (incr_sign > 0) { value += incr; @@ -811,20 +810,19 @@ case 12: flags = m->flags; b = tbuf_new(fiber->gc_pool); - tbuf_printf(b, "%"PRIu64, value); + tbuf_printf(b, "%" PRIu64, value); data = b->data; bytes = b->size; stats.cmd_set++; - @try { + try { store(key, exptime, flags, bytes, data); stats.total_items++; obuf_dup(out, b->data, b->size); obuf_dup(out, "\r\n", 2); - } - @catch (ClientError *e) { + } catch (const ClientError& e) { obuf_dup(out, "SERVER_ERROR ", 13); - obuf_dup(out, e->errmsg, strlen(e->errmsg)); + obuf_dup(out, e.errmsg(), strlen(e.errmsg())); obuf_dup(out, "\r\n", 2); } } else { @@ -835,11 +833,11 @@ case 12: } goto st197; tr132: -#line 282 "src/memcached-grammar.rl" +#line 281 "src/memcached-grammar.rl" { noreply = true; } -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; @@ -863,7 +861,7 @@ case 12: value_len = load_varint32(&field); if (is_numeric(field, value_len)) { - value = natoq(field, field + value_len); + value = natoq((char *) field, (char *) field + value_len); if (incr_sign > 0) { value += incr; @@ -878,20 +876,19 @@ case 12: flags = m->flags; b = tbuf_new(fiber->gc_pool); - tbuf_printf(b, "%"PRIu64, value); + tbuf_printf(b, "%" PRIu64, value); data = b->data; bytes = b->size; stats.cmd_set++; - @try { + try { store(key, exptime, flags, bytes, data); stats.total_items++; obuf_dup(out, b->data, b->size); obuf_dup(out, "\r\n", 2); - } - @catch (ClientError *e) { + } catch (const ClientError& e) { obuf_dup(out, "SERVER_ERROR ", 13); - obuf_dup(out, e->errmsg, strlen(e->errmsg)); + obuf_dup(out, e.errmsg(), strlen(e.errmsg())); obuf_dup(out, "\r\n", 2); } } else { @@ -902,107 +899,107 @@ case 12: } goto st197; tr141: -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; in->pos = p; } -#line 179 "src/memcached-grammar.rl" +#line 178 "src/memcached-grammar.rl" { key = tbuf_read_field(keys); struct tuple *tuple = find(key); if (tuple == NULL || expired(tuple)) { obuf_dup(out, "NOT_FOUND\r\n", 11); } else { - @try { - delete(key); + try { + remove(key); obuf_dup(out, "DELETED\r\n", 9); } - @catch (ClientError *e) { + catch (const ClientError& e) { obuf_dup(out, "SERVER_ERROR ", 13); - obuf_dup(out, e->errmsg, strlen(e->errmsg)); + obuf_dup(out, e.errmsg(), strlen(e.errmsg())); obuf_dup(out, "\r\n", 2); } } } goto st197; tr146: -#line 238 "src/memcached-grammar.rl" +#line 237 "src/memcached-grammar.rl" { exptime = natoq(fstart, p); if (exptime > 0 && exptime <= 60*60*24*30) exptime = exptime + ev_now(); } -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; in->pos = p; } -#line 179 "src/memcached-grammar.rl" +#line 178 "src/memcached-grammar.rl" { key = tbuf_read_field(keys); struct tuple *tuple = find(key); if (tuple == NULL || expired(tuple)) { obuf_dup(out, "NOT_FOUND\r\n", 11); } else { - @try { - delete(key); + try { + remove(key); obuf_dup(out, "DELETED\r\n", 9); } - @catch (ClientError *e) { + catch (const ClientError& e) { obuf_dup(out, "SERVER_ERROR ", 13); - obuf_dup(out, e->errmsg, strlen(e->errmsg)); + obuf_dup(out, e.errmsg(), strlen(e.errmsg())); obuf_dup(out, "\r\n", 2); } } } goto st197; tr157: -#line 282 "src/memcached-grammar.rl" +#line 281 "src/memcached-grammar.rl" { noreply = true; } -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; in->pos = p; } -#line 179 "src/memcached-grammar.rl" +#line 178 "src/memcached-grammar.rl" { key = tbuf_read_field(keys); struct tuple *tuple = find(key); if (tuple == NULL || expired(tuple)) { obuf_dup(out, "NOT_FOUND\r\n", 11); } else { - @try { - delete(key); + try { + remove(key); obuf_dup(out, "DELETED\r\n", 9); } - @catch (ClientError *e) { + catch (const ClientError& e) { obuf_dup(out, "SERVER_ERROR ", 13); - obuf_dup(out, e->errmsg, strlen(e->errmsg)); + obuf_dup(out, e.errmsg(), strlen(e.errmsg())); obuf_dup(out, "\r\n", 2); } } } goto st197; tr169: -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; in->pos = p; } -#line 208 "src/memcached-grammar.rl" +#line 207 "src/memcached-grammar.rl" { struct fiber *f = fiber_new("flush_all", flush_all); fiber_call(f, flush_delay); @@ -1010,17 +1007,17 @@ case 12: } goto st197; tr174: -#line 249 "src/memcached-grammar.rl" +#line 248 "src/memcached-grammar.rl" {flush_delay = natoq(fstart, p);} -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; in->pos = p; } -#line 208 "src/memcached-grammar.rl" +#line 207 "src/memcached-grammar.rl" { struct fiber *f = fiber_new("flush_all", flush_all); fiber_call(f, flush_delay); @@ -1028,17 +1025,17 @@ case 12: } goto st197; tr185: -#line 282 "src/memcached-grammar.rl" +#line 281 "src/memcached-grammar.rl" { noreply = true; } -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; in->pos = p; } -#line 208 "src/memcached-grammar.rl" +#line 207 "src/memcached-grammar.rl" { struct fiber *f = fiber_new("flush_all", flush_all); fiber_call(f, flush_delay); @@ -1046,46 +1043,46 @@ case 12: } goto st197; tr195: -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; in->pos = p; } -#line 197 "src/memcached-grammar.rl" +#line 196 "src/memcached-grammar.rl" { - @try { + try { memcached_get(out, keys_count, keys, show_cas); - } @catch (ClientError *e) { + } catch (const ClientError& e) { obuf_rollback_to_svp(out, &obuf_svp); obuf_dup(out, "SERVER_ERROR ", 13); - obuf_dup(out, e->errmsg, strlen(e->errmsg)); + obuf_dup(out, e.errmsg(), strlen(e.errmsg())); obuf_dup(out, "\r\n", 2); } } goto st197; tr213: -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; in->pos = p; } -#line 218 "src/memcached-grammar.rl" +#line 217 "src/memcached-grammar.rl" { return -1; } goto st197; tr233: -#line 246 "src/memcached-grammar.rl" +#line 245 "src/memcached-grammar.rl" {bytes = natoq(fstart, p);} -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 251 "src/memcached-grammar.rl" +#line 250 "src/memcached-grammar.rl" { size_t parsed = p - in->pos; while (ibuf_size(in) - parsed < bytes + 2) { @@ -1108,7 +1105,7 @@ case 12: goto exit; } } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; @@ -1125,9 +1122,9 @@ case 12: } goto st197; tr237: -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 251 "src/memcached-grammar.rl" +#line 250 "src/memcached-grammar.rl" { size_t parsed = p - in->pos; while (ibuf_size(in) - parsed < bytes + 2) { @@ -1150,7 +1147,7 @@ case 12: goto exit; } } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; @@ -1167,11 +1164,11 @@ case 12: } goto st197; tr246: -#line 282 "src/memcached-grammar.rl" +#line 281 "src/memcached-grammar.rl" { noreply = true; } -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 251 "src/memcached-grammar.rl" +#line 250 "src/memcached-grammar.rl" { size_t parsed = p - in->pos; while (ibuf_size(in) - parsed < bytes + 2) { @@ -1194,7 +1191,7 @@ case 12: goto exit; } } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; @@ -1211,11 +1208,11 @@ case 12: } goto st197; tr263: -#line 246 "src/memcached-grammar.rl" +#line 245 "src/memcached-grammar.rl" {bytes = natoq(fstart, p);} -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 251 "src/memcached-grammar.rl" +#line 250 "src/memcached-grammar.rl" { size_t parsed = p - in->pos; while (ibuf_size(in) - parsed < bytes + 2) { @@ -1238,7 +1235,7 @@ case 12: goto exit; } } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; @@ -1251,9 +1248,9 @@ case 12: } goto st197; tr267: -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 251 "src/memcached-grammar.rl" +#line 250 "src/memcached-grammar.rl" { size_t parsed = p - in->pos; while (ibuf_size(in) - parsed < bytes + 2) { @@ -1276,7 +1273,7 @@ case 12: goto exit; } } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; @@ -1289,11 +1286,11 @@ case 12: } goto st197; tr276: -#line 282 "src/memcached-grammar.rl" +#line 281 "src/memcached-grammar.rl" { noreply = true; } -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 251 "src/memcached-grammar.rl" +#line 250 "src/memcached-grammar.rl" { size_t parsed = p - in->pos; while (ibuf_size(in) - parsed < bytes + 2) { @@ -1316,7 +1313,7 @@ case 12: goto exit; } } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; @@ -1329,15 +1326,15 @@ case 12: } goto st197; tr281: -#line 280 "src/memcached-grammar.rl" +#line 279 "src/memcached-grammar.rl" { p++; } -#line 274 "src/memcached-grammar.rl" +#line 273 "src/memcached-grammar.rl" { done = true; stats.bytes_read += p - in->pos; in->pos = p; } -#line 214 "src/memcached-grammar.rl" +#line 213 "src/memcached-grammar.rl" { print_stats(out); } @@ -1346,33 +1343,33 @@ case 12: if ( ++p == pe ) goto _test_eof197; case 197: -#line 1350 "src/memcached-grammar.m" +#line 1347 "src/memcached-grammar.cc" goto st0; tr27: -#line 246 "src/memcached-grammar.rl" +#line 245 "src/memcached-grammar.rl" {bytes = natoq(fstart, p);} goto st13; tr40: -#line 282 "src/memcached-grammar.rl" +#line 281 "src/memcached-grammar.rl" { noreply = true; } goto st13; st13: if ( ++p == pe ) goto _test_eof13; case 13: -#line 1364 "src/memcached-grammar.m" +#line 1361 "src/memcached-grammar.cc" if ( (*p) == 10 ) goto tr30; goto st0; tr28: -#line 246 "src/memcached-grammar.rl" +#line 245 "src/memcached-grammar.rl" {bytes = natoq(fstart, p);} goto st14; st14: if ( ++p == pe ) goto _test_eof14; case 14: -#line 1376 "src/memcached-grammar.m" +#line 1373 "src/memcached-grammar.cc" switch( (*p) ) { case 32: goto st14; case 78: goto st15; @@ -1486,18 +1483,18 @@ case 26: goto tr45; goto st0; tr45: -#line 288 "src/memcached-grammar.rl" +#line 287 "src/memcached-grammar.rl" {append = true; } goto st27; tr209: -#line 289 "src/memcached-grammar.rl" +#line 288 "src/memcached-grammar.rl" {append = false;} goto st27; st27: if ( ++p == pe ) goto _test_eof27; case 27: -#line 1501 "src/memcached-grammar.m" +#line 1498 "src/memcached-grammar.cc" switch( (*p) ) { case 13: goto st0; case 32: goto st27; @@ -1506,7 +1503,7 @@ case 27: goto st0; goto tr46; tr46: -#line 223 "src/memcached-grammar.rl" +#line 222 "src/memcached-grammar.rl" { fstart = p; for (; p < pe && *p != ' ' && *p != '\r' && *p != '\n'; p++); @@ -1522,7 +1519,7 @@ case 27: if ( ++p == pe ) goto _test_eof28; case 28: -#line 1526 "src/memcached-grammar.m" +#line 1523 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto st29; goto st0; @@ -1536,49 +1533,49 @@ case 29: goto tr49; goto st0; tr49: -#line 222 "src/memcached-grammar.rl" +#line 221 "src/memcached-grammar.rl" { fstart = p; } goto st30; st30: if ( ++p == pe ) goto _test_eof30; case 30: -#line 1547 "src/memcached-grammar.m" +#line 1544 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto tr50; if ( 48 <= (*p) && (*p) <= 57 ) goto st30; goto st0; tr50: -#line 245 "src/memcached-grammar.rl" +#line 244 "src/memcached-grammar.rl" {flags = natoq(fstart, p);} goto st31; st31: if ( ++p == pe ) goto _test_eof31; case 31: -#line 1561 "src/memcached-grammar.m" +#line 1558 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto st31; if ( 48 <= (*p) && (*p) <= 57 ) goto tr53; goto st0; tr53: -#line 222 "src/memcached-grammar.rl" +#line 221 "src/memcached-grammar.rl" { fstart = p; } goto st32; st32: if ( ++p == pe ) goto _test_eof32; case 32: -#line 1575 "src/memcached-grammar.m" +#line 1572 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto tr54; if ( 48 <= (*p) && (*p) <= 57 ) goto st32; goto st0; tr54: -#line 238 "src/memcached-grammar.rl" +#line 237 "src/memcached-grammar.rl" { exptime = natoq(fstart, p); if (exptime > 0 && exptime <= 60*60*24*30) @@ -1589,21 +1586,21 @@ case 32: if ( ++p == pe ) goto _test_eof33; case 33: -#line 1593 "src/memcached-grammar.m" +#line 1590 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto st33; if ( 48 <= (*p) && (*p) <= 57 ) goto tr57; goto st0; tr57: -#line 222 "src/memcached-grammar.rl" +#line 221 "src/memcached-grammar.rl" { fstart = p; } goto st34; st34: if ( ++p == pe ) goto _test_eof34; case 34: -#line 1607 "src/memcached-grammar.m" +#line 1604 "src/memcached-grammar.cc" switch( (*p) ) { case 10: goto tr58; case 13: goto tr59; @@ -1613,30 +1610,30 @@ case 34: goto st34; goto st0; tr59: -#line 246 "src/memcached-grammar.rl" +#line 245 "src/memcached-grammar.rl" {bytes = natoq(fstart, p);} goto st35; tr72: -#line 282 "src/memcached-grammar.rl" +#line 281 "src/memcached-grammar.rl" { noreply = true; } goto st35; st35: if ( ++p == pe ) goto _test_eof35; case 35: -#line 1628 "src/memcached-grammar.m" +#line 1625 "src/memcached-grammar.cc" if ( (*p) == 10 ) goto tr62; goto st0; tr60: -#line 246 "src/memcached-grammar.rl" +#line 245 "src/memcached-grammar.rl" {bytes = natoq(fstart, p);} goto st36; st36: if ( ++p == pe ) goto _test_eof36; case 36: -#line 1640 "src/memcached-grammar.m" +#line 1637 "src/memcached-grammar.cc" switch( (*p) ) { case 32: goto st36; case 78: goto st37; @@ -1743,7 +1740,7 @@ case 47: goto st0; goto tr76; tr76: -#line 223 "src/memcached-grammar.rl" +#line 222 "src/memcached-grammar.rl" { fstart = p; for (; p < pe && *p != ' ' && *p != '\r' && *p != '\n'; p++); @@ -1759,7 +1756,7 @@ case 47: if ( ++p == pe ) goto _test_eof48; case 48: -#line 1763 "src/memcached-grammar.m" +#line 1760 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto st49; goto st0; @@ -1773,49 +1770,49 @@ case 49: goto tr78; goto st0; tr78: -#line 222 "src/memcached-grammar.rl" +#line 221 "src/memcached-grammar.rl" { fstart = p; } goto st50; st50: if ( ++p == pe ) goto _test_eof50; case 50: -#line 1784 "src/memcached-grammar.m" +#line 1781 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto tr79; if ( 48 <= (*p) && (*p) <= 57 ) goto st50; goto st0; tr79: -#line 245 "src/memcached-grammar.rl" +#line 244 "src/memcached-grammar.rl" {flags = natoq(fstart, p);} goto st51; st51: if ( ++p == pe ) goto _test_eof51; case 51: -#line 1798 "src/memcached-grammar.m" +#line 1795 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto st51; if ( 48 <= (*p) && (*p) <= 57 ) goto tr82; goto st0; tr82: -#line 222 "src/memcached-grammar.rl" +#line 221 "src/memcached-grammar.rl" { fstart = p; } goto st52; st52: if ( ++p == pe ) goto _test_eof52; case 52: -#line 1812 "src/memcached-grammar.m" +#line 1809 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto tr83; if ( 48 <= (*p) && (*p) <= 57 ) goto st52; goto st0; tr83: -#line 238 "src/memcached-grammar.rl" +#line 237 "src/memcached-grammar.rl" { exptime = natoq(fstart, p); if (exptime > 0 && exptime <= 60*60*24*30) @@ -1826,49 +1823,49 @@ case 52: if ( ++p == pe ) goto _test_eof53; case 53: -#line 1830 "src/memcached-grammar.m" +#line 1827 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto st53; if ( 48 <= (*p) && (*p) <= 57 ) goto tr86; goto st0; tr86: -#line 222 "src/memcached-grammar.rl" +#line 221 "src/memcached-grammar.rl" { fstart = p; } goto st54; st54: if ( ++p == pe ) goto _test_eof54; case 54: -#line 1844 "src/memcached-grammar.m" +#line 1841 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto tr87; if ( 48 <= (*p) && (*p) <= 57 ) goto st54; goto st0; tr87: -#line 246 "src/memcached-grammar.rl" +#line 245 "src/memcached-grammar.rl" {bytes = natoq(fstart, p);} goto st55; st55: if ( ++p == pe ) goto _test_eof55; case 55: -#line 1858 "src/memcached-grammar.m" +#line 1855 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto st55; if ( 48 <= (*p) && (*p) <= 57 ) goto tr90; goto st0; tr90: -#line 222 "src/memcached-grammar.rl" +#line 221 "src/memcached-grammar.rl" { fstart = p; } goto st56; st56: if ( ++p == pe ) goto _test_eof56; case 56: -#line 1872 "src/memcached-grammar.m" +#line 1869 "src/memcached-grammar.cc" switch( (*p) ) { case 10: goto tr91; case 13: goto tr92; @@ -1878,30 +1875,30 @@ case 56: goto st56; goto st0; tr106: -#line 282 "src/memcached-grammar.rl" +#line 281 "src/memcached-grammar.rl" { noreply = true; } goto st57; tr92: -#line 247 "src/memcached-grammar.rl" +#line 246 "src/memcached-grammar.rl" {cas = natoq(fstart, p);} goto st57; st57: if ( ++p == pe ) goto _test_eof57; case 57: -#line 1893 "src/memcached-grammar.m" +#line 1890 "src/memcached-grammar.cc" if ( (*p) == 10 ) goto tr95; goto st0; tr93: -#line 247 "src/memcached-grammar.rl" +#line 246 "src/memcached-grammar.rl" {cas = natoq(fstart, p);} goto st58; st58: if ( ++p == pe ) goto _test_eof58; case 58: -#line 1905 "src/memcached-grammar.m" +#line 1902 "src/memcached-grammar.cc" switch( (*p) ) { case 10: goto tr95; case 13: goto st57; @@ -1975,14 +1972,14 @@ case 65: } goto st0; tr107: -#line 282 "src/memcached-grammar.rl" +#line 281 "src/memcached-grammar.rl" { noreply = true; } goto st66; st66: if ( ++p == pe ) goto _test_eof66; case 66: -#line 1986 "src/memcached-grammar.m" +#line 1983 "src/memcached-grammar.cc" switch( (*p) ) { case 10: goto tr95; case 13: goto st57; @@ -2026,18 +2023,18 @@ case 70: goto tr113; goto st0; tr113: -#line 297 "src/memcached-grammar.rl" +#line 296 "src/memcached-grammar.rl" {incr_sign = -1;} goto st71; tr202: -#line 296 "src/memcached-grammar.rl" +#line 295 "src/memcached-grammar.rl" {incr_sign = 1; } goto st71; st71: if ( ++p == pe ) goto _test_eof71; case 71: -#line 2041 "src/memcached-grammar.m" +#line 2038 "src/memcached-grammar.cc" switch( (*p) ) { case 13: goto st0; case 32: goto st71; @@ -2046,7 +2043,7 @@ case 71: goto st0; goto tr114; tr114: -#line 223 "src/memcached-grammar.rl" +#line 222 "src/memcached-grammar.rl" { fstart = p; for (; p < pe && *p != ' ' && *p != '\r' && *p != '\n'; p++); @@ -2062,7 +2059,7 @@ case 71: if ( ++p == pe ) goto _test_eof72; case 72: -#line 2066 "src/memcached-grammar.m" +#line 2063 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto st73; goto st0; @@ -2076,14 +2073,14 @@ case 73: goto tr117; goto st0; tr117: -#line 222 "src/memcached-grammar.rl" +#line 221 "src/memcached-grammar.rl" { fstart = p; } goto st74; st74: if ( ++p == pe ) goto _test_eof74; case 74: -#line 2087 "src/memcached-grammar.m" +#line 2084 "src/memcached-grammar.cc" switch( (*p) ) { case 10: goto tr118; case 13: goto tr119; @@ -2093,30 +2090,30 @@ case 74: goto st74; goto st0; tr133: -#line 282 "src/memcached-grammar.rl" +#line 281 "src/memcached-grammar.rl" { noreply = true; } goto st75; tr119: -#line 248 "src/memcached-grammar.rl" +#line 247 "src/memcached-grammar.rl" {incr = natoq(fstart, p);} goto st75; st75: if ( ++p == pe ) goto _test_eof75; case 75: -#line 2108 "src/memcached-grammar.m" +#line 2105 "src/memcached-grammar.cc" if ( (*p) == 10 ) goto tr122; goto st0; tr120: -#line 248 "src/memcached-grammar.rl" +#line 247 "src/memcached-grammar.rl" {incr = natoq(fstart, p);} goto st76; st76: if ( ++p == pe ) goto _test_eof76; case 76: -#line 2120 "src/memcached-grammar.m" +#line 2117 "src/memcached-grammar.cc" switch( (*p) ) { case 10: goto tr122; case 13: goto st75; @@ -2190,14 +2187,14 @@ case 83: } goto st0; tr134: -#line 282 "src/memcached-grammar.rl" +#line 281 "src/memcached-grammar.rl" { noreply = true; } goto st84; st84: if ( ++p == pe ) goto _test_eof84; case 84: -#line 2201 "src/memcached-grammar.m" +#line 2198 "src/memcached-grammar.cc" switch( (*p) ) { case 10: goto tr122; case 13: goto st75; @@ -2250,7 +2247,7 @@ case 89: goto st0; goto tr140; tr140: -#line 223 "src/memcached-grammar.rl" +#line 222 "src/memcached-grammar.rl" { fstart = p; for (; p < pe && *p != ' ' && *p != '\r' && *p != '\n'; p++); @@ -2266,7 +2263,7 @@ case 89: if ( ++p == pe ) goto _test_eof90; case 90: -#line 2270 "src/memcached-grammar.m" +#line 2267 "src/memcached-grammar.cc" switch( (*p) ) { case 10: goto tr141; case 13: goto st91; @@ -2274,7 +2271,7 @@ case 90: } goto st0; tr147: -#line 238 "src/memcached-grammar.rl" +#line 237 "src/memcached-grammar.rl" { exptime = natoq(fstart, p); if (exptime > 0 && exptime <= 60*60*24*30) @@ -2282,14 +2279,14 @@ case 90: } goto st91; tr158: -#line 282 "src/memcached-grammar.rl" +#line 281 "src/memcached-grammar.rl" { noreply = true; } goto st91; st91: if ( ++p == pe ) goto _test_eof91; case 91: -#line 2293 "src/memcached-grammar.m" +#line 2290 "src/memcached-grammar.cc" if ( (*p) == 10 ) goto tr141; goto st0; @@ -2308,14 +2305,14 @@ case 92: goto tr144; goto st0; tr144: -#line 222 "src/memcached-grammar.rl" +#line 221 "src/memcached-grammar.rl" { fstart = p; } goto st93; st93: if ( ++p == pe ) goto _test_eof93; case 93: -#line 2319 "src/memcached-grammar.m" +#line 2316 "src/memcached-grammar.cc" switch( (*p) ) { case 10: goto tr146; case 13: goto tr147; @@ -2325,7 +2322,7 @@ case 93: goto st93; goto st0; tr148: -#line 238 "src/memcached-grammar.rl" +#line 237 "src/memcached-grammar.rl" { exptime = natoq(fstart, p); if (exptime > 0 && exptime <= 60*60*24*30) @@ -2336,7 +2333,7 @@ case 93: if ( ++p == pe ) goto _test_eof94; case 94: -#line 2340 "src/memcached-grammar.m" +#line 2337 "src/memcached-grammar.cc" switch( (*p) ) { case 10: goto tr141; case 13: goto st91; @@ -2410,14 +2407,14 @@ case 101: } goto st0; tr159: -#line 282 "src/memcached-grammar.rl" +#line 281 "src/memcached-grammar.rl" { noreply = true; } goto st102; st102: if ( ++p == pe ) goto _test_eof102; case 102: -#line 2421 "src/memcached-grammar.m" +#line 2418 "src/memcached-grammar.cc" switch( (*p) ) { case 10: goto tr141; case 13: goto st91; @@ -2505,18 +2502,18 @@ case 111: } goto st0; tr186: -#line 282 "src/memcached-grammar.rl" +#line 281 "src/memcached-grammar.rl" { noreply = true; } goto st112; tr175: -#line 249 "src/memcached-grammar.rl" +#line 248 "src/memcached-grammar.rl" {flush_delay = natoq(fstart, p);} goto st112; st112: if ( ++p == pe ) goto _test_eof112; case 112: -#line 2520 "src/memcached-grammar.m" +#line 2517 "src/memcached-grammar.cc" if ( (*p) == 10 ) goto tr169; goto st0; @@ -2535,14 +2532,14 @@ case 113: goto tr172; goto st0; tr172: -#line 222 "src/memcached-grammar.rl" +#line 221 "src/memcached-grammar.rl" { fstart = p; } goto st114; st114: if ( ++p == pe ) goto _test_eof114; case 114: -#line 2546 "src/memcached-grammar.m" +#line 2543 "src/memcached-grammar.cc" switch( (*p) ) { case 10: goto tr174; case 13: goto tr175; @@ -2552,14 +2549,14 @@ case 114: goto st114; goto st0; tr176: -#line 249 "src/memcached-grammar.rl" +#line 248 "src/memcached-grammar.rl" {flush_delay = natoq(fstart, p);} goto st115; st115: if ( ++p == pe ) goto _test_eof115; case 115: -#line 2563 "src/memcached-grammar.m" +#line 2560 "src/memcached-grammar.cc" switch( (*p) ) { case 10: goto tr169; case 13: goto st112; @@ -2633,14 +2630,14 @@ case 122: } goto st0; tr187: -#line 282 "src/memcached-grammar.rl" +#line 281 "src/memcached-grammar.rl" { noreply = true; } goto st123; st123: if ( ++p == pe ) goto _test_eof123; case 123: -#line 2644 "src/memcached-grammar.m" +#line 2641 "src/memcached-grammar.cc" switch( (*p) ) { case 10: goto tr169; case 13: goto st112; @@ -2676,18 +2673,18 @@ case 126: } goto st0; tr191: -#line 293 "src/memcached-grammar.rl" +#line 292 "src/memcached-grammar.rl" {show_cas = false;} goto st127; tr198: -#line 294 "src/memcached-grammar.rl" +#line 293 "src/memcached-grammar.rl" {show_cas = true;} goto st127; st127: if ( ++p == pe ) goto _test_eof127; case 127: -#line 2691 "src/memcached-grammar.m" +#line 2688 "src/memcached-grammar.cc" switch( (*p) ) { case 13: goto st0; case 32: goto st127; @@ -2696,7 +2693,7 @@ case 127: goto st0; goto tr193; tr193: -#line 223 "src/memcached-grammar.rl" +#line 222 "src/memcached-grammar.rl" { fstart = p; for (; p < pe && *p != ' ' && *p != '\r' && *p != '\n'; p++); @@ -2712,7 +2709,7 @@ case 127: if ( ++p == pe ) goto _test_eof128; case 128: -#line 2716 "src/memcached-grammar.m" +#line 2713 "src/memcached-grammar.cc" switch( (*p) ) { case 10: goto tr195; case 13: goto st129; @@ -2955,7 +2952,7 @@ case 155: goto st0; goto tr222; tr222: -#line 223 "src/memcached-grammar.rl" +#line 222 "src/memcached-grammar.rl" { fstart = p; for (; p < pe && *p != ' ' && *p != '\r' && *p != '\n'; p++); @@ -2971,7 +2968,7 @@ case 155: if ( ++p == pe ) goto _test_eof156; case 156: -#line 2975 "src/memcached-grammar.m" +#line 2972 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto st157; goto st0; @@ -2985,49 +2982,49 @@ case 157: goto tr224; goto st0; tr224: -#line 222 "src/memcached-grammar.rl" +#line 221 "src/memcached-grammar.rl" { fstart = p; } goto st158; st158: if ( ++p == pe ) goto _test_eof158; case 158: -#line 2996 "src/memcached-grammar.m" +#line 2993 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto tr225; if ( 48 <= (*p) && (*p) <= 57 ) goto st158; goto st0; tr225: -#line 245 "src/memcached-grammar.rl" +#line 244 "src/memcached-grammar.rl" {flags = natoq(fstart, p);} goto st159; st159: if ( ++p == pe ) goto _test_eof159; case 159: -#line 3010 "src/memcached-grammar.m" +#line 3007 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto st159; if ( 48 <= (*p) && (*p) <= 57 ) goto tr228; goto st0; tr228: -#line 222 "src/memcached-grammar.rl" +#line 221 "src/memcached-grammar.rl" { fstart = p; } goto st160; st160: if ( ++p == pe ) goto _test_eof160; case 160: -#line 3024 "src/memcached-grammar.m" +#line 3021 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto tr229; if ( 48 <= (*p) && (*p) <= 57 ) goto st160; goto st0; tr229: -#line 238 "src/memcached-grammar.rl" +#line 237 "src/memcached-grammar.rl" { exptime = natoq(fstart, p); if (exptime > 0 && exptime <= 60*60*24*30) @@ -3038,21 +3035,21 @@ case 160: if ( ++p == pe ) goto _test_eof161; case 161: -#line 3042 "src/memcached-grammar.m" +#line 3039 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto st161; if ( 48 <= (*p) && (*p) <= 57 ) goto tr232; goto st0; tr232: -#line 222 "src/memcached-grammar.rl" +#line 221 "src/memcached-grammar.rl" { fstart = p; } goto st162; st162: if ( ++p == pe ) goto _test_eof162; case 162: -#line 3056 "src/memcached-grammar.m" +#line 3053 "src/memcached-grammar.cc" switch( (*p) ) { case 10: goto tr233; case 13: goto tr234; @@ -3062,30 +3059,30 @@ case 162: goto st162; goto st0; tr234: -#line 246 "src/memcached-grammar.rl" +#line 245 "src/memcached-grammar.rl" {bytes = natoq(fstart, p);} goto st163; tr247: -#line 282 "src/memcached-grammar.rl" +#line 281 "src/memcached-grammar.rl" { noreply = true; } goto st163; st163: if ( ++p == pe ) goto _test_eof163; case 163: -#line 3077 "src/memcached-grammar.m" +#line 3074 "src/memcached-grammar.cc" if ( (*p) == 10 ) goto tr237; goto st0; tr235: -#line 246 "src/memcached-grammar.rl" +#line 245 "src/memcached-grammar.rl" {bytes = natoq(fstart, p);} goto st164; st164: if ( ++p == pe ) goto _test_eof164; case 164: -#line 3089 "src/memcached-grammar.m" +#line 3086 "src/memcached-grammar.cc" switch( (*p) ) { case 32: goto st164; case 78: goto st165; @@ -3194,7 +3191,7 @@ case 175: goto st0; goto tr252; tr252: -#line 223 "src/memcached-grammar.rl" +#line 222 "src/memcached-grammar.rl" { fstart = p; for (; p < pe && *p != ' ' && *p != '\r' && *p != '\n'; p++); @@ -3210,7 +3207,7 @@ case 175: if ( ++p == pe ) goto _test_eof176; case 176: -#line 3214 "src/memcached-grammar.m" +#line 3211 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto st177; goto st0; @@ -3224,49 +3221,49 @@ case 177: goto tr254; goto st0; tr254: -#line 222 "src/memcached-grammar.rl" +#line 221 "src/memcached-grammar.rl" { fstart = p; } goto st178; st178: if ( ++p == pe ) goto _test_eof178; case 178: -#line 3235 "src/memcached-grammar.m" +#line 3232 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto tr255; if ( 48 <= (*p) && (*p) <= 57 ) goto st178; goto st0; tr255: -#line 245 "src/memcached-grammar.rl" +#line 244 "src/memcached-grammar.rl" {flags = natoq(fstart, p);} goto st179; st179: if ( ++p == pe ) goto _test_eof179; case 179: -#line 3249 "src/memcached-grammar.m" +#line 3246 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto st179; if ( 48 <= (*p) && (*p) <= 57 ) goto tr258; goto st0; tr258: -#line 222 "src/memcached-grammar.rl" +#line 221 "src/memcached-grammar.rl" { fstart = p; } goto st180; st180: if ( ++p == pe ) goto _test_eof180; case 180: -#line 3263 "src/memcached-grammar.m" +#line 3260 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto tr259; if ( 48 <= (*p) && (*p) <= 57 ) goto st180; goto st0; tr259: -#line 238 "src/memcached-grammar.rl" +#line 237 "src/memcached-grammar.rl" { exptime = natoq(fstart, p); if (exptime > 0 && exptime <= 60*60*24*30) @@ -3277,21 +3274,21 @@ case 180: if ( ++p == pe ) goto _test_eof181; case 181: -#line 3281 "src/memcached-grammar.m" +#line 3278 "src/memcached-grammar.cc" if ( (*p) == 32 ) goto st181; if ( 48 <= (*p) && (*p) <= 57 ) goto tr262; goto st0; tr262: -#line 222 "src/memcached-grammar.rl" +#line 221 "src/memcached-grammar.rl" { fstart = p; } goto st182; st182: if ( ++p == pe ) goto _test_eof182; case 182: -#line 3295 "src/memcached-grammar.m" +#line 3292 "src/memcached-grammar.cc" switch( (*p) ) { case 10: goto tr263; case 13: goto tr264; @@ -3301,30 +3298,30 @@ case 182: goto st182; goto st0; tr264: -#line 246 "src/memcached-grammar.rl" +#line 245 "src/memcached-grammar.rl" {bytes = natoq(fstart, p);} goto st183; tr277: -#line 282 "src/memcached-grammar.rl" +#line 281 "src/memcached-grammar.rl" { noreply = true; } goto st183; st183: if ( ++p == pe ) goto _test_eof183; case 183: -#line 3316 "src/memcached-grammar.m" +#line 3313 "src/memcached-grammar.cc" if ( (*p) == 10 ) goto tr267; goto st0; tr265: -#line 246 "src/memcached-grammar.rl" +#line 245 "src/memcached-grammar.rl" {bytes = natoq(fstart, p);} goto st184; st184: if ( ++p == pe ) goto _test_eof184; case 184: -#line 3328 "src/memcached-grammar.m" +#line 3325 "src/memcached-grammar.cc" switch( (*p) ) { case 32: goto st184; case 78: goto st185; @@ -3639,7 +3636,7 @@ case 196: _out: {} } -#line 307 "src/memcached-grammar.rl" +#line 306 "src/memcached-grammar.rl" if (!done) { @@ -3652,7 +3649,7 @@ case 196: return -1; } char *r; - if ((r = memmem(p, pe - p, "\r\n", 2)) != NULL) { + if ((r = (char *) memmem(p, pe - p, "\r\n", 2)) != NULL) { in->pos = r + 2; obuf_dup(out, "CLIENT_ERROR bad command line format\r\n", 38); return 1; diff --git a/src/memcached-grammar.rl b/src/memcached-grammar.rl index c92f04905dcd9a8985c8e8e87e6b8c1e36ceec37..d015f8a85ff5ad2eb018755ba2644c5f5ef99181 100644 --- a/src/memcached-grammar.rl +++ b/src/memcached-grammar.rl @@ -138,7 +138,8 @@ memcached_dispatch(struct ev_io *coio, struct iobuf *iobuf) value_len = load_varint32(&field); if (is_numeric(field, value_len)) { - value = natoq(field, field + value_len); + value = natoq((const char *) field, + (const char *) field + value_len); if (incr_sign > 0) { value += incr; @@ -153,20 +154,19 @@ memcached_dispatch(struct ev_io *coio, struct iobuf *iobuf) flags = m->flags; b = tbuf_new(fiber->gc_pool); - tbuf_printf(b, "%"PRIu64, value); + tbuf_printf(b, "%" PRIu64, value); data = b->data; bytes = b->size; stats.cmd_set++; - @try { + try { store(key, exptime, flags, bytes, data); stats.total_items++; obuf_dup(out, b->data, b->size); obuf_dup(out, "\r\n", 2); - } - @catch (ClientError *e) { + } catch (const ClientError& e) { obuf_dup(out, "SERVER_ERROR ", 13); - obuf_dup(out, e->errmsg, strlen(e->errmsg)); + obuf_dup(out, e.errmsg(), strlen(e.errmsg())); obuf_dup(out, "\r\n", 2); } } else { @@ -182,25 +182,25 @@ memcached_dispatch(struct ev_io *coio, struct iobuf *iobuf) if (tuple == NULL || expired(tuple)) { obuf_dup(out, "NOT_FOUND\r\n", 11); } else { - @try { - delete(key); + try { + remove(key); obuf_dup(out, "DELETED\r\n", 9); } - @catch (ClientError *e) { + catch (const ClientError& e) { obuf_dup(out, "SERVER_ERROR ", 13); - obuf_dup(out, e->errmsg, strlen(e->errmsg)); + obuf_dup(out, e.errmsg(), strlen(e.errmsg())); obuf_dup(out, "\r\n", 2); } } } action get { - @try { + try { memcached_get(out, keys_count, keys, show_cas); - } @catch (ClientError *e) { + } catch (const ClientError& e) { obuf_rollback_to_svp(out, &obuf_svp); obuf_dup(out, "SERVER_ERROR ", 13); - obuf_dup(out, e->errmsg, strlen(e->errmsg)); + obuf_dup(out, e.errmsg(), strlen(e.errmsg())); obuf_dup(out, "\r\n", 2); } } @@ -316,7 +316,7 @@ memcached_dispatch(struct ev_io *coio, struct iobuf *iobuf) return -1; } char *r; - if ((r = memmem(p, pe - p, "\r\n", 2)) != NULL) { + if ((r = (char *) memmem(p, pe - p, "\r\n", 2)) != NULL) { in->pos = r + 2; obuf_dup(out, "CLIENT_ERROR bad command line format\r\n", 38); return 1; diff --git a/src/memcached.m b/src/memcached.cc similarity index 75% rename from src/memcached.m rename to src/memcached.cc index fac53e681222482641b7e024c7fa1adf9f79ce7e..fb501909f005300df8f0fe5d265567c34d9b52d9 100644 --- a/src/memcached.m +++ b/src/memcached.cc @@ -37,13 +37,16 @@ #include "box/port.h" #include "box/tuple.h" #include "fiber.h" -#include "cfg/warning.h" -#include TARANTOOL_CONFIG +extern "C" { +#include <cfg/warning.h> +#include <cfg/tarantool_box_cfg.h> +} /* extern "C" */ #include "say.h" #include "stat.h" #include "salloc.h" #include "pickle.h" #include "coio_buf.h" +#include "scoped_guard.h" #define STAT(_) \ _(MEMC_GET, 1) \ @@ -85,14 +88,14 @@ tbuf_append_field(struct tbuf *b, const void *f) { const void *begin = f; u32 size = load_varint32(&f); - tbuf_append(b, begin, f + size - begin); + tbuf_append(b, begin, (const char *) f - (const char *) begin + size); } void tbuf_store_field(struct tbuf *b, const void *field, u32 len) { char buf[sizeof(u32)+1]; - char *bufend = pack_varint32(buf, len); + char *bufend = (char *) pack_varint32(buf, len); tbuf_append(b, buf, bufend - buf); tbuf_append(b, field, len); } @@ -107,11 +110,11 @@ tbuf_read_field(struct tbuf *buf) const void *field = buf->data; u32 field_len = pick_varint32((const void **) &buf->data, buf->data + buf->size); - if (buf->data + field_len > field + buf->size) - tnt_raise(IllegalParams, :"packet too short (expected a field)"); + if ((char *) buf->data + field_len > (char *) field + buf->size) + tnt_raise(IllegalParams, "packet too short (expected a field)"); buf->data += field_len; - buf->size -= buf->data - field; - buf->capacity -= buf->data - field; + buf->size -= (const char *) buf->data - (const char *) field; + buf->capacity -= (const char *) buf->data - (const char *) field; return field; } @@ -137,13 +140,13 @@ store(const void *key, u32 exptime, u32 flags, u32 bytes, const char *data) tbuf_store_field(req, &m, sizeof(m)); char b[43]; - sprintf(b, " %"PRIu32" %"PRIu32"\r\n", flags, bytes); + sprintf(b, " %" PRIu32 " %" PRIu32 "\r\n", flags, bytes); tbuf_store_field(req, b, strlen(b)); tbuf_store_field(req, data, bytes); int key_len = load_varint32(&key); - say_debug("memcached/store key:(%i)'%.*s' exptime:%"PRIu32" flags:%"PRIu32" cas:%"PRIu64, + say_debug("memcached/store key:(%i)'%.*s' exptime:%" PRIu32 " flags:%" PRIu32 " cas:%" PRIu64, key_len, key_len, (char*) key, exptime, flags, cas); /* * Use a box dispatch wrapper which handles correctly @@ -153,7 +156,7 @@ store(const void *key, u32 exptime, u32 flags, u32 bytes, const char *data) } static void -delete(const void *key) +remove(const void *key) { u32 key_len = 1; u32 box_flags = 0; @@ -170,14 +173,14 @@ delete(const void *key) static struct tuple * find(const void *key) { - return [memcached_index findByKey :key :1]; + return memcached_index->findByKey(key, 1); } static struct meta * meta(struct tuple *tuple) { void *field = tuple_field(tuple, 1); - return field + 1; + return (struct meta *) ((char *) field + 1); } static bool @@ -217,7 +220,8 @@ struct salloc_stat_memcached_cb_ctx { static int salloc_stat_memcached_cb(const struct slab_cache_stats *cstat, void *cb_ctx) { - struct salloc_stat_memcached_cb_ctx *ctx = cb_ctx; + struct salloc_stat_memcached_cb_ctx *ctx = + (struct salloc_stat_memcached_cb_ctx *) cb_ctx; ctx->bytes_used += cstat->bytes_used; ctx->items += cstat->items; return 0; @@ -232,25 +236,25 @@ print_stats(struct obuf *out) memstats.bytes_used = memstats.items = 0; salloc_stat(salloc_stat_memcached_cb, NULL, &memstats); - tbuf_printf(buf, "STAT pid %"PRIu32"\r\n", (u32)getpid()); - tbuf_printf(buf, "STAT uptime %"PRIu32"\r\n", (u32)tarantool_uptime()); - tbuf_printf(buf, "STAT time %"PRIu32"\r\n", (u32)ev_now()); + tbuf_printf(buf, "STAT pid %" PRIu32 "\r\n", (u32)getpid()); + tbuf_printf(buf, "STAT uptime %" PRIu32 "\r\n", (u32)tarantool_uptime()); + tbuf_printf(buf, "STAT time %" PRIu32 "\r\n", (u32)ev_now()); tbuf_printf(buf, "STAT version 1.2.5 (tarantool/box)\r\n"); - tbuf_printf(buf, "STAT pointer_size %"PRI_SZ"\r\n", sizeof(void *)*8); - tbuf_printf(buf, "STAT curr_items %"PRIu64"\r\n", memstats.items); - tbuf_printf(buf, "STAT total_items %"PRIu64"\r\n", stats.total_items); - tbuf_printf(buf, "STAT bytes %"PRIu64"\r\n", memstats.bytes_used); - tbuf_printf(buf, "STAT curr_connections %"PRIu32"\r\n", stats.curr_connections); - tbuf_printf(buf, "STAT total_connections %"PRIu32"\r\n", stats.total_connections); - tbuf_printf(buf, "STAT connection_structures %"PRIu32"\r\n", stats.curr_connections); /* lie a bit */ - tbuf_printf(buf, "STAT cmd_get %"PRIu64"\r\n", stats.cmd_get); - tbuf_printf(buf, "STAT cmd_set %"PRIu64"\r\n", stats.cmd_set); - tbuf_printf(buf, "STAT get_hits %"PRIu64"\r\n", stats.get_hits); - tbuf_printf(buf, "STAT get_misses %"PRIu64"\r\n", stats.get_misses); - tbuf_printf(buf, "STAT evictions %"PRIu64"\r\n", stats.evictions); - tbuf_printf(buf, "STAT bytes_read %"PRIu64"\r\n", stats.bytes_read); - tbuf_printf(buf, "STAT bytes_written %"PRIu64"\r\n", stats.bytes_written); - tbuf_printf(buf, "STAT limit_maxbytes %"PRIu64"\r\n", (u64)(cfg.slab_alloc_arena * (1 << 30))); + tbuf_printf(buf, "STAT pointer_size %" PRI_SZ "\r\n", sizeof(void *)*8); + tbuf_printf(buf, "STAT curr_items %" PRIu64 "\r\n", memstats.items); + tbuf_printf(buf, "STAT total_items %" PRIu64 "\r\n", stats.total_items); + tbuf_printf(buf, "STAT bytes %" PRIu64 "\r\n", memstats.bytes_used); + tbuf_printf(buf, "STAT curr_connections %" PRIu32 "\r\n", stats.curr_connections); + tbuf_printf(buf, "STAT total_connections %" PRIu32 "\r\n", stats.total_connections); + tbuf_printf(buf, "STAT connection_structures %" PRIu32 "\r\n", stats.curr_connections); /* lie a bit */ + tbuf_printf(buf, "STAT cmd_get %" PRIu64 "\r\n", stats.cmd_get); + tbuf_printf(buf, "STAT cmd_set %" PRIu64 "\r\n", stats.cmd_set); + tbuf_printf(buf, "STAT get_hits %" PRIu64 "\r\n", stats.get_hits); + tbuf_printf(buf, "STAT get_misses %" PRIu64 "\r\n", stats.get_misses); + tbuf_printf(buf, "STAT evictions %" PRIu64 "\r\n", stats.evictions); + tbuf_printf(buf, "STAT bytes_read %" PRIu64 "\r\n", stats.bytes_read); + tbuf_printf(buf, "STAT bytes_written %" PRIu64 "\r\n", stats.bytes_written); + tbuf_printf(buf, "STAT limit_maxbytes %" PRIu64 "\r\n", (u64)(cfg.slab_alloc_arena * (1 << 30))); tbuf_printf(buf, "STAT threads 1\r\n"); tbuf_printf(buf, "END\r\n"); obuf_dup(out, buf->data, buf->size); @@ -261,7 +265,7 @@ void memcached_get(struct obuf *out, size_t keys_count, struct tbuf *keys, { stat_collect(stat_base, MEMC_GET, 1); stats.cmd_get++; - say_debug("ensuring space for %"PRI_SZ" keys", keys_count); + say_debug("ensuring space for %" PRI_SZ " keys", keys_count); while (keys_count-- > 0) { struct tuple *tuple; const struct meta *m; @@ -287,17 +291,17 @@ void memcached_get(struct obuf *out, size_t keys_count, struct tbuf *keys, /* skip key */ _l = load_varint32(&field); - field += _l; + field = (const char *) field + _l; /* metainfo */ _l = load_varint32(&field); - m = field; - field += _l; + m = (const struct meta *) field; + field = (const char *) field + _l; /* suffix */ suffix_len = load_varint32(&field); suffix = field; - field += suffix_len; + field = (const char *) field + suffix_len; /* value */ value_len = load_varint32(&field); @@ -313,7 +317,7 @@ void memcached_get(struct obuf *out, size_t keys_count, struct tbuf *keys, if (show_cas) { struct tbuf *b = tbuf_new(fiber->gc_pool); - tbuf_printf(b, "VALUE %.*s %"PRIu32" %"PRIu32" %"PRIu64"\r\n", key_len, (char*) key, m->flags, value_len, m->cas); + tbuf_printf(b, "VALUE %.*s %" PRIu32 " %" PRIu32 " %" PRIu64 "\r\n", key_len, (char*) key, m->flags, value_len, m->cas); obuf_dup(out, b->data, b->size); stats.bytes_written += b->size; } else { @@ -335,8 +339,8 @@ flush_all(va_list ap) uintptr_t delay = va_arg(ap, uintptr_t); fiber_sleep(delay - ev_now()); struct tuple *tuple; - struct iterator *it = [memcached_index allocIterator]; - [memcached_index initIterator: it :ITER_ALL :NULL :0]; + struct iterator *it = memcached_index->allocIterator(); + memcached_index->initIterator(it, ITER_ALL, NULL, 0); while ((tuple = it->next(it))) { meta(tuple)->exptime = 1; } @@ -349,20 +353,20 @@ do { \ if (bytes > (1<<20)) { \ obuf_dup(out, "SERVER_ERROR object too large for cache\r\n", 41);\ } else { \ - @try { \ + try { \ store(key, exptime, flags, bytes, data); \ stats.total_items++; \ obuf_dup(out, "STORED\r\n", 8); \ } \ - @catch (ClientError *e) { \ + catch (const ClientError& e) { \ obuf_dup(out, "SERVER_ERROR ", 13); \ - obuf_dup(out, e->errmsg, strlen(e->errmsg)); \ + obuf_dup(out, e.errmsg(), strlen(e.errmsg())); \ obuf_dup(out, "\r\n", 2); \ } \ } \ } while (0) -#include "memcached-grammar.m" +#include "memcached-grammar.cc" void memcached_loop(struct ev_io *coio, struct iobuf *iobuf) @@ -413,18 +417,20 @@ memcached_handler(va_list ap) stats.total_connections++; stats.curr_connections++; - @try { + try { + auto scoped_guard = make_scoped_guard([&] { + fiber_sleep(0.01); + stats.curr_connections--; + evio_close(&coio); + iobuf_delete(iobuf); + }); + memcached_loop(&coio, iobuf); iobuf_flush(iobuf, &coio); - } @catch (FiberCancelException *e) { - @throw; - } @catch (tnt_Exception *e) { - [e log]; - } @finally { - fiber_sleep(0.01); - stats.curr_connections--; - evio_close(&coio); - iobuf_delete(iobuf); + } catch (const FiberCancelException& e) { + throw; + } catch (const Exception& e) { + e.log(); } } @@ -437,7 +443,7 @@ memcached_check_config(struct tarantool_cfg *conf) if (conf->memcached_port <= 0 || conf->memcached_port >= USHRT_MAX) { /* invalid space number */ - out_warning(0, "invalid memcached port value: %i", + out_warning(CNF_OK, "invalid memcached port value: %i", conf->memcached_port); return -1; } @@ -446,14 +452,14 @@ memcached_check_config(struct tarantool_cfg *conf) if (conf->memcached_expire_per_loop <= 0) { /* invalid expire per loop value */ - out_warning(0, "invalid expire per loop value: %i", + out_warning(CNF_OK, "invalid expire per loop value: %i", conf->memcached_expire_per_loop); return -1; } if (conf->memcached_expire_full_sweep <= 0) { /* invalid expire full sweep value */ - out_warning(0, "invalid expire full sweep value: %i", + out_warning(CNF_OK, "invalid expire full sweep value: %i", conf->memcached_expire_full_sweep); return -1; } @@ -498,13 +504,13 @@ memcached_space_init() /* Configure memcached index key. */ - struct key_def *key_def = malloc(sizeof(struct key_def)); + struct key_def *key_def = (struct key_def *) malloc(sizeof(struct key_def)); key_def->part_count = 1; key_def->is_unique = true; key_def->type = HASH; - key_def->parts = malloc(sizeof(struct key_part)); - key_def->cmp_order = malloc(sizeof(u32)); + key_def->parts = (struct key_part *) malloc(sizeof(struct key_part)); + key_def->cmp_order = (u32 *) malloc(sizeof(u32)); if (key_def->parts == NULL || key_def->cmp_order == NULL) panic("out of memory when configuring memcached_space"); @@ -519,10 +525,8 @@ memcached_space_init() struct space *memc_s = space_create(cfg.memcached_space, key_def, 1, 4); - Index *memc_index = [Index alloc: HASH :key_def :memc_s]; + Index *memc_index = Index::factory(HASH, key_def, memc_s); space_set_index(memc_s, 0, memc_index); - - [memc_index init: key_def :memc_s]; } /** Delete a bunch of expired keys. */ @@ -533,13 +537,13 @@ memcached_delete_expired_keys(struct tbuf *keys_to_delete) int expired_keys = 0; while (keys_to_delete->size > 0) { - @try { - delete(tbuf_read_field(keys_to_delete)); + try { + remove(tbuf_read_field(keys_to_delete)); expired_keys++; } - @catch (ClientError *e) { + catch (const ClientError& e) { /* expire is off when replication is on */ - assert(e->errcode != ER_NONMASTER); + assert(e.errcode() != ER_NONMASTER); /* The error is already logged. */ } } @@ -547,7 +551,7 @@ memcached_delete_expired_keys(struct tbuf *keys_to_delete) double delay = ((double) cfg.memcached_expire_per_loop * cfg.memcached_expire_full_sweep / - ([memcached_index size] + 1)); + (memcached_index->size() + 1)); if (delay > 1) delay = 1; fiber_setcancellable(true); @@ -561,11 +565,11 @@ memcached_expire_loop(va_list ap __attribute__((unused))) struct tuple *tuple = NULL; say_info("memcached expire fiber started"); - memcached_it = [memcached_index allocIterator]; - @try { + memcached_it = memcached_index->allocIterator(); + try { restart: if (tuple == NULL) - [memcached_index initIterator: memcached_it :ITER_ALL :NULL :0]; + memcached_index->initIterator(memcached_it, ITER_ALL, NULL, 0); struct tbuf *keys_to_delete = tbuf_new(fiber->gc_pool); @@ -585,7 +589,7 @@ memcached_expire_loop(va_list ap __attribute__((unused))) memcached_delete_expired_keys(keys_to_delete); fiber_gc(); goto restart; - } @finally { + } catch(const Exception& e) { memcached_it->free(memcached_it); memcached_it = NULL; } @@ -597,10 +601,10 @@ void memcached_start_expire() return; assert(memcached_expire == NULL); - @try { + try { memcached_expire = fiber_new("memcached_expire", memcached_expire_loop); - } @catch (tnt_Exception *e) { + } catch (const Exception& e) { say_error("can't start the expire fiber"); return; } diff --git a/src/object.m b/src/object.cc similarity index 83% rename from src/object.m rename to src/object.cc index 7d5a6c3bb278c62749c2b95c8764327eb48303be..0f79a1b654f27e0eb12bad13e40304652e43dc88 100644 --- a/src/object.m +++ b/src/object.cc @@ -26,26 +26,5 @@ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#import "object.h" -#include <stdlib.h> -@implementation tnt_Object -+ (id) alloc -{ - return class_createInstance(self, 0); -} -- (id) init -{ - return self; -} -- (void) subclassResponsibility: (SEL) cmd -{ - (void) cmd; - abort(); -} - -- (void) free -{ - object_dispose(self); -} -@end +#include "object.h" diff --git a/src/opts.c b/src/opts.c new file mode 100644 index 0000000000000000000000000000000000000000..9b02f1d68d3736dcd666ef404b4e58c1b9f026b1 --- /dev/null +++ b/src/opts.c @@ -0,0 +1,57 @@ +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "tarantool.h" + +#include <stddef.h> + +#include <third_party/gopt/gopt.h> + +const void *opt_def = + gopt_start(gopt_option('g', GOPT_ARG, gopt_shorts(0), + gopt_longs("cfg-get", "cfg_get"), + "=KEY", "return a value from configuration file described by KEY"), + gopt_option('k', 0, gopt_shorts(0), + gopt_longs("check-config"), + NULL, "Check configuration file for errors"), + gopt_option('c', GOPT_ARG, gopt_shorts('c'), + gopt_longs("config"), + "=FILE", "path to configuration file (default: " DEFAULT_CFG_FILENAME ")"), + gopt_option('I', 0, gopt_shorts(0), + gopt_longs("init-storage", "init_storage"), + NULL, "initialize storage (an empty snapshot file) and exit"), + gopt_option('v', 0, gopt_shorts('v'), gopt_longs("verbose"), + NULL, "increase verbosity level in log messages"), + gopt_option('B', 0, gopt_shorts('B'), gopt_longs("background"), + NULL, "redirect input/output streams to a log file and run as daemon"), + gopt_option('h', 0, gopt_shorts('h', '?'), gopt_longs("help"), + NULL, "display this help and exit"), + gopt_option('V', 0, gopt_shorts('V'), gopt_longs("version"), + NULL, "print program version and exit") +); diff --git a/src/palloc.m b/src/palloc.cc similarity index 77% rename from src/palloc.m rename to src/palloc.cc index 2d7831026e8968995cd313da8aee0a4caa56605c..1a35530fee38b9c58227f302f2904c94e7ac1520 100644 --- a/src/palloc.m +++ b/src/palloc.cc @@ -48,7 +48,7 @@ struct chunk { size_t free; size_t size; - struct chunk_class *class; + struct chunk_class *clazz; SLIST_ENTRY(chunk) busy_link; SLIST_ENTRY(chunk) free_link; }; @@ -100,25 +100,25 @@ palloc_greatest_size(void) static struct chunk_class * class_init(size_t size) { - struct chunk_class *class; + struct chunk_class *clazz; - class = malloc(sizeof(struct chunk_class)); - if (class == NULL) + clazz = (struct chunk_class *) malloc(sizeof(struct chunk_class)); + if (clazz == NULL) return NULL; - class->i = class_count++; - class->chunks_count = 0; - class->allocated_size = size; - SLIST_INIT(&class->chunks); - TAILQ_INSERT_TAIL(&classes, class, link); + clazz->i = class_count++; + clazz->chunks_count = 0; + clazz->allocated_size = size; + SLIST_INIT(&clazz->chunks); + TAILQ_INSERT_TAIL(&classes, clazz, link); - return class; + return clazz; } int palloc_init(void) { - struct chunk_class *class; + struct chunk_class *clazz; class_count = 0; TAILQ_INIT(&classes); @@ -137,10 +137,10 @@ palloc_init(void) if (class_init(palloc_greatest_size()) == NULL) return 0; - if ((class = class_init(-1)) == NULL) + if ((clazz = class_init(-1)) == NULL) return 0; - TAILQ_NEXT(class, link) = NULL; + TAILQ_NEXT(clazz, link) = NULL; eter_pool = palloc_create_pool("eter_pool"); return 1; @@ -155,9 +155,9 @@ palloc_free(void) palloc_free_unused(); - struct chunk_class *class, *class_next; - TAILQ_FOREACH_SAFE(class, &classes, link, class_next) - free(class); + struct chunk_class *clazz, *class_next; + TAILQ_FOREACH_SAFE(clazz, &classes, link, class_next) + free(clazz); } static void @@ -174,47 +174,47 @@ static struct chunk * next_chunk_for(struct palloc_pool *restrict pool, size_t size) { struct chunk *restrict chunk = SLIST_FIRST(&pool->chunks); - struct chunk_class *restrict class; + struct chunk_class *restrict clazz; size_t chunk_size; if (chunk != NULL) - class = chunk->class; + clazz = chunk->clazz; else - class = TAILQ_FIRST(&classes); + clazz = TAILQ_FIRST(&classes); - if (class->allocated_size == -1) - class = TAILQ_PREV(class, class_tailq_head, link); + if (clazz->allocated_size == -1) + clazz = TAILQ_PREV(clazz, class_tailq_head, link); - while (class != NULL && class->allocated_size < size + sizeof(struct chunk)) - class = TAILQ_NEXT(class, link); + while (clazz != NULL && clazz->allocated_size < size + sizeof(struct chunk)) + clazz = TAILQ_NEXT(clazz, link); - assert(class != NULL); + assert(clazz != NULL); - chunk = SLIST_FIRST(&class->chunks); + chunk = SLIST_FIRST(&clazz->chunks); if (chunk != NULL) { - SLIST_REMOVE_HEAD(&class->chunks, free_link); + SLIST_REMOVE_HEAD(&clazz->chunks, free_link); goto found; } if (size > palloc_greatest_size()) { chunk_size = size + sizeof(struct chunk); - chunk = malloc(chunk_size); + chunk = (struct chunk *) malloc(chunk_size); if (chunk == NULL) return NULL; } else { - chunk_size = class->allocated_size; - chunk = mmap(NULL, chunk_size, + chunk_size = clazz->allocated_size; + chunk = (struct chunk *) mmap(NULL, chunk_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (chunk == MAP_FAILED) return NULL; } - class->chunks_count++; + clazz->chunks_count++; chunk->magic = chunk_magic; chunk->size = chunk_size; chunk->free = chunk_size - sizeof(struct chunk); - chunk->brk = (void *)chunk + sizeof(struct chunk); - chunk->class = class; + chunk->brk = (char *)chunk + sizeof(struct chunk); + chunk->clazz = clazz; found: assert(chunk != NULL && chunk->magic == chunk_magic); SLIST_INSERT_HEAD(&pool->chunks, chunk, busy_link); @@ -244,13 +244,13 @@ palloc_slow_path(struct palloc_pool *restrict pool, size_t size) struct chunk *chunk; chunk = next_chunk_for(pool, size); if (chunk == NULL) { - tnt_raise(LoggedError, :ER_MEMORY_ISSUE, + tnt_raise(LoggedError, ER_MEMORY_ISSUE, size, "palloc", "next chunk"); } assert(chunk->free >= size); void *ptr = chunk->brk; - chunk->brk += size; + chunk->brk = (char *) chunk->brk + size; chunk->free -= size; return ptr; } @@ -266,15 +266,15 @@ palloc(struct palloc_pool *restrict pool, size_t size) if (likely(chunk != NULL && chunk->free >= rz_size)) { ptr = chunk->brk; - chunk->brk += rz_size; + chunk->brk = (char *) chunk->brk + rz_size; chunk->free -= rz_size; } else ptr = palloc_slow_path(pool, rz_size); - assert(poisoned(ptr + PALLOC_REDZONE, size) == NULL); - (void) VALGRIND_MAKE_MEM_DEFINED(ptr + PALLOC_REDZONE, size); + assert(poisoned((char *) ptr + PALLOC_REDZONE, size) == NULL); + (void) VALGRIND_MAKE_MEM_DEFINED((char *) ptr + PALLOC_REDZONE, size); - return ptr + PALLOC_REDZONE; + return (char *) ptr + PALLOC_REDZONE; } void *__attribute__((regparm(2))) @@ -302,8 +302,8 @@ chunk_free(struct chunk *chunk) { if (chunk->size <= palloc_greatest_size()) { chunk->free = chunk->size - sizeof(struct chunk); - chunk->brk = (void *)chunk + sizeof(struct chunk); - SLIST_INSERT_HEAD(&chunk->class->chunks, chunk, free_link); + chunk->brk = (char *)chunk + sizeof(struct chunk); + SLIST_INSERT_HEAD(&chunk->clazz->chunks, chunk, free_link); poison_chunk(chunk); } else { free(chunk); @@ -328,7 +328,7 @@ ptruncate(struct palloc_pool *pool, size_t new_size) sizeof(struct chunk)); if (chunk_used > cut_size) { /* This is the last chunk to trim. */ - chunk->brk -= cut_size; + chunk->brk = (char *) chunk->brk - cut_size; chunk->free += cut_size; (void) VALGRIND_MAKE_MEM_NOACCESS(chunk->brk, cut_size); cut_size = 0; @@ -365,7 +365,7 @@ palloc_reset(struct palloc_pool *pool) pool->allocated -= chunk->size - sizeof(struct chunk) - chunk->free; chunk->free = chunk->size - sizeof(struct chunk); - chunk->brk = (void *)chunk + sizeof(struct chunk); + chunk->brk = (char *)chunk + sizeof(struct chunk); } } @@ -379,9 +379,10 @@ prelease_after(struct palloc_pool *pool, size_t after) struct palloc_pool * palloc_create_pool(const char *name) { - struct palloc_pool *pool = calloc(sizeof(struct palloc_pool), 1); + struct palloc_pool *pool = (struct palloc_pool *) + calloc(sizeof(struct palloc_pool), 1); if (pool == NULL) { - tnt_raise(LoggedError, :ER_MEMORY_ISSUE, + tnt_raise(LoggedError, ER_MEMORY_ISSUE, sizeof(struct palloc_pool), "malloc", "palloc pool"); } @@ -402,20 +403,20 @@ palloc_destroy_pool(struct palloc_pool *pool) void palloc_free_unused(void) { - struct chunk_class *class; + struct chunk_class *clazz; struct chunk *chunk, *next_chunk; - TAILQ_FOREACH(class, &classes, link) { - SLIST_FOREACH_SAFE(chunk, &class->chunks, free_link, next_chunk) - munmap(chunk, class->allocated_size); - SLIST_INIT(&class->chunks); + TAILQ_FOREACH(clazz, &classes, link) { + SLIST_FOREACH_SAFE(chunk, &clazz->chunks, free_link, next_chunk) + munmap(chunk, clazz->allocated_size); + SLIST_INIT(&clazz->chunks); } } void palloc_stat(struct tbuf *buf) { - struct chunk_class *class; + struct chunk_class *clazz; struct chunk *chunk; struct palloc_pool *pool; int chunks[class_count]; @@ -433,26 +434,26 @@ palloc_stat(struct tbuf *buf) tbuf_printf(buf, " busy chunks:" CRLF); SLIST_FOREACH(chunk, &pool->chunks, busy_link) - chunks[chunk->class->i]++; + chunks[chunk->clazz->i]++; - TAILQ_FOREACH(class, &classes, link) { - if (chunks[class->i] == 0) + TAILQ_FOREACH(clazz, &classes, link) { + if (chunks[clazz->i] == 0) continue; - tbuf_printf(buf, " - { size: %"PRIu32", used: %i }" CRLF, - class->allocated_size, chunks[class->i]); + tbuf_printf(buf, " - { size: %" PRIu32 ", used: %i }" CRLF, + clazz->allocated_size, chunks[clazz->i]); } } } tbuf_printf(buf, " classes:" CRLF); - TAILQ_FOREACH(class, &classes, link) { + TAILQ_FOREACH(clazz, &classes, link) { int free_chunks = 0; - SLIST_FOREACH(chunk, &class->chunks, free_link) + SLIST_FOREACH(chunk, &clazz->chunks, free_link) free_chunks++; tbuf_printf(buf, - " - { size: %"PRIu32 - ", free_chunks: %- 6i, busy_chunks: %- 6i }" CRLF, class->allocated_size, - free_chunks, class->chunks_count - free_chunks); + " - { size: %" PRIu32 + ", free_chunks: %- 6i, busy_chunks: %- 6i }" CRLF, clazz->allocated_size, + free_chunks, clazz->chunks_count - free_chunks); } u64 palloc_total = 0; u64 palloc_used = 0; @@ -465,7 +466,7 @@ palloc_stat(struct tbuf *buf) palloc_total += chunk->size; } tbuf_printf(buf, " total:" CRLF); - tbuf_printf(buf, " - { occupied: %"PRIu64", used: %"PRIu64" }"CRLF, + tbuf_printf(buf, " - { occupied: %" PRIu64 ", used: %" PRIu64 " }" CRLF, palloc_total, palloc_used); } diff --git a/src/pickle.m b/src/pickle.cc similarity index 99% rename from src/pickle.m rename to src/pickle.cc index 09aaf354321c0fcd16ed871c0164271c32924f2a..428602ededc4033269fbb54c5a5be44c697c855b 100644 --- a/src/pickle.m +++ b/src/pickle.cc @@ -27,3 +27,4 @@ * SUCH DAMAGE. */ #include "pickle.h" + diff --git a/src/recovery.m b/src/recovery.cc similarity index 97% rename from src/recovery.m rename to src/recovery.cc index dba5f7004b5d94ec7f6eee11dc8e81eeab24da48..240e5c6547a76ce5bef37d6c36960681559975c2 100644 --- a/src/recovery.m +++ b/src/recovery.cc @@ -119,8 +119,9 @@ wait_lsn_set(struct wait_lsn *wait_lsn, int64_t lsn) static inline void wakeup_lsn_waiter(struct recovery_state *r) { - if (r->wait_lsn.waiter && r->confirmed_lsn >= r->wait_lsn.lsn) + if (r->wait_lsn.waiter && r->confirmed_lsn >= r->wait_lsn.lsn) { fiber_wakeup(r->wait_lsn.waiter); + } } void @@ -167,10 +168,12 @@ recovery_wait_lsn(struct recovery_state *r, int64_t lsn) { while (lsn < r->confirmed_lsn) { wait_lsn_set(&r->wait_lsn, lsn); - @try { + try { fiber_yield(); - } @finally { wait_lsn_clear(&r->wait_lsn); + } catch(const Exception& e) { + wait_lsn_clear(&r->wait_lsn); + throw; } } } @@ -202,7 +205,7 @@ recovery_init(const char *snap_dirname, const char *wal_dirname, int rows_per_wal, int flags) { assert(recovery_state == NULL); - recovery_state = p0alloc(eter_pool, sizeof(struct recovery_state)); + recovery_state = (struct recovery_state *) p0alloc(eter_pool, sizeof(struct recovery_state)); struct recovery_state *r = recovery_state; recovery_update_mode(r, "none", 0); @@ -226,7 +229,7 @@ void recovery_update_mode(struct recovery_state *r, const char *mode, double fsync_delay) { - r->wal_mode = strindex(wal_mode_STRS, mode, WAL_MODE_MAX); + r->wal_mode = (enum wal_mode) strindex(wal_mode_STRS, mode, WAL_MODE_MAX); assert(r->wal_mode != WAL_MODE_MAX); /* No mutex lock: let's not bother with whether * or not a WAL writer thread is present, and @@ -384,6 +387,9 @@ recover_remaining_wals(struct recovery_state *r) struct log_io *next_wal; i64 current_lsn, wal_greatest_lsn; size_t rows_before; + FILE *f; + char *filename; + enum log_suffix suffix; current_lsn = r->confirmed_lsn + 1; wal_greatest_lsn = greatest_lsn(r->wal_dir); @@ -418,9 +424,8 @@ recover_remaining_wals(struct recovery_state *r) * .xlog, with no risk of a concurrent * inprogress_log_rename(). */ - FILE *f = NULL; - char *filename; - enum log_suffix suffix = INPROGRESS; + f = NULL; + suffix = INPROGRESS; if (current_lsn == wal_greatest_lsn) { /* Last WAL present at the time of rescan. */ filename = format_filename(r->wal_dir, @@ -607,7 +612,7 @@ recovery_stop_file(struct wal_watcher *watcher) static void recovery_rescan_dir(ev_timer *w, int revents __attribute__((unused))) { - struct recovery_state *r = w->data; + struct recovery_state *r = (struct recovery_state *) w->data; struct wal_watcher *watcher = r->watcher; struct log_io *save_current_wal = r->current_wal; @@ -625,7 +630,7 @@ recovery_rescan_dir(ev_timer *w, int revents __attribute__((unused))) static void recovery_rescan_file(ev_stat *w, int revents __attribute__((unused))) { - struct recovery_state *r = w->data; + struct recovery_state *r = (struct recovery_state *) w->data; struct wal_watcher *watcher = r->watcher; int result = recover_wal(r, r->current_wal); if (result < 0) @@ -767,9 +772,9 @@ wal_schedule_queue(struct wal_fifo *queue) } static void -wal_schedule(ev_watcher *watcher, int event __attribute__((unused))) +wal_schedule(ev_async *watcher, int event __attribute__((unused))) { - struct wal_writer *writer = watcher->data; + struct wal_writer *writer = (struct wal_writer *) watcher->data; struct wal_fifo commit = STAILQ_HEAD_INITIALIZER(commit); struct wal_fifo rollback = STAILQ_HEAD_INITIALIZER(rollback); @@ -818,7 +823,7 @@ wal_writer_init(struct wal_writer *writer) STAILQ_INIT(&writer->input); STAILQ_INIT(&writer->commit); - ev_async_init(&writer->write_event, (void *)wal_schedule); + ev_async_init(&writer->write_event, wal_schedule); writer->write_event.data = writer; (void) tt_pthread_once(&wal_writer_once, wal_writer_init_once); @@ -1059,7 +1064,7 @@ wal_write_to_disk(struct recovery_state *r, struct wal_writer *writer, static void * wal_writer_thread(void *worker_args) { - struct recovery_state *r = worker_args; + struct recovery_state *r = (struct recovery_state *) worker_args; struct wal_writer *writer = r->writer; struct wal_fifo input = STAILQ_HEAD_INITIALIZER(input); struct wal_fifo commit = STAILQ_HEAD_INITIALIZER(commit); @@ -1109,7 +1114,7 @@ wal_write(struct recovery_state *r, i64 lsn, u64 cookie, struct wal_writer *writer = r->writer; - struct wal_write_request *req = + struct wal_write_request *req = (struct wal_write_request *) palloc(fiber->gc_pool, sizeof(struct wal_write_request) + sizeof(op) + row_len); @@ -1158,7 +1163,7 @@ snapshot_write_row(struct log_io *l, struct fio_batch *batch, ev_tstamp elapsed; static ev_tstamp last = 0; - struct row_v11 *row = palloc(fiber->gc_pool, + struct row_v11 *row = (struct row_v11 *) palloc(fiber->gc_pool, sizeof(struct row_v11) + data_len + metadata_len); diff --git a/src/replica.m b/src/replica.cc similarity index 93% rename from src/replica.m rename to src/replica.cc index be4af6d7df85356f40421784b4662a87ce750c90..753c82be2a074855b700156b2511c4d1156610f3 100644 --- a/src/replica.m +++ b/src/replica.cc @@ -58,10 +58,12 @@ remote_read_row(struct ev_io *coio, struct iobuf *iobuf) if (to_read > 0) coio_breadn(coio, in, to_read); - struct tbuf row = { - .size = request_len, .capacity = request_len, - .data = in->pos, .pool = fiber->gc_pool - }; + struct tbuf row; + row.size = (uint32_t) request_len; + row.capacity = (uint32_t) request_len; + row.data = in->pos; + row.pool = fiber->gc_pool; + in->pos += request_len; return row; } @@ -83,7 +85,7 @@ remote_connect(struct ev_io *coio, struct sockaddr_in *remote_addr, coio_readn(coio, &version, sizeof(version)); *err = NULL; if (version != default_version) - tnt_raise(SystemError, :"remote version mismatch"); + tnt_raise(IllegalParams, "remote version mismatch"); say_crit("successfully connected to master"); say_crit("starting replication from lsn: %" PRIi64, initial_lsn); @@ -102,7 +104,7 @@ pull_from_remote(va_list ap) for (;;) { const char *err = NULL; - @try { + try { fiber_setcancellable(true); if (! evio_is_active(&coio)) { if (iobuf == NULL) @@ -123,12 +125,12 @@ pull_from_remote(va_list ap) iobuf_gc(iobuf); fiber_gc(); - } @catch (FiberCancelException *e) { + } catch (const FiberCancelException& e) { iobuf_delete(iobuf); evio_close(&coio); - @throw; - } @catch (tnt_Exception *e) { - [e log]; + throw; + } catch (const Exception& e) { + e.log(); if (! warning_said) { if (err != NULL) say_info("%s", err); @@ -169,9 +171,9 @@ recovery_follow_remote(struct recovery_state *r, const char *addr) say_crit("initializing the replica, WAL master %s", addr); snprintf(name, sizeof(name), "replica/%s", addr); - @try { + try { f = fiber_new(name, pull_from_remote); - } @catch (tnt_Exception *e) { + } catch (const Exception& ) { return; } diff --git a/src/replication.m b/src/replication.cc similarity index 97% rename from src/replication.m rename to src/replication.cc index bb4419aebd99ec3a223ea8c679be7ab99d301664..50241c361bc3690c0f2afe71f1239fec76ed2e7c 100644 --- a/src/replication.m +++ b/src/replication.cc @@ -29,7 +29,10 @@ #include <replication.h> #include <say.h> #include <fiber.h> -#include TARANTOOL_CONFIG +extern "C" { +#include <cfg/warning.h> +#include <cfg/tarantool_box_cfg.h> +} /* extern "C" */ #include <palloc.h> #include <stddef.h> @@ -151,7 +154,7 @@ replication_check_config(struct tarantool_cfg *config) { if (config->replication_port < 0 || config->replication_port >= USHRT_MAX) { - say_error("invalid replication port value: %"PRId32, + say_error("invalid replication port value: %" PRId32, config->replication_port); return -1; } @@ -236,7 +239,7 @@ replication_on_accept(struct evio_service *service __attribute__((unused)), */ sio_setfl(fd, O_NONBLOCK, 0); - struct ev_io *io = malloc(sizeof(struct ev_io)); + struct ev_io *io = (struct ev_io *) malloc(sizeof(struct ev_io)); if (io == NULL) { close(fd); return; @@ -487,7 +490,7 @@ spawner_shutdown_children() /* We'll wait for children no longer than 5 sec. */ alarm(5); - say_info("sending signal %d to %"PRIu32" children", kill_signo, + say_info("sending signal %d to %" PRIu32 " children", kill_signo, (u32) spawner.child_count); kill(0, kill_signo); @@ -556,7 +559,7 @@ static int replication_relay_send_row(void *param, struct tbuf *t) { int client_sock = (int) (intptr_t) param; - u8 *data = t->data; + u8 *data = (u8 *) t->data; ssize_t bytes, len = t->size; while (len > 0) { bytes = write(client_sock, data, len); @@ -624,7 +627,7 @@ replication_relay_loop(int client_sock) } panic("invalid LSN request size: %zu", r); } - say_info("starting replication from lsn: %"PRIi64, lsn); + say_info("starting replication from lsn: %" PRIi64, lsn); ver = tbuf_new(fiber->gc_pool); tbuf_append(ver, &default_version, sizeof(default_version)); diff --git a/src/salloc.m b/src/salloc.cc similarity index 89% rename from src/salloc.m rename to src/salloc.cc index 13d18e898719de258c279ee59fbc20467bf027ba..1ba9876f1b9f3a83beeeb4b37e2da779e69f519b 100644 --- a/src/salloc.m +++ b/src/salloc.cc @@ -102,7 +102,7 @@ static struct arena arena; static struct slab * slab_header(void *ptr) { - struct slab *slab = SLAB_ALIGN_PTR(ptr); + struct slab *slab = (struct slab *) SLAB_ALIGN_PTR(ptr); assert(slab->magic == SLAB_MAGIC); return slab; } @@ -196,7 +196,7 @@ format_slab(struct slab_cache *cache, struct slab *slab) slab->cache = cache; slab->items = 0; slab->used = 0; - slab->brk = (void *)CACHEALIGN((void *)slab + sizeof(struct slab)); + slab->brk = (char *)CACHEALIGN((char *)slab + sizeof(struct slab)); TAILQ_INSERT_HEAD(&cache->slabs, slab, cache_link); TAILQ_INSERT_HEAD(&cache->free_slabs, slab, cache_free_link); @@ -205,7 +205,7 @@ format_slab(struct slab_cache *cache, struct slab *slab) static bool fully_formatted(struct slab *slab) { - return slab->brk + slab->cache->item_size >= (void *)slab + SLAB_SIZE; + return (char *) slab->brk + slab->cache->item_size >= (char *)slab + SLAB_SIZE; } void @@ -251,7 +251,7 @@ slab_of(struct slab_cache *cache) return slab; } - if ((slab = arena_alloc(&arena)) != NULL) { + if ((slab = (struct slab *) arena_alloc(&arena)) != NULL) { format_slab(cache, slab); SLIST_INSERT_HEAD(&arena.slabs, slab, link); return slab; @@ -264,8 +264,8 @@ slab_of(struct slab_cache *cache) static bool valid_item(struct slab *slab, void *item) { - return (void *)item >= (void *)(slab) + sizeof(struct slab) && - (void *)item < (void *)(slab) + sizeof(struct slab) + SLAB_SIZE; + return (char *)item >= (char *)(slab) + sizeof(struct slab) && + (char *)item < (char *)(slab) + sizeof(struct slab) + SLAB_SIZE; } #endif @@ -279,15 +279,15 @@ salloc(size_t size, const char *what) if ((cache = cache_for(size)) == NULL || (slab = slab_of(cache)) == NULL) { - tnt_raise(LoggedError, :ER_MEMORY_ISSUE, size, + tnt_raise(LoggedError, ER_MEMORY_ISSUE, size, "slab allocator", what); } if (slab->free == NULL) { assert(valid_item(slab, slab->brk)); - item = slab->brk; - memcpy((void *)item + cache->item_size, red_zone, sizeof(red_zone)); - slab->brk += cache->item_size + sizeof(red_zone); + item = (struct slab_item *) slab->brk; + memcpy((char *)item + cache->item_size, red_zone, sizeof(red_zone)); + slab->brk = (char *) slab->brk + cache->item_size + sizeof(red_zone); } else { assert(valid_item(slab, slab->free)); item = slab->free; @@ -314,7 +314,7 @@ sfree(void *ptr) return; struct slab *slab = slab_header(ptr); struct slab_cache *cache = slab->cache; - struct slab_item *item = ptr; + struct slab_item *item = (struct slab_item *) ptr; if (fully_formatted(slab) && slab->free == NULL) TAILQ_INSERT_TAIL(&cache->free_slabs, slab, cache_free_link); @@ -341,17 +341,17 @@ size_t salloc_ptr_to_index(void *ptr) { struct slab *slab = slab_header(ptr); - struct slab_item *item = ptr; + struct slab_item *item = (struct slab_item *) ptr; struct slab_cache *clazz = slab->cache; (void) item; assert(valid_item(slab, item)); - void *brk_start = (void *)CACHEALIGN((void *)slab+sizeof(struct slab)); - ptrdiff_t item_no = (ptr - brk_start) / clazz->item_size; + void *brk_start = (char *)CACHEALIGN((char *)slab+sizeof(struct slab)); + ptrdiff_t item_no = ((const char *) ptr - (const char *) brk_start) / clazz->item_size; assert(item_no >= 0); - ptrdiff_t slab_no = ((void *) slab - (void *) arena.base) / SLAB_SIZE; + ptrdiff_t slab_no = ((const char *) slab - (const char *) arena.base) / SLAB_SIZE; assert(slab_no >= 0); size_t index = (size_t)slab_no * MAX_SLAB_ITEM_COUNT + (size_t) item_no; @@ -371,8 +371,8 @@ salloc_ptr_from_index(size_t index) (void *) ((size_t) arena.base + SLAB_SIZE * slab_no)); struct slab_cache *clazz = slab->cache; - void *brk_start = (void *)CACHEALIGN((void *)slab+sizeof(struct slab)); - struct slab_item *item = brk_start + item_no * clazz->item_size; + void *brk_start = (char *)CACHEALIGN((char *)slab+sizeof(struct slab)); + struct slab_item *item = (struct slab_item *)((char *) brk_start + item_no * clazz->item_size); assert(valid_item(slab, item)); return (void *) item; diff --git a/src/say.m b/src/say.cc similarity index 95% rename from src/say.m rename to src/say.cc index b0fa1b29860bf5ff4de27657aeddbe7b3dc9ba71..b3e5db473adb32a1e705b2264ebe34fd9b55c6e0 100644 --- a/src/say.m +++ b/src/say.cc @@ -39,7 +39,10 @@ #endif #include <fiber.h> -#include TARANTOOL_CONFIG +extern "C" { +#include <cfg/warning.h> +#include <cfg/tarantool_box_cfg.h> +} /* extern "C" */ #include "tarantool.h" #include "sio.h" @@ -72,7 +75,9 @@ say_logger_init(int nonblock) { int pipefd[2]; pid_t pid; - char *argv[] = { "/bin/sh", "-c", cfg.logger, NULL }; + char cmd[] = { "/bin/sh" }; + char args[] = { "-c" }; + char *argv[] = { cmd, args, cfg.logger, NULL }; char *envp[] = { NULL }; if (cfg.logger != NULL) { @@ -178,7 +183,7 @@ void _say(int level, const char *filename, int line, const char *error, const char *format, ...) { int errsv = errno; /* Preserve the errno. */ - if (cfg.log_level < level) + if (cfg.log_level < level) return; va_list ap; va_start(ap, format); diff --git a/src/scoped_guard.cc b/src/scoped_guard.cc new file mode 100644 index 0000000000000000000000000000000000000000..f7414593c8eb629fce8602fd4f3f9088030e76f9 --- /dev/null +++ b/src/scoped_guard.cc @@ -0,0 +1,30 @@ +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "scoped_guard.h" diff --git a/src/session.m b/src/session.cc similarity index 89% rename from src/session.m rename to src/session.cc index 034c44d97818e307af1fd22785307a7a5d61a9dd..26f5e3ee1845de8cc5faeb88c67d5d0042024ec9 100644 --- a/src/session.m +++ b/src/session.cc @@ -47,14 +47,14 @@ session_create(int fd) ; uint32_t sid = sid_max; - struct mh_i32ptr_node_t node = { - .key = sid, .val = (void *) (intptr_t) fd - }; + struct mh_i32ptr_node_t node; + node.key = sid; + node.val = (void *) (intptr_t) fd; mh_int_t k = mh_i32ptr_put(session_registry, &node, NULL, NULL); if (k == mh_end(session_registry)) { - tnt_raise(ClientError, :ER_MEMORY_ISSUE, + tnt_raise(ClientError, ER_MEMORY_ISSUE, "session hash", "new session"); } /* @@ -64,12 +64,12 @@ session_create(int fd) fiber_set_sid(fiber, sid); if (session_on_connect.trigger) { void *param = session_on_connect.param; - @try { + try { session_on_connect.trigger(param); - } @catch (tnt_Exception *e) { + } catch (const Exception& e) { fiber_set_sid(fiber, 0); mh_i32ptr_remove(session_registry, &node, NULL); - @throw; + throw; } } @@ -84,22 +84,22 @@ session_destroy(uint32_t sid) if (session_on_disconnect.trigger) { void *param = session_on_disconnect.param; - @try { + try { session_on_disconnect.trigger(param); - } @catch (tnt_Exception *e) { - [e log]; - } @catch (id e) { + } catch (const Exception& e) { + e.log(); + } catch (...) { /* catch all. */ } } - struct mh_i32ptr_node_t node = { .key = sid }; + struct mh_i32ptr_node_t node = { sid, NULL }; mh_i32ptr_remove(session_registry, &node, NULL); } int session_fd(uint32_t sid) { - struct mh_i32ptr_node_t node = { .key = sid }; + struct mh_i32ptr_node_t node = { sid, NULL }; mh_int_t k = mh_i32ptr_get(session_registry, &node, NULL); return k == mh_end(session_registry) ? -1 : (intptr_t) mh_i32ptr_node(session_registry, k)->val; diff --git a/src/sio.m b/src/sio.cc similarity index 87% rename from src/sio.m rename to src/sio.cc index 4118db8d2e542d3c3ba27d2a0a53b0f0b5ab2c0e..03d592df635c16f85144e547efc7e30e736b8bf7 100644 --- a/src/sio.m +++ b/src/sio.cc @@ -37,6 +37,23 @@ #include "say.h" +SocketError::SocketError(const char *file, unsigned line, int fd, + const char *format, ...) + : SystemError(file, line) +{ + int save_errno = errno; + + char buf[TNT_ERRMSG_MAX]; + + va_list ap; + va_start(ap, format); + vsnprintf(buf, sizeof(buf), format, ap); + const char *socketname = sio_socketname(fd); + init("%s, called on %s", buf, socketname); + va_end(ap); + errno = save_errno; +} + /** Pretty print socket name and peer (for exceptions) */ const char * sio_socketname(int fd) @@ -61,28 +78,6 @@ sio_socketname(int fd) return name; } -@implementation SocketError -- (id) init: (int) fd in: (const char *) format: (va_list) ap -{ - int save_errno = errno; - char buf[TNT_ERRMSG_MAX]; - vsnprintf(buf, sizeof(buf), format, ap); - const char *socketname = sio_socketname(fd); - errno = save_errno; - self = [self init: "%s, called on %s", buf, socketname]; - return self; -} - -- (id) init: (int) fd in: (const char *) format, ... -{ - va_list ap; - va_start(ap, format); - self = [self init: fd in:format :ap]; - va_end(ap); - return self; -} -@end - /** Get a string representation of a socket option name, * for logging. */ @@ -108,7 +103,7 @@ sio_shutdown(int fd, int how) { int rc = shutdown(fd, how); if (rc < 0) - tnt_raise(SocketError, :fd in:"shutdown"); + tnt_raise(SocketError, fd, "shutdown"); return rc; } @@ -139,7 +134,7 @@ sio_socket(int domain, int type, int protocol) { int fd = socket(domain, type, protocol); if (fd < 0) - tnt_raise(SocketError, :fd in:"socket"); + tnt_raise(SocketError, fd, "socket"); return fd; } @@ -149,7 +144,7 @@ sio_getfl(int fd) { int flags = fcntl(fd, F_GETFL, 0); if (flags < 0) - tnt_raise(SocketError, :fd in:"fcntl(..., F_GETFL, ...)"); + tnt_raise(SocketError, fd, "fcntl(..., F_GETFL, ...)"); return flags; } @@ -160,7 +155,7 @@ sio_setfl(int fd, int flag, int on) int flags = sio_getfl(fd); flags = fcntl(fd, F_SETFL, on ? flags | flag : flags & ~flag); if (flags < 0) - tnt_raise(SocketError, :fd in:"fcntl(..., F_SETFL, ...)"); + tnt_raise(SocketError, fd, "fcntl(..., F_SETFL, ...)"); return flags; } @@ -171,7 +166,7 @@ sio_setsockopt(int fd, int level, int optname, { int rc = setsockopt(fd, level, optname, optval, optlen); if (rc) { - tnt_raise(SocketError, :fd in:"setsockopt(%s)", + tnt_raise(SocketError, fd, "setsockopt(%s)", sio_option_name(optname)); } } @@ -183,7 +178,7 @@ sio_getsockopt(int fd, int level, int optname, { int rc = getsockopt(fd, level, optname, optval, optlen); if (rc) { - tnt_raise(SocketError, :fd in:"getsockopt(%s)", + tnt_raise(SocketError, fd, "getsockopt(%s)", sio_option_name(optname)); } } @@ -195,7 +190,7 @@ sio_connect(int fd, struct sockaddr_in *addr, socklen_t addrlen) /* Establish the connection. */ int rc = connect(fd, (struct sockaddr *) addr, addrlen); if (rc < 0 && errno != EINPROGRESS) { - tnt_raise(SocketError, :fd in:"connect"); + tnt_raise(SocketError, fd, "connect"); } return rc; } @@ -206,7 +201,7 @@ sio_bind(int fd, struct sockaddr_in *addr, socklen_t addrlen) { int rc = bind(fd, (struct sockaddr *) addr, addrlen); if (rc < 0 && errno != EADDRINUSE) - tnt_raise(SocketError, :fd in:"bind"); + tnt_raise(SocketError, fd, "bind"); return rc; } @@ -216,7 +211,7 @@ sio_listen(int fd) { int rc = listen(fd, sio_listen_backlog()); if (rc < 0 && errno != EADDRINUSE) - tnt_raise(SocketError, :fd in:"listen"); + tnt_raise(SocketError, fd, "listen"); return rc; } @@ -227,7 +222,7 @@ sio_accept(int fd, struct sockaddr_in *addr, socklen_t *addrlen) /* Accept a connection. */ int newfd = accept(fd, (struct sockaddr *) addr, addrlen); if (newfd < 0 && errno != EAGAIN && errno != EWOULDBLOCK) - tnt_raise(SocketError, :fd in:"accept"); + tnt_raise(SocketError, fd, "accept"); return newfd; } @@ -238,7 +233,7 @@ sio_read(int fd, void *buf, size_t count) ssize_t n = read(fd, buf, count); if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) - tnt_raise(SocketError, :fd in:"read(%zd)", count); + tnt_raise(SocketError, fd, "read(%zd)", count); return n; } @@ -249,7 +244,7 @@ sio_write(int fd, const void *buf, size_t count) ssize_t n = write(fd, buf, count); if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) - tnt_raise(SocketError, :fd in:"write(%zd)", count); + tnt_raise(SocketError, fd, "write(%zd)", count); return n; } @@ -261,7 +256,7 @@ sio_writev(int fd, const struct iovec *iov, int iovcnt) ssize_t n = writev(fd, iov, cnt); if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) { - tnt_raise(SocketError, :fd in:"writev(%d)", iovcnt); + tnt_raise(SocketError, fd, "writev(%d)", iovcnt); } return n; } @@ -275,7 +270,7 @@ sio_sendto(int fd, const void *buf, size_t len, int flags, addrlen); if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) - tnt_raise(SocketError, :fd in:"sendto(%zd)", len); + tnt_raise(SocketError, fd, "sendto(%zd)", len); return n; } @@ -288,7 +283,7 @@ sio_recvfrom(int fd, void *buf, size_t len, int flags, addrlen); if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) - tnt_raise(SocketError, :fd in:"recvfrom(%zd)", len); + tnt_raise(SocketError, fd, "recvfrom(%zd)", len); return n; } diff --git a/src/stat.m b/src/stat.cc similarity index 97% rename from src/stat.m rename to src/stat.cc index 543e71405c3254a354d90ab8efe83c699fdff5f7..703245f6c5e2783030cb55292ebc528b6ff8e2c6 100644 --- a/src/stat.m +++ b/src/stat.cc @@ -38,7 +38,7 @@ #define SECS 5 static ev_timer timer; -struct { +struct stats { const char *name; i64 value[SECS + 1]; } *stats = NULL; @@ -66,7 +66,7 @@ stat_register(const char **name, size_t max_idx) for (int i = 0; i < max_idx; i++, name++, base++) { if (stats_size <= base) { stats_size += 1024; - stats = realloc(stats, sizeof(*stats) * stats_size); + stats = (struct stats *) realloc(stats, sizeof(*stats) * stats_size); if (stats == NULL) abort(); } diff --git a/src/tarantool.m b/src/tarantool.cc similarity index 83% rename from src/tarantool.m rename to src/tarantool.cc index 10ea0ff2e04e160197a9b5d1d458aa391c6e968e..2fccc14804baceb1257d055b193b3bec4ec36442 100644 --- a/src/tarantool.m +++ b/src/tarantool.cc @@ -58,20 +58,21 @@ #include <say.h> #include <stat.h> #include <limits.h> -#include TARANTOOL_CONFIG #include <util.h> -#include <third_party/gopt/gopt.h> +extern "C" { #include <cfg/warning.h> +#include <cfg/tarantool_box_cfg.h> +#include <third_party/gopt/gopt.h> +} /* extern "C" */ #include "tarantool_pthread.h" #include "lua/init.h" #include "memcached.h" #include "session.h" #include "box/box.h" +#include "scoped_guard.h" static pid_t master_pid; -#define DEFAULT_CFG_FILENAME "tarantool.cfg" -#define DEFAULT_CFG SYSCONF_DIR "/" DEFAULT_CFG_FILENAME const char *cfg_filename = NULL; char *cfg_filename_fullpath = NULL; char *binary_filename; @@ -84,13 +85,14 @@ static ev_signal *sigs = NULL; int snapshot_pid = 0; /* snapshot processes pid */ bool init_storage, booting = true; +extern const void *opt_def; static int core_check_config(struct tarantool_cfg *conf) { if (strindex(wal_mode_STRS, conf->wal_mode, WAL_MODE_MAX) == WAL_MODE_MAX) { - out_warning(0, "wal_mode %s is not recognized", conf->wal_mode); + out_warning(CNF_OK, "wal_mode %s is not recognized", conf->wal_mode); return -1; } return 0; @@ -110,8 +112,8 @@ title(const char *fmt, ...) cfg.memcached_port, cfg.admin_port, cfg.replication_port }; int *pptr = ports; - char *names[] = { "pri", "sec", "memc", "adm", "rpl", NULL }; - char **nptr = names; + const char *names[] = { "pri", "sec", "memc", "adm", "rpl", NULL }; + const char **nptr = names; for (; *nptr; nptr++, pptr++) if (*pptr) @@ -135,7 +137,7 @@ load_cfg(struct tarantool_cfg *conf, i32 check_rdonly) f = fopen(cfg_filename, "r"); if (f == NULL) { - out_warning(0, "can't open config `%s'", cfg_filename); + out_warning(CNF_OK, "can't open config `%s'", cfg_filename); return -1; } @@ -155,7 +157,7 @@ load_cfg(struct tarantool_cfg *conf, i32 check_rdonly) return -1; if (n_accepted == 0) { - out_warning(0, "empty configuration file '%s'", cfg_filename); + out_warning(CNF_OK, "empty configuration file '%s'", cfg_filename); return -1; } @@ -182,7 +184,7 @@ core_reload_config(const struct tarantool_cfg *old_conf, if (strcasecmp(old_conf->wal_mode, new_conf->wal_mode)) { if (strcasecmp(old_conf->wal_mode, "fsync") == 0 || strcasecmp(new_conf->wal_mode, "fsync") == 0) { - out_warning(0, "wal_mode cannot switch to/from fsync"); + out_warning(CNF_OK, "wal_mode cannot switch to/from fsync"); return -1; } say_debug("%s: wal_mode [%s] -> [%s]", @@ -215,61 +217,19 @@ reload_cfg(struct tbuf *out) struct tarantool_cfg new_cfg, aux_cfg; if (mutex == NULL) { - mutex = palloc(eter_pool, sizeof(*mutex)); + mutex = (struct mutex *) palloc(eter_pool, sizeof(*mutex)); mutex_create(mutex); } if (mutex_trylock(mutex) == true) { - out_warning(0, "Could not reload configuration: it is being reloaded right now"); + out_warning(CNF_OK, "Could not reload configuration: it is being reloaded right now"); tbuf_append(out, cfg_out->data, cfg_out->size); return -1; } - @try { - init_tarantool_cfg(&new_cfg); - init_tarantool_cfg(&aux_cfg); - - /* - Prepare a copy of the original config file - for confetti, so that it can compare the new - file with the old one when loading the new file. - Load the new file and return an error if it - contains a different value for some read-only - parameter. - */ - if (dup_tarantool_cfg(&aux_cfg, &cfg) != 0 || - load_cfg(&aux_cfg, 1) != 0) - return -1; - /* - Load the new configuration file, but - skip the check for read only parameters. - new_cfg contains only defaults and - new settings. - */ - if (fill_default_tarantool_cfg(&new_cfg) != 0 || - load_cfg(&new_cfg, 0) != 0) - return -1; - - /* Check that no default value has been changed. */ - char *diff = cmp_tarantool_cfg(&aux_cfg, &new_cfg, 1); - if (diff != NULL) { - out_warning(0, "Could not accept read only '%s' option", diff); - return -1; - } - - /* Process wal-writer-related changes. */ - if (core_reload_config(&cfg, &new_cfg) != 0) - return -1; - /* Now pass the config to the module, to take action. */ - if (box_reload_config(&cfg, &new_cfg) != 0) - return -1; - /* All OK, activate the config. */ - swap_tarantool_cfg(&cfg, &new_cfg); - tarantool_lua_load_cfg(tarantool_L, &cfg); - } - @finally { + auto scoped_guard = make_scoped_guard([&] { destroy_tarantool_cfg(&aux_cfg); destroy_tarantool_cfg(&new_cfg); @@ -277,7 +237,50 @@ reload_cfg(struct tbuf *out) tbuf_append(out, cfg_out->data, cfg_out->size); mutex_unlock(mutex); + }); + + init_tarantool_cfg(&new_cfg); + init_tarantool_cfg(&aux_cfg); + + /* + Prepare a copy of the original config file + for confetti, so that it can compare the new + file with the old one when loading the new file. + Load the new file and return an error if it + contains a different value for some read-only + parameter. + */ + if (dup_tarantool_cfg(&aux_cfg, &cfg) != 0 || + load_cfg(&aux_cfg, 1) != 0) + return -1; + /* + Load the new configuration file, but + skip the check for read only parameters. + new_cfg contains only defaults and + new settings. + */ + if (fill_default_tarantool_cfg(&new_cfg) != 0 || + load_cfg(&new_cfg, 0) != 0) + return -1; + + /* Check that no default value has been changed. */ + char *diff = cmp_tarantool_cfg(&aux_cfg, &new_cfg, 1); + if (diff != NULL) { + out_warning(CNF_OK, "Could not accept read only '%s' option", diff); + return -1; } + + /* Process wal-writer-related changes. */ + if (core_reload_config(&cfg, &new_cfg) != 0) + return -1; + + /* Now pass the config to the module, to take action. */ + if (box_reload_config(&cfg, &new_cfg) != 0) + return -1; + /* All OK, activate the config. */ + swap_tarantool_cfg(&cfg, &new_cfg); + tarantool_lua_load_cfg(tarantool_L, &cfg); + return 0; } @@ -351,8 +354,11 @@ snapshot(void) * Create snapshot from signal handler (SIGUSR1) */ static void -sig_snapshot(void) +sig_snapshot(struct ev_signal *w, int revents) { + (void) w; + (void) revents; + if (snapshot_pid) { say_warn("Snapshot process is already running," " the signal is ignored"); @@ -362,8 +368,11 @@ sig_snapshot(void) } static void -signal_cb(void) +signal_cb(struct ev_signal *w, int revents) { + (void) w; + (void) revents; + /* Terminate the main event loop */ ev_unloop(EV_A_ EVUNLOOP_ALL); } @@ -485,15 +494,15 @@ signal_init(void) exit(EX_OSERR); } - sigs = palloc(eter_pool, sizeof(ev_signal) * 4); + sigs = (ev_signal *) palloc(eter_pool, sizeof(ev_signal) * 4); memset(sigs, 0, sizeof(ev_signal) * 4); - ev_signal_init(&sigs[0], (void*)sig_snapshot, SIGUSR1); + ev_signal_init(&sigs[0], sig_snapshot, SIGUSR1); ev_signal_start(&sigs[0]); - ev_signal_init(&sigs[1], (void*)signal_cb, SIGINT); + ev_signal_init(&sigs[1], signal_cb, SIGINT); ev_signal_start(&sigs[1]); - ev_signal_init(&sigs[2], (void*)signal_cb, SIGTERM); + ev_signal_init(&sigs[2], signal_cb, SIGTERM); ev_signal_start(&sigs[2]); - ev_signal_init(&sigs[3], (void*)signal_cb, SIGHUP); + ev_signal_init(&sigs[3], signal_cb, SIGHUP); ev_signal_start(&sigs[3]); atexit(signal_free); @@ -641,29 +650,6 @@ main(int argc, char **argv) main_argc = argc; main_argv = argv; - const void *opt_def = - gopt_start(gopt_option('g', GOPT_ARG, gopt_shorts(0), - gopt_longs("cfg-get", "cfg_get"), - "=KEY", "return a value from configuration file described by KEY"), - gopt_option('k', 0, gopt_shorts(0), - gopt_longs("check-config"), - NULL, "Check configuration file for errors"), - gopt_option('c', GOPT_ARG, gopt_shorts('c'), - gopt_longs("config"), - "=FILE", "path to configuration file (default: " DEFAULT_CFG_FILENAME ")"), - gopt_option('I', 0, gopt_shorts(0), - gopt_longs("init-storage", "init_storage"), - NULL, "initialize storage (an empty snapshot file) and exit"), - gopt_option('v', 0, gopt_shorts('v'), gopt_longs("verbose"), - NULL, "increase verbosity level in log messages"), - gopt_option('B', 0, gopt_shorts('B'), gopt_longs("background"), - NULL, "redirect input/output streams to a log file and run as daemon"), - gopt_option('h', 0, gopt_shorts('h', '?'), gopt_longs("help"), - NULL, "display this help and exit"), - gopt_option('V', 0, gopt_shorts('V'), gopt_longs("version"), - NULL, "print program version and exit") - ); - void *opt = gopt_sort(&argc, (const char **)argv, opt_def); main_opt = opt; binary_filename = argv[0]; @@ -674,6 +660,7 @@ main(int argc, char **argv) printf("Build options: %s\n", BUILD_OPTIONS); printf("Compiler: %s\n", COMPILER_INFO); printf("C_FLAGS:%s\n", TARANTOOL_C_FLAGS); + printf("CXX_FLAGS:%s\n", TARANTOOL_CXX_FLAGS); return 0; } @@ -710,7 +697,7 @@ main(int argc, char **argv) } if (cfg_filename[0] != '/') { - cfg_filename_fullpath = malloc(PATH_MAX); + cfg_filename_fullpath = (char *) malloc(PATH_MAX); if (getcwd(cfg_filename_fullpath, PATH_MAX - strlen(cfg_filename) - 1) == NULL) { say_syserror("getcwd"); exit(EX_OSERR); @@ -826,9 +813,10 @@ main(int argc, char **argv) /* init process title */ if (cfg.custom_proc_title == NULL) { - custom_proc_title = ""; + custom_proc_title = (char *) palloc(eter_pool, 1); + custom_proc_title[0] = '\0'; } else { - custom_proc_title = palloc(eter_pool, strlen(cfg.custom_proc_title) + 2); + custom_proc_title = (char *) palloc(eter_pool, strlen(cfg.custom_proc_title) + 2); strcpy(custom_proc_title, "@"); strcat(custom_proc_title, cfg.custom_proc_title); } @@ -848,7 +836,7 @@ main(int argc, char **argv) signal_init(); - @try { + try { tarantool_L = tarantool_lua_init(); box_init(); memcached_init(cfg.bind_ipaddr, cfg.memcached_port); @@ -882,10 +870,11 @@ main(int argc, char **argv) ev_now_update(); start_time = ev_now(); ev_loop(0); - } @catch (tnt_Exception *e) { - [e log]; + } catch (const Exception& e) { + e.log(); panic("%s", "Fatal error, exiting loop"); } + say_crit("exiting loop"); /* freeing resources */ return 0; diff --git a/src/tbuf.m b/src/tbuf.c similarity index 91% rename from src/tbuf.m rename to src/tbuf.c index cc8612577f2c4fb061b44aa61cbab35d8381496f..28f6a65dbad030c94a787d0651ae9c0f9860bd41 100644 --- a/src/tbuf.m +++ b/src/tbuf.c @@ -60,7 +60,7 @@ tbuf_assert(const struct tbuf *b) struct tbuf * tbuf_new(struct palloc_pool *pool) { - struct tbuf *e = palloc(pool, TBUF_ALLOC_FACTOR); + struct tbuf *e = (struct tbuf *) palloc(pool, TBUF_ALLOC_FACTOR); e->size = 0; e->capacity = TBUF_ALLOC_FACTOR - sizeof(struct tbuf); e->data = (char *)e + sizeof(struct tbuf); @@ -76,7 +76,7 @@ tbuf_ensure_resize(struct tbuf *e, size_t required) tbuf_assert(e); /* Make new capacity a multiple of alloc factor. */ - size_t new_capacity = MAX(e->capacity, TBUF_ALLOC_FACTOR) * 2; + size_t new_capacity = MAX(e->capacity, (uint32_t)TBUF_ALLOC_FACTOR) * 2; while (new_capacity < e->size + required) new_capacity *= 2; @@ -86,7 +86,7 @@ tbuf_ensure_resize(struct tbuf *e, size_t required) poison(p, new_capacity); memcpy(p, e->data, e->size); poison(e->data, e->size); - e->data = p; + e->data = (char *) p; e->capacity = new_capacity; tbuf_assert(e); } @@ -103,13 +103,13 @@ tbuf_clone(struct palloc_pool *pool, const struct tbuf *orig) struct tbuf * tbuf_split(struct tbuf *orig, size_t at) { - struct tbuf *head = palloc(orig->pool, sizeof(*orig)); + struct tbuf *head = (struct tbuf *) palloc(orig->pool, sizeof(*orig)); assert(at <= orig->size); tbuf_assert(orig); head->pool = orig->pool; head->data = orig->data; head->size = head->capacity = at; - orig->data += at; + orig->data = (char *) orig->data + at; orig->capacity -= at; orig->size -= at; return head; @@ -121,7 +121,7 @@ tbuf_peek(struct tbuf *b, size_t count) void *p = b->data; tbuf_assert(b); if (count <= b->size) { - b->data += count; + b->data = (char *) b->data + count; b->size -= count; b->capacity -= count; return p; @@ -190,9 +190,9 @@ tbuf_printf(struct tbuf *b, const char *format, ...) char * tbuf_to_hex(const struct tbuf *x) { - const unsigned char *data = x->data; + const char *data = x->data; size_t size = x->size; - char *out = palloc(x->pool, size * 3 + 1); + char *out = (char *) palloc(x->pool, size * 3 + 1); out[size * 3] = 0; for (int i = 0; i < size; i++) { diff --git a/src/trace.m b/src/trace.c similarity index 100% rename from src/trace.m rename to src/trace.c diff --git a/src/util.m b/src/util.c similarity index 92% rename from src/util.m rename to src/util.c index 799d62f5efa187f7aed7f6640e5d7519e4bbcf2f..2e5c5c70761d8dda39e56641b487e3613a9bf1cb 100644 --- a/src/util.m +++ b/src/util.c @@ -42,7 +42,7 @@ #include <bfd.h> #endif /* HAVE_BFD */ -#include <fiber.h> +#include "fiber.h" #include "say.h" #ifndef HAVE_LIBC_STACK_END @@ -223,15 +223,15 @@ struct frame { char * backtrace(void *frame_, void *stack, size_t stack_size) { - struct frame *frame = frame_; - void *stack_top = stack + stack_size; + struct frame *frame = (struct frame *) frame_; + void *stack_top = (char *) stack + stack_size; void *stack_bottom = stack; char *p = backtrace_buf; size_t r, len = sizeof(backtrace_buf); while (stack_bottom <= (void *)frame && (void *)frame < stack_top) { r = snprintf(p, len, " - { frame: %p, caller: %p", - (void *)frame + 2 * sizeof(void *), frame->ret); + (char *)frame + 2 * sizeof(void *), frame->ret); if (r >= len) goto out; @@ -241,7 +241,7 @@ backtrace(void *frame_, void *stack, size_t stack_size) #ifdef HAVE_BFD struct symbol *s = addr2symbol(frame->ret); if (s != NULL) { - r = snprintf(p, len, " <%s+%"PRI_SZ"> ", s->name, frame->ret - s->addr); + r = snprintf(p, len, " <%s+%" PRI_SZ "> ", s->name, (const char *) frame->ret - (const char *) s->addr); if (r >= len) goto out; p += r; @@ -266,7 +266,7 @@ backtrace(void *frame_, void *stack, size_t stack_size) out: p += MIN(len - 1, r); *p = 0; - return backtrace_buf; + return backtrace_buf; } void @@ -279,7 +279,7 @@ print_backtrace() if (fiber == NULL || fiber_name(fiber) == NULL || strcmp(fiber_name(fiber), "sched") == 0) { stack_top = frame; /* we don't know where the system stack top is */ - stack_size = __libc_stack_end - frame; + stack_size = (const char *) __libc_stack_end - (const char *) frame; } else { stack_top = fiber->coro.stack; stack_size = fiber->coro.stack_size; @@ -308,7 +308,8 @@ static ssize_t symbol_count; int compare_symbol(const void *_a, const void *_b) { - const struct symbol *a = _a, *b = _b; + const struct symbol *a = (const struct symbol *) _a; + const struct symbol *b = (const struct symbol *) _b; if (a->addr > b->addr) return 1; if (a->addr == b->addr) @@ -340,9 +341,9 @@ symbols_load(const char *name) storage_needed = bfd_get_symtab_upper_bound(h); if (storage_needed <= 0) - goto out; + goto out; - symbol_table = malloc(storage_needed); + symbol_table = (asymbol **) malloc(storage_needed); if (symbol_table == NULL) goto out; @@ -370,7 +371,7 @@ symbols_load(const char *name) goto out; j = 0; - symbols = malloc(symbol_count * sizeof(struct symbol)); + symbols = (struct symbol *) malloc(symbol_count * sizeof(struct symbol)); if (symbols == NULL) goto out; @@ -399,7 +400,8 @@ symbols_load(const char *name) qsort(symbols, symbol_count, sizeof(struct symbol), compare_symbol); for (int j = 0; j < symbol_count - 1; j++) - symbols[j].end = MIN(symbols[j].end, symbols[j + 1].addr - 1); + symbols[j].end = MIN((char *) symbols[j].end, + (char *) symbols[j + 1].addr - 1); out: if (symbol_count == 0) diff --git a/test/box/args.result b/test/box/args.result index 8905849a1dfabc4661725cbb544d2b033f553850..5d0b6846eaa21369c784c43f4881f1347a2f0ce3 100644 --- a/test/box/args.result +++ b/test/box/args.result @@ -75,6 +75,7 @@ Target: platform <build> Build options: flags Compiler: cc C_FLAGS: flags +CXX_FLAGS: flags tarantool_box -V Tarantool 1.minor.patch-<rev>-<commit> @@ -82,6 +83,7 @@ Target: platform <build> Build options: flags Compiler: cc C_FLAGS: flags +CXX_FLAGS: flags # # A test case for Bug#726778 "Gopt broke wal_dir and snap_dir: they are no diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 982a932569cd0c8fb395dc2bd97d74c336c9b395..20f2d55fc55d30f51f208b6f43ba785c4744ebd2 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -16,16 +16,3 @@ add_executable(bitset_iterator_test bitset_iterator.c) target_link_libraries(bitset_iterator_test bitset) add_executable(bitset_index_test bitset_index.c) target_link_libraries(bitset_index_test bitset) - -add_executable(objc_finally objc_finally.m) -include_directories(${LIBOBJC_INCLUDE_DIR}) -add_executable(objc_catchcxx objc_catchcxx.m) - -add_dependencies(objc_finally build_bundled_libs) -add_dependencies(objc_catchcxx build_bundled_libs) - -target_link_libraries(objc_finally ${LIBOBJC_LIBRARIES} -lm -pthread) -target_link_libraries(objc_catchcxx ${LIBOBJC_LIBRARIES} ${LUAJIT_LIB} -lm -pthread) -if (TARGET_OS_LINUX OR TARGET_OS_DEBIAN_FREEBSD) - target_link_libraries(objc_catchcxx dl) -endif() diff --git a/test/unit/objc_catchcxx.m b/test/unit/objc_catchcxx.m deleted file mode 100644 index 23fed813b15e27820b2c67d961da6e595a9e8160..0000000000000000000000000000000000000000 --- a/test/unit/objc_catchcxx.m +++ /dev/null @@ -1,17 +0,0 @@ -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" - -int main() -{ - lua_State *L = luaL_newstate(); - luaL_openlibs(L); - @try { - luaL_error(L, "test"); - } @catch (id allOthers) { - printf("exception handled\n"); - } - lua_close(L); - - return 0; -} diff --git a/test/unit/objc_catchcxx.result b/test/unit/objc_catchcxx.result deleted file mode 100644 index 761f3a20404e3a9aed380cfe9f631e6d231671f8..0000000000000000000000000000000000000000 --- a/test/unit/objc_catchcxx.result +++ /dev/null @@ -1 +0,0 @@ -exception handled diff --git a/test/unit/objc_catchcxx.test b/test/unit/objc_catchcxx.test deleted file mode 100644 index 13f381fcb7bcb15f5df824b7022269be6f46bbc1..0000000000000000000000000000000000000000 --- a/test/unit/objc_catchcxx.test +++ /dev/null @@ -1 +0,0 @@ -run_test("objc_catchcxx") diff --git a/test/unit/objc_finally.m b/test/unit/objc_finally.m deleted file mode 100644 index 18cf5c62b5838415226380e92e968d313023f6af..0000000000000000000000000000000000000000 --- a/test/unit/objc_finally.m +++ /dev/null @@ -1,46 +0,0 @@ -#include <stdio.h> -#include <objc/Object.h> -#include <objc/runtime.h> - -@interface Exception: Object { -} -+ (id) new; -@end - -@implementation Exception -+ (id) new -{ - return class_createInstance(self, 0); -} -@end - -void -throw_exception(void) -{ - printf("throw\n"); - @throw [Exception new]; -} - -void -test(void) -{ - @try { - throw_exception(); - } @finally { - printf("internal finally\n"); - } -} - -int -main(int ac, char **av) -{ - printf("start\n"); - @try { - test(); - } @catch(id e) { - printf("catch\n"); - } @finally { - printf("external finally\n"); - } - return 0; -} diff --git a/test/unit/objc_finally.result b/test/unit/objc_finally.result deleted file mode 100644 index 1d09f8b41372dfdb1c732e6c522080975571ae31..0000000000000000000000000000000000000000 --- a/test/unit/objc_finally.result +++ /dev/null @@ -1,5 +0,0 @@ -start -throw -internal finally -catch -external finally diff --git a/test/unit/objc_finally.test b/test/unit/objc_finally.test deleted file mode 100644 index 65770394cce04b504544ad9578f2c2203990773c..0000000000000000000000000000000000000000 --- a/test/unit/objc_finally.test +++ /dev/null @@ -1 +0,0 @@ -run_test("objc_finally") diff --git a/third_party/qsort_arg.h b/third_party/qsort_arg.h index 8a94e1e3b4889257d845d365cd5b9677581e268a..6b9fe44cc012223a8ebeac0dc8c1e8fe8e98ef56 100644 --- a/third_party/qsort_arg.h +++ b/third_party/qsort_arg.h @@ -3,6 +3,14 @@ #include <sys/types.h> +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + void qsort_arg(void *a, size_t n, size_t es, int (*cmp)(const void *a, const void *b, void *arg), void *arg); +#if defined(__cplusplus) +} +#endif /* defined(__cplusplus) */ + #endif diff --git a/third_party/sptree.h b/third_party/sptree.h index b3d74e78e933efdad95f9edbd115be2b65e2108a..e310710c5391ddce59610047f5bc2a80e3780c32 100644 --- a/third_party/sptree.h +++ b/third_party/sptree.h @@ -34,6 +34,10 @@ #include <third_party/qsort_arg.h> +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + #ifndef SPTREE_NODE_SELF /* * user could suggest pointer's storage himself @@ -46,8 +50,8 @@ typedef struct sptree_node_pointers { u_int32_t right; } sptree_node_pointers; -#define GET_SPNODE_LEFT(snp) ( (snp)->left ) -#define SET_SPNODE_LEFT(snp, v) (snp)->left = (v) +#define GET_SPNODE_LEFT(snp) ( (snp)->left ) +#define SET_SPNODE_LEFT(snp, v) (snp)->left = (v) #define GET_SPNODE_RIGHT(snp) ( (snp)->right ) #define SET_SPNODE_RIGHT(snp, v) (snp)->right = (v) @@ -63,7 +67,7 @@ typedef struct sptree_node_pointers { #define _GET_SPNODE_RIGHT(n) GET_SPNODE_RIGHT( t->lrpointers + (n) ) #define _SET_SPNODE_RIGHT(n, v) SET_SPNODE_RIGHT( t->lrpointers + (n), (v) ) -#define ITHELEM(t, i) ( (t)->members + (t)->elemsize * (i) ) +#define ITHELEM(t, i) ( (char *) (t)->members + (t)->elemsize * (i) ) #define ELEMIDX(t, e) ( ((e) - (t)->members) / (t)->elemsize ) /* @@ -71,8 +75,8 @@ typedef struct sptree_node_pointers { * be unique across all definitions. * * Methods: - * void sptree_NAME_init(sptree_NAME *tree, size_t elemsize, void *array, - * spnode_t array_len, spnode_t array_size, + * void sptree_NAME_init(sptree_NAME *tree, size_t elemsize, void *array, + * spnode_t array_len, spnode_t array_size, * int (*compare)(const void *key, const void *elem, void *arg), * int (*elemcompare)(const void *e1, const void *e2, void *arg), * void *arg) @@ -84,9 +88,9 @@ typedef struct sptree_node_pointers { * spnode_t sptree_NAME_walk(sptree_NAME *t, void* array, spnode_t limit, spnode_t offset) * void sptree_NAME_walk_cb(sptree_NAME *t, int (*cb)(void* cb_arg, void* elem), void *cb_arg) * - * sptree_NAME_iterator* sptree_NAME_iterator_init(sptree_NAME *t) + * sptree_NAME_iterator* sptree_NAME_iterator_init(sptree_NAME *t) * void sptree_NAME_iterator_init_set(sptree_NAME *t, sptree_NAME_iterator **iterator, void *start) - * sptree_NAME_iterator* sptree_NAME_iterator_reverse_init(sptree_NAME *t) + * sptree_NAME_iterator* sptree_NAME_iterator_reverse_init(sptree_NAME *t) * void sptree_NAME_iterator_reverse_init_set(sptree_NAME *t, sptree_NAME_iterator **iterator, void *start) * void sptree_NAME_iterator_free(sptree_NAME_iterator *i) * @@ -159,7 +163,8 @@ sptree_##name##_init(sptree_##name *t, size_t elemsize, void *m, if (t->members == NULL) \ t->members = realloc(NULL, elemsize * t->ntotal); \ } \ - t->lrpointers = realloc(NULL, sizeof(sptree_node_pointers) * t->ntotal); \ + t->lrpointers = (sptree_node_pointers *) realloc(NULL, \ + sizeof(sptree_node_pointers) * t->ntotal); \ \ if (t->nmember == 1) { \ t->root = 0; \ @@ -181,16 +186,16 @@ sptree_##name##_destroy(sptree_##name *t) { \ /** Nodes in the garbage list have a loop on their right link. */ \ static inline bool \ -sptree_##name##_node_is_deleted(sptree_##name *t, spnode_t node) { \ +sptree_##name##_node_is_deleted(const sptree_##name *t, spnode_t node) { \ \ return _GET_SPNODE_RIGHT(node) == node; \ } \ \ static inline void* \ -sptree_##name##_find(sptree_##name *t, void *k) { \ +sptree_##name##_find(const sptree_##name *t, void *k) { \ spnode_t node = t->root; \ while(node != SPNIL) { \ - int r = t->compare(k, ITHELEM(t, node), t->arg); \ + int r = t->compare(k, ITHELEM(t, node), t->arg); \ if (r > 0) { \ node = _GET_SPNODE_RIGHT(node); \ } else if (r < 0) { \ @@ -203,7 +208,7 @@ sptree_##name##_find(sptree_##name *t, void *k) { } \ \ static inline void* \ -sptree_##name##_first(sptree_##name *t) { \ +sptree_##name##_first(const sptree_##name *t) { \ spnode_t node = t->root; \ spnode_t first = SPNIL; \ while (node != SPNIL) { \ @@ -216,7 +221,7 @@ sptree_##name##_first(sptree_##name *t) { } \ \ static inline void* \ -sptree_##name##_last(sptree_##name *t) { \ +sptree_##name##_last(const sptree_##name *t) { \ spnode_t node = t->root; \ spnode_t last = SPNIL; \ while (node != SPNIL) { \ @@ -229,7 +234,7 @@ sptree_##name##_last(sptree_##name *t) { } \ \ static inline void* \ -sptree_##name##_random(sptree_##name *t, spnode_t rnd) { \ +sptree_##name##_random(const sptree_##name *t, spnode_t rnd) { \ for (spnode_t i = 0; i < t->size; i++, rnd++) { \ rnd %= t->nmember; \ if (!sptree_##name##_node_is_deleted(t, rnd)) \ @@ -258,7 +263,7 @@ sptree_##name##_get_place(sptree_##name *t) { if (t->nmember >= t->ntotal) { \ t->ntotal *= 2; \ t->members = realloc(t->members, t->ntotal * t->elemsize); \ - t->lrpointers = realloc(t->lrpointers, \ + t->lrpointers = (sptree_node_pointers *) realloc(t->lrpointers, \ t->ntotal * sizeof(sptree_node_pointers)); \ } \ \ @@ -498,7 +503,7 @@ sptree_##name##_walk(sptree_##name *t, void* array, spnode_t limit, spnode_t off while( count < offset + limit && level >= 0 ) { \ \ if (count >= offset) \ - memcpy(array + (count-offset) * t->elemsize, \ + memcpy((char *) array + (count-offset) * t->elemsize, \ ITHELEM(t, stack[level]), t->elemsize); \ count++; \ \ @@ -543,7 +548,7 @@ sptree_##name##_walk_cb(sptree_##name *t, int (*cb)(void*, void*), void *cb_arg } \ \ typedef struct sptree_##name##_iterator { \ - sptree_##name *t; \ + const sptree_##name *t; \ int level; \ int max_depth; \ spnode_t stack[0]; \ @@ -551,7 +556,7 @@ typedef struct sptree_##name##_iterator { \ static inline sptree_##name##_iterator * \ sptree_##name##_iterator_alloc(sptree_##name *t) { \ - sptree_##name##_iterator *i = \ + sptree_##name##_iterator *i = (sptree_##name##_iterator *) \ realloc(NULL, sizeof(*i) + sizeof(spnode_t) * (t->max_depth + 1)); \ i->t = t; \ i->level = 0; \ @@ -576,13 +581,14 @@ sptree_##name##_iterator_init(sptree_##name *t) { } \ \ static inline void \ -sptree_##name##_iterator_init_set(sptree_##name *t, sptree_##name##_iterator **i, \ +sptree_##name##_iterator_init_set(const sptree_##name *t, sptree_##name##_iterator **i, \ void *k) { \ spnode_t node; \ int lastLevelEq = -1, cmp; \ \ if ((*i) == NULL || t->max_depth > (*i)->max_depth) \ - *i = realloc(*i, sizeof(**i) + sizeof(spnode_t) * (t->max_depth + 31)); \ + *i = (sptree_##name##_iterator *) realloc(*i, sizeof(**i) + \ + sizeof(spnode_t) * (t->max_depth + 31)); \ \ (*i)->t = t; \ (*i)->level = -1; \ @@ -633,13 +639,14 @@ sptree_##name##_iterator_reverse_init(sptree_##name *t) { } \ \ static inline void \ -sptree_##name##_iterator_reverse_init_set(sptree_##name *t, sptree_##name##_iterator **i, \ - void *k) { \ +sptree_##name##_iterator_reverse_init_set(const sptree_##name *t, \ + sptree_##name##_iterator **i, void *k) { \ spnode_t node; \ int lastLevelEq = -1, cmp; \ \ if ((*i) == NULL || t->max_depth > (*i)->max_depth) \ - *i = realloc(*i, sizeof(**i) + sizeof(spnode_t) * (t->max_depth + 31)); \ + *i = (sptree_##name##_iterator *) realloc(*i, sizeof(**i) + \ + sizeof(spnode_t) * (t->max_depth + 31)); \ \ (*i)->t = t; \ (*i)->level = -1; \ @@ -699,7 +706,7 @@ sptree_##name##_iterator_next(sptree_##name##_iterator *i) { \ if (i == NULL) return NULL; \ \ - sptree_##name *t = i->t; \ + const sptree_##name *t = i->t; \ spnode_t returnNode = sptree_##name##_iterator_next_node(i); \ \ if (returnNode == SPNIL) return NULL; \ @@ -719,7 +726,7 @@ sptree_##name##_iterator_reverse_next(sptree_##name##_iterator *i) { \ if (i == NULL) return NULL; \ \ - sptree_##name *t = i->t; \ + const sptree_##name *t = i->t; \ spnode_t returnNode = sptree_##name##_iterator_next_node(i); \ \ if (returnNode == SPNIL) return NULL; \ @@ -736,3 +743,7 @@ sptree_##name##_iterator_reverse_next(sptree_##name##_iterator *i) { * vim: ts=4 sts=4 et */ #endif + +#if defined(__cplusplus) +} +#endif /* defined(__cplusplus) */