You've already forked mariadb-connector-c
mirror of
https://github.com/mariadb-corporation/mariadb-connector-c.git
synced 2025-08-08 14:02:17 +03:00
Merge branch '3.3' into 3.4
This commit is contained in:
@@ -16,8 +16,6 @@ IF(COMMAND CMAKE_POLICY)
|
||||
ENDIF()
|
||||
|
||||
|
||||
PROJECT(mariadb-connector-c C)
|
||||
|
||||
# Is C/C built as subproject?
|
||||
get_directory_property(IS_SUBPROJECT PARENT_DIRECTORY)
|
||||
|
||||
@@ -25,11 +23,29 @@ get_directory_property(IS_SUBPROJECT PARENT_DIRECTORY)
|
||||
SET_PROPERTY(DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
|
||||
FOREACH(V WITH_MYSQLCOMPAT WITH_MSI WITH_SIGNCODE WITH_RTC WITH_UNIT_TESTS
|
||||
WITH_DYNCOL WITH_EXTERNAL_ZLIB WITH_CURL WITH_SQLITE WITH_SSL WITH_ICONV
|
||||
DEFAULT_CHARSET INSTALL_LAYOUT WITH_TEST_SRCPKG
|
||||
DEFAULT_CHARSET INSTALL_LAYOUT WITH_TEST_SRCPKG WITH_BOOST_CONTEXT
|
||||
DEFAULT_SSL_VERIFY_SERVER_CERT)
|
||||
SET(${V} ${${OPT}${V}})
|
||||
ENDFOREACH()
|
||||
|
||||
MACRO(ADD_OPTION _name _text _default)
|
||||
IF(NOT DEFINED ${_name})
|
||||
OPTION(${OPT}${_name} "${_text}" "${_default}")
|
||||
ELSE()
|
||||
OPTION(${OPT}${_name} "${_text}" "${${_name}}")
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
ADD_OPTION(WITH_BOOST_CONTEXT
|
||||
"Use Boost::Context for the non-blocking API on platforms without native implementation"
|
||||
OFF)
|
||||
|
||||
IF(WITH_BOOST_CONTEXT)
|
||||
PROJECT(mariadb-connector-c LANGUAGES C CXX)
|
||||
ELSE()
|
||||
PROJECT(mariadb-connector-c C)
|
||||
ENDIF()
|
||||
|
||||
SET(CC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
SET(CC_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
@@ -41,14 +57,6 @@ MATH(EXPR MARIADB_PACKAGE_VERSION_ID "${CPACK_PACKAGE_VERSION_MAJOR} * 10000 +
|
||||
${CPACK_PACKAGE_VERSION_MINOR} * 100 +
|
||||
${CPACK_PACKAGE_VERSION_PATCH}")
|
||||
|
||||
MACRO(ADD_OPTION _name _text _default)
|
||||
IF(NOT DEFINED ${_name})
|
||||
OPTION(${OPT}${_name} "${_text}" "${_default}")
|
||||
ELSE()
|
||||
OPTION(${OPT}${_name} "${_text}" "${${_name}}")
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
### Options ###
|
||||
IF(NOT WIN32)
|
||||
ADD_OPTION(WITH_MYSQLCOMPAT "creates libmysql* symbolic links" OFF)
|
||||
@@ -367,6 +375,11 @@ IF(NOT WITH_SSL STREQUAL "OFF")
|
||||
MARK_AS_ADVANCED(SSL_SOURCES)
|
||||
ENDIF()
|
||||
|
||||
IF(WITH_BOOST_CONTEXT)
|
||||
FIND_PACKAGE(Boost 1.40 COMPONENTS context REQUIRED)
|
||||
SET(SYSTEM_LIBS ${SYSTEM_LIBS} ${Boost_LIBRARIES})
|
||||
ENDIF()
|
||||
|
||||
SET(ENABLED_LOCAL_INFILE "AUTO" CACHE STRING "If we should should enable LOAD DATA LOCAL by default (OFF/ON/AUTO)")
|
||||
MARK_AS_ADVANCED(ENABLED_LOCAL_INFILE)
|
||||
IF (ENABLED_LOCAL_INFILE MATCHES "^(0|FALSE)$")
|
||||
|
@@ -43,6 +43,9 @@ CHECK_INCLUDE_FILES (sys/types.h HAVE_SYS_TYPES_H)
|
||||
CHECK_INCLUDE_FILES (sys/stat.h HAVE_SYS_STAT_H)
|
||||
CHECK_INCLUDE_FILES (sys/un.h HAVE_SYS_UN_H)
|
||||
CHECK_INCLUDE_FILES (unistd.h HAVE_UNISTD_H)
|
||||
IF(WITH_BOOST_CONTEXT)
|
||||
CHECK_INCLUDE_FILE_CXX (boost/fiber/context.hpp HAVE_BOOST_CONTEXT_H)
|
||||
ENDIF()
|
||||
|
||||
IF(APPLE)
|
||||
SET(CMAKE_REQUIRED_DEFINITIONS -D_XOPEN_SOURCE=600)
|
||||
|
@@ -50,7 +50,7 @@ FUNCTION(REGISTER_PLUGIN)
|
||||
endif()
|
||||
|
||||
if(NOT ${CC_PLUGIN_DEFAULT} STREQUAL "OFF")
|
||||
set(PLUGIN_${CC_PLUGIN_TARGET}_TYPE ${CC_PLUGIN_TYPE})
|
||||
set(PLUGIN_${CC_PLUGIN_TARGET}_TYPE ${CC_PLUGIN_TYPE} PARENT_SCOPE)
|
||||
|
||||
if(${CC_PLUGIN_DEFAULT} MATCHES "DYNAMIC")
|
||||
|
||||
|
@@ -29,6 +29,7 @@
|
||||
#cmakedefine HAVE_SYS_UN_H 1
|
||||
#cmakedefine HAVE_UNISTD_H 1
|
||||
#cmakedefine HAVE_UCONTEXT_H 1
|
||||
#cmakedefine HAVE_BOOST_CONTEXT_H 1
|
||||
|
||||
/*
|
||||
* function definitions - processed in LibmysqlFunctions.txt
|
||||
|
@@ -32,12 +32,20 @@
|
||||
#define MY_CONTEXT_USE_X86_64_GCC_ASM
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 3 && defined(__i386__)
|
||||
#define MY_CONTEXT_USE_I386_GCC_ASM
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 3 && defined(__aarch64__)
|
||||
#define MY_CONTEXT_USE_AARCH64_GCC_ASM
|
||||
#elif defined(HAVE_BOOST_CONTEXT_H)
|
||||
#define MY_CONTEXT_USE_BOOST_CONTEXT
|
||||
#elif defined(HAVE_UCONTEXT_H)
|
||||
#define MY_CONTEXT_USE_UCONTEXT
|
||||
#else
|
||||
#define MY_CONTEXT_DISABLE
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef MY_CONTEXT_USE_WIN32_FIBERS
|
||||
struct my_context {
|
||||
void (*user_func)(void *);
|
||||
@@ -107,6 +115,49 @@ struct my_context {
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef MY_CONTEXT_USE_AARCH64_GCC_ASM
|
||||
#include <stdint.h>
|
||||
|
||||
struct my_context {
|
||||
uint64_t save[22];
|
||||
void *stack_top;
|
||||
void *stack_bot;
|
||||
#ifdef HAVE_VALGRIND
|
||||
unsigned int valgrind_stack_id;
|
||||
#endif
|
||||
#ifndef DBUG_OFF
|
||||
void *dbug_state;
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef MY_CONTEXT_USE_BOOST_CONTEXT
|
||||
/*
|
||||
boost::context is a C++-library that provides a portable co-routine fallback
|
||||
for architectures that lack a native my_context implementation, and which is
|
||||
available on some platforms where ucontext is not (ucontext has been
|
||||
deprecated in Posix).
|
||||
|
||||
Since boost::context is in C++, the implementation details must be put into
|
||||
a separate source file ma_boost_context.cc and hidden in an opaque void *.
|
||||
*/
|
||||
struct my_context {
|
||||
/* Pointer to state that uses C++-types and cannot be compiled in C. */
|
||||
void *internal_context;
|
||||
void *stack;
|
||||
size_t stack_size;
|
||||
#ifndef DBUG_OFF
|
||||
void *dbug_state;
|
||||
#endif
|
||||
int active;
|
||||
#ifdef HAVE_VALGRIND
|
||||
unsigned int valgrind_stack_id;
|
||||
#endif
|
||||
};
|
||||
#endif /* MY_CONTEXT_USE_BOOST_CONTEXT */
|
||||
|
||||
|
||||
#ifdef MY_CONTEXT_DISABLE
|
||||
struct my_context {
|
||||
int dummy;
|
||||
@@ -240,3 +291,7 @@ struct mysql_async_context {
|
||||
*/
|
||||
struct my_context async_context;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -298,7 +298,7 @@ MESSAGE(STATUS "SYSTEM_LIBS: ${SYSTEM_LIBS}")
|
||||
INCLUDE_DIRECTORIES(${LIBMARIADB_PLUGIN_INCLUDES})
|
||||
ADD_DEFINITIONS(${LIBMARIADB_PLUGIN_DEFS})
|
||||
FOREACH(plugin ${PLUGINS_STATIC})
|
||||
SET(EXTERNAL_PLUGINS "${EXTERNAL_PLUGINS} extern struct st_mysql_client_plugin ${plugin}_client_plugin;\n")
|
||||
SET(EXTERNAL_PLUGINS "${EXTERNAL_PLUGINS} extern struct st_mysql_client_plugin_${PLUGIN_${plugin}_TYPE} ${plugin}_client_plugin;\n")
|
||||
SET(BUILTIN_PLUGINS "${BUILTIN_PLUGINS} (struct st_mysql_client_plugin *)&${plugin}_client_plugin,\n")
|
||||
ENDFOREACH()
|
||||
CONFIGURE_FILE(${CC_SOURCE_DIR}/libmariadb/ma_client_plugin.c.in
|
||||
@@ -394,6 +394,9 @@ IF(WITH_DYNCOL)
|
||||
ENDIF()
|
||||
|
||||
SET(LIBMARIADB_SOURCES ${LIBMARIADB_SOURCES} mariadb_async.c ma_context.c)
|
||||
IF(WITH_BOOST_CONTEXT)
|
||||
SET(LIBMARIADB_SOURCES ${LIBMARIADB_SOURCES} ma_boost_context.cc)
|
||||
ENDIF()
|
||||
SET(MARIADB_LIB_SYMBOLS ${MARIADB_LIB_SYMBOLS} ${MARIADB_NONBLOCK_SYMBOLS})
|
||||
|
||||
INCLUDE(${CC_SOURCE_DIR}/cmake/export.cmake)
|
||||
|
117
libmariadb/ma_boost_context.cc
Normal file
117
libmariadb/ma_boost_context.cc
Normal file
@@ -0,0 +1,117 @@
|
||||
#include "ma_config.h"
|
||||
#include "mysql.h"
|
||||
#include "ma_context.h"
|
||||
|
||||
#ifdef MY_CONTEXT_USE_BOOST_CONTEXT
|
||||
|
||||
#include <boost/fiber/context.hpp>
|
||||
|
||||
namespace ctx=boost::context;
|
||||
|
||||
struct my_context_intern {
|
||||
ctx::fiber parent, coro;
|
||||
|
||||
void *stack_top(const my_context *c) {
|
||||
return (unsigned char *)(c->stack) + c->stack_size;
|
||||
}
|
||||
|
||||
/* A StackAlloc for ctx::fiber that reuses our stack. */
|
||||
struct my_stack_alloc {
|
||||
typedef ctx::stack_traits traits_type;
|
||||
my_context *c;
|
||||
my_stack_alloc(my_context *c_arg) : c(c_arg) { };
|
||||
ctx::stack_context allocate() {
|
||||
ctx::stack_context sctx;
|
||||
sctx.size= c->stack_size;
|
||||
sctx.sp= ((my_context_intern *)c->internal_context)->stack_top(c);
|
||||
#if defined(BOOST_USE_VALGRIND) && defined(HAVE_VALGRIND)
|
||||
sctx.valgrind_stack_id= c->valgrind_stack_id;
|
||||
#endif
|
||||
return sctx;
|
||||
}
|
||||
void deallocate(ctx::stack_context & sctx) {
|
||||
/* Empty, we will re-use the stack. */
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
extern "C"
|
||||
int
|
||||
my_context_spawn(struct my_context *c, void (*f)(void *), void *d)
|
||||
{
|
||||
my_context_intern *ci= (my_context_intern *)c->internal_context;
|
||||
ci->coro= ctx::fiber(std::allocator_arg, my_context_intern::my_stack_alloc(c),
|
||||
[c, f, d](ctx::fiber && parent) {
|
||||
my_context_intern *ci= (my_context_intern *)c->internal_context;
|
||||
ci->parent= std::move(parent);
|
||||
(*f)(d);
|
||||
c->active= 0;
|
||||
return std::move(ci->parent);
|
||||
});
|
||||
c->active= 1;
|
||||
ci->coro= std::move(ci->coro).resume();
|
||||
return c->active;
|
||||
}
|
||||
|
||||
|
||||
extern "C"
|
||||
int
|
||||
my_context_continue(struct my_context *c)
|
||||
{
|
||||
if (!c->active)
|
||||
return 0;
|
||||
my_context_intern *ci= (my_context_intern *)c->internal_context;
|
||||
ci->coro= std::move(ci->coro).resume();
|
||||
return c->active;
|
||||
}
|
||||
|
||||
|
||||
extern "C"
|
||||
int
|
||||
my_context_yield(struct my_context *c)
|
||||
{
|
||||
if (!c->active)
|
||||
return -1;
|
||||
my_context_intern *ci= (my_context_intern *)c->internal_context;
|
||||
ci->parent= std::move(ci->parent).resume();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern "C"
|
||||
int
|
||||
my_context_init(struct my_context *c, size_t stack_size)
|
||||
{
|
||||
memset(c, 0, sizeof(*c));
|
||||
if (!(c->stack= malloc(stack_size)))
|
||||
return -1; /* Out of memory */
|
||||
if (!(c->internal_context= new my_context_intern))
|
||||
{
|
||||
free(c->stack);
|
||||
return -1;
|
||||
}
|
||||
c->stack_size= stack_size;
|
||||
#ifdef HAVE_VALGRIND
|
||||
c->valgrind_stack_id=
|
||||
VALGRIND_STACK_REGISTER(c->stack, ((unsigned char *)(c->stack))+stack_size);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern "C"
|
||||
void
|
||||
my_context_destroy(struct my_context *c)
|
||||
{
|
||||
delete (my_context_intern *)c->internal_context;
|
||||
if (c->stack)
|
||||
{
|
||||
#ifdef HAVE_VALGRIND
|
||||
VALGRIND_STACK_DEREGISTER(c->valgrind_stack_id);
|
||||
#endif
|
||||
free(c->stack);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MY_CONTEXT_USE_BOOST_CONTEXT */
|
@@ -21,6 +21,9 @@
|
||||
swapcontext().
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ma_global.h"
|
||||
#include "ma_string.h"
|
||||
#include "ma_context.h"
|
||||
@@ -167,9 +170,6 @@ my_context_destroy(struct my_context *c)
|
||||
save them as we cannot know if we will yield or not in advance).
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
Layout of saved registers etc.
|
||||
Since this is accessed through gcc inline assembler, it is simpler to just
|
||||
@@ -204,7 +204,7 @@ my_context_spawn(struct my_context *c, void (*f)(void *), void *d)
|
||||
(
|
||||
"movq %%rsp, (%[save])\n\t"
|
||||
"movq %[stack], %%rsp\n\t"
|
||||
#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4 && !defined(__INTEL_COMPILER)
|
||||
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) || __clang__) && !defined(__INTEL_COMPILER)
|
||||
/*
|
||||
This emits a DWARF DW_CFA_undefined directive to make the return address
|
||||
undefined. This indicates that this is the top of the stack frame, and
|
||||
@@ -408,9 +408,6 @@ my_context_destroy(struct my_context *c)
|
||||
save them as we cannot know if we will yield or not in advance).
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
Layout of saved registers etc.
|
||||
Since this is accessed through gcc inline assembler, it is simpler to just
|
||||
@@ -443,7 +440,7 @@ my_context_spawn(struct my_context *c, void (*f)(void *), void *d)
|
||||
(
|
||||
"movl %%esp, (%[save])\n\t"
|
||||
"movl %[stack], %%esp\n\t"
|
||||
#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4 && !defined(__INTEL_COMPILER)
|
||||
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) || __clang__) && !defined(__INTEL_COMPILER)
|
||||
/*
|
||||
This emits a DWARF DW_CFA_undefined directive to make the return address
|
||||
undefined. This indicates that this is the top of the stack frame, and
|
||||
@@ -625,6 +622,334 @@ my_context_destroy(struct my_context *c)
|
||||
#endif /* MY_CONTEXT_USE_I386_GCC_ASM */
|
||||
|
||||
|
||||
#ifdef MY_CONTEXT_USE_AARCH64_GCC_ASM
|
||||
/*
|
||||
GCC-aarch64 (arm64) implementation of my_context.
|
||||
|
||||
This is slightly optimized in the common case where we never yield
|
||||
(eg. fetch next row and it is already fully received in buffer). In this
|
||||
case we do not need to restore registers at return (though we still need to
|
||||
save them as we cannot know if we will yield or not in advance).
|
||||
*/
|
||||
|
||||
/*
|
||||
Layout of saved registers etc.
|
||||
Since this is accessed through gcc inline assembler, it is simpler to just
|
||||
use numbers than to try to define nice constants or structs.
|
||||
|
||||
0 0 x19
|
||||
1 8 x20
|
||||
2 16 x21
|
||||
...
|
||||
9 72 x28
|
||||
10 80 x29 (frame pointer)
|
||||
11 88 sp
|
||||
12 96 d8
|
||||
13 104 d9
|
||||
...
|
||||
19 152 d15
|
||||
20 160 pc for done
|
||||
21 168 pc for yield/continue
|
||||
*/
|
||||
|
||||
int
|
||||
my_context_spawn(struct my_context *c, void (*f)(void *), void *d)
|
||||
{
|
||||
register int ret asm("w0");
|
||||
register void (*f_reg)(void *) asm("x1") = f;
|
||||
register void *d_reg asm("x2") = d;
|
||||
register void *stack asm("x13") = c->stack_top;
|
||||
/* Need this in callee-save register to preserve in function call. */
|
||||
register const uint64_t *save asm("x19") = &c->save[0];
|
||||
|
||||
/*
|
||||
There are a total of 20 callee-save registers (including frame pointer and
|
||||
link register) we need to save and restore when suspending and continuing,
|
||||
plus stack pointer sp and program counter pc.
|
||||
|
||||
However, if we never suspend, the user-supplied function will in any case
|
||||
restore the callee-save registers, so we can avoid restoring them in this
|
||||
case.
|
||||
*/
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"mov x10, sp\n\t"
|
||||
"mov sp, %[stack]\n\t"
|
||||
#if !defined(__INTEL_COMPILER)
|
||||
/*
|
||||
This emits a DWARF DW_CFA_undefined directive to make the return address
|
||||
(UNW_AARCH64_X30) undefined. This indicates that this is the top of the
|
||||
stack frame, and helps tools that use DWARF stack unwinding to obtain
|
||||
stack traces. (I use numeric constant to avoid a dependency on libdwarf
|
||||
includes).
|
||||
*/
|
||||
".cfi_escape 0x07, 30\n\t"
|
||||
#endif
|
||||
"stp x19, x20, [%[save], #0]\n\t"
|
||||
"stp x21, x22, [%[save], #16]\n\t"
|
||||
"stp x23, x24, [%[save], #32]\n\t"
|
||||
"stp x25, x26, [%[save], #48]\n\t"
|
||||
"stp x27, x28, [%[save], #64]\n\t"
|
||||
"stp x29, x10, [%[save], #80]\n\t"
|
||||
"stp d8, d9, [%[save], #96]\n\t"
|
||||
"stp d10, d11, [%[save], #112]\n\t"
|
||||
"stp d12, d13, [%[save], #128]\n\t"
|
||||
"stp d14, d15, [%[save], #144]\n\t"
|
||||
"adr x10, 1f\n\t"
|
||||
"adr x11, 2f\n\t"
|
||||
"stp x10, x11, [%[save], #160]\n\t"
|
||||
|
||||
/* Need this in x0 to follow calling convention. */
|
||||
"mov x0, %[d]\n\t"
|
||||
"blr %[f]\n\t"
|
||||
"ldr x11, [%[save], #160]\n\t"
|
||||
"br x11\n"
|
||||
/*
|
||||
Come here when operation is done.
|
||||
We do not need to restore callee-save registers, as the called function
|
||||
will do this for us if needed.
|
||||
*/
|
||||
"1:\n\t"
|
||||
"ldr x10, [%[save], #88]\n\t"
|
||||
"mov sp, x10\n\t"
|
||||
"mov %w[ret], #0\n\t"
|
||||
"b 3f\n"
|
||||
/* Come here when operation was suspended. */
|
||||
"2:\n\t"
|
||||
"mov %w[ret], #1\n"
|
||||
"3:\n"
|
||||
: [ret] "=r" (ret),
|
||||
[f] "+r" (f_reg),
|
||||
[d] "+r" (d_reg),
|
||||
[stack] "+r" (stack)
|
||||
: [save] "r" (save)
|
||||
: "x3", "x4", "x5", "x6", "x7",
|
||||
"x9", "x10", "x11", "x14", "x15", "x18", "x30",
|
||||
"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
|
||||
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
|
||||
"v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
|
||||
"memory", "cc"
|
||||
);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
my_context_continue(struct my_context *c)
|
||||
{
|
||||
register int ret asm("w0");
|
||||
/* Need this in callee-save register to preserve in function call. */
|
||||
register const uint64_t *save asm("x19") = &c->save[0];
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"ldp x13, x11, [%[save], #0]\n\t"
|
||||
"stp x19, x20, [%[save], #0]\n\t"
|
||||
/* x19 is %[save], delay restoring it until %[save] is no longer needed. */
|
||||
"mov x20, x11\n\t"
|
||||
|
||||
"ldp x10, x11, [%[save], #16]\n\t"
|
||||
"stp x21, x22, [%[save], #16]\n\t"
|
||||
"mov x21, x10\n\t"
|
||||
"mov x22, x11\n\t"
|
||||
|
||||
"ldp x10, x11, [%[save], #32]\n\t"
|
||||
"stp x23, x24, [%[save], #32]\n\t"
|
||||
"mov x23, x10\n\t"
|
||||
"mov x24, x11\n\t"
|
||||
|
||||
"ldp x10, x11, [%[save], #48]\n\t"
|
||||
"stp x25, x26, [%[save], #48]\n\t"
|
||||
"mov x25, x10\n\t"
|
||||
"mov x26, x11\n\t"
|
||||
|
||||
"ldp x10, x11, [%[save], #64]\n\t"
|
||||
"stp x27, x28, [%[save], #64]\n\t"
|
||||
"mov x27, x10\n\t"
|
||||
"mov x28, x11\n\t"
|
||||
|
||||
"ldp x10, x11, [%[save], #80]\n\t"
|
||||
"mov x14, sp\n\t"
|
||||
"stp x29, x14, [%[save], #80]\n\t"
|
||||
"mov x29, x10\n\t"
|
||||
"mov sp, x11\n\t"
|
||||
|
||||
"ldp d0, d1, [%[save], #96]\n\t"
|
||||
"stp d8, d9, [%[save], #96]\n\t"
|
||||
"fmov d8, d0\n\t"
|
||||
"fmov d9, d1\n\t"
|
||||
|
||||
"ldp d0, d1, [%[save], #112]\n\t"
|
||||
"stp d10, d11, [%[save], #112]\n\t"
|
||||
"fmov d10, d0\n\t"
|
||||
"fmov d11, d1\n\t"
|
||||
|
||||
"ldp d0, d1, [%[save], #128]\n\t"
|
||||
"stp d12, d13, [%[save], #128]\n\t"
|
||||
"fmov d12, d0\n\t"
|
||||
"fmov d13, d1\n\t"
|
||||
|
||||
"ldp d0, d1, [%[save], #144]\n\t"
|
||||
"stp d14, d15, [%[save], #144]\n\t"
|
||||
"fmov d14, d0\n\t"
|
||||
"fmov d15, d1\n\t"
|
||||
|
||||
"adr x10, 1f\n\t"
|
||||
"adr x11, 2f\n\t"
|
||||
"ldr x15, [%[save], #168]\n\t"
|
||||
"stp x10, x11, [%[save], #160]\n\t"
|
||||
"mov x19, x13\n\t"
|
||||
"br x15\n"
|
||||
/*
|
||||
Come here when operation is done.
|
||||
Be sure to use the same callee-save register for %[save] here and in
|
||||
my_context_spawn(), so we preserve the value correctly at this point.
|
||||
*/
|
||||
"1:\n\t"
|
||||
/* x19 (aka %[save]) is preserved from my_context_spawn() in this case. */
|
||||
"ldr x20, [%[save], #8]\n\t"
|
||||
"ldp x21, x22, [%[save], #16]\n\t"
|
||||
"ldp x23, x24, [%[save], #32]\n\t"
|
||||
"ldp x25, x26, [%[save], #48]\n\t"
|
||||
"ldp x27, x28, [%[save], #64]\n\t"
|
||||
"ldp x29, x10, [%[save], #80]\n\t"
|
||||
"mov sp, x10\n\t"
|
||||
"ldp d8, d9, [%[save], #96]\n\t"
|
||||
"ldp d10, d11, [%[save], #112]\n\t"
|
||||
"ldp d12, d13, [%[save], #128]\n\t"
|
||||
"ldp d14, d15, [%[save], #144]\n\t"
|
||||
"mov %w[ret], #0\n\t"
|
||||
"b 3f\n"
|
||||
/* Come here when operation is suspended. */
|
||||
"2:\n\t"
|
||||
"mov %w[ret], #1\n"
|
||||
"3:\n"
|
||||
: [ret] "=r" (ret)
|
||||
: [save] "r" (save)
|
||||
: "x1", "x2", "x3", "x4", "x5", "x6", "x7",
|
||||
"x9", "x10", "x11", "x12", "x13", "x14", "x15", "x18", "x30",
|
||||
"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
|
||||
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
|
||||
"v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
|
||||
"memory", "cc"
|
||||
);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
my_context_yield(struct my_context *c)
|
||||
{
|
||||
register const uint64_t *save asm("x19") = &c->save[0];
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"ldp x13, x11, [%[save], #0]\n\t"
|
||||
"stp x19, x20, [%[save], #0]\n\t"
|
||||
/* x19 is %[save], delay restoring it until %[save] is no longer needed. */
|
||||
"mov x20, x11\n\t"
|
||||
|
||||
"ldp x10, x11, [%[save], #16]\n\t"
|
||||
"stp x21, x22, [%[save], #16]\n\t"
|
||||
"mov x21, x10\n\t"
|
||||
"mov x22, x11\n\t"
|
||||
|
||||
"ldp x10, x11, [%[save], #32]\n\t"
|
||||
"stp x23, x24, [%[save], #32]\n\t"
|
||||
"mov x23, x10\n\t"
|
||||
"mov x24, x11\n\t"
|
||||
|
||||
"ldp x10, x11, [%[save], #48]\n\t"
|
||||
"stp x25, x26, [%[save], #48]\n\t"
|
||||
"mov x25, x10\n\t"
|
||||
"mov x26, x11\n\t"
|
||||
|
||||
"ldp x10, x11, [%[save], #64]\n\t"
|
||||
"stp x27, x28, [%[save], #64]\n\t"
|
||||
"mov x27, x10\n\t"
|
||||
"mov x28, x11\n\t"
|
||||
|
||||
"ldp x10, x11, [%[save], #80]\n\t"
|
||||
"mov x14, sp\n\t"
|
||||
"stp x29, x14, [%[save], #80]\n\t"
|
||||
"mov x29, x10\n\t"
|
||||
"mov sp, x11\n\t"
|
||||
|
||||
"ldp d0, d1, [%[save], #96]\n\t"
|
||||
"stp d8, d9, [%[save], #96]\n\t"
|
||||
"fmov d8, d0\n\t"
|
||||
"fmov d9, d1\n\t"
|
||||
|
||||
"ldp d0, d1, [%[save], #112]\n\t"
|
||||
"stp d10, d11, [%[save], #112]\n\t"
|
||||
"fmov d10, d0\n\t"
|
||||
"fmov d11, d1\n\t"
|
||||
|
||||
"ldp d0, d1, [%[save], #128]\n\t"
|
||||
"stp d12, d13, [%[save], #128]\n\t"
|
||||
"fmov d12, d0\n\t"
|
||||
"fmov d13, d1\n\t"
|
||||
|
||||
"ldp d0, d1, [%[save], #144]\n\t"
|
||||
"stp d14, d15, [%[save], #144]\n\t"
|
||||
"fmov d14, d0\n\t"
|
||||
"fmov d15, d1\n\t"
|
||||
|
||||
"ldr x11, [%[save], #168]\n\t"
|
||||
"adr x10, 1f\n\t"
|
||||
"str x10, [%[save], #168]\n\t"
|
||||
"mov x19, x13\n\t"
|
||||
"br x11\n"
|
||||
|
||||
"1:\n"
|
||||
:
|
||||
: [save] "r" (save)
|
||||
: "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
|
||||
"x9", "x10", "x11", "x12", "x13", "x14", "x15", "x18", "x30",
|
||||
"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
|
||||
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
|
||||
"v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
|
||||
"memory", "cc"
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
my_context_init(struct my_context *c, size_t stack_size)
|
||||
{
|
||||
memset(c, 0, sizeof(*c));
|
||||
|
||||
if (!(c->stack_bot= malloc(stack_size)))
|
||||
return -1; /* Out of memory */
|
||||
/*
|
||||
Align stack to 16-byte boundary.
|
||||
Also put two zero words at the top of the stack.
|
||||
*/
|
||||
c->stack_top= (void *)
|
||||
(( ((intptr)c->stack_bot + stack_size) & ~(intptr)0xf) - 16);
|
||||
memset(c->stack_top, 0, 16);
|
||||
|
||||
#ifdef HAVE_VALGRIND
|
||||
c->valgrind_stack_id=
|
||||
VALGRIND_STACK_REGISTER(c->stack_bot, c->stack_top);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
my_context_destroy(struct my_context *c)
|
||||
{
|
||||
if (c->stack_bot)
|
||||
{
|
||||
free(c->stack_bot);
|
||||
#ifdef HAVE_VALGRIND
|
||||
VALGRIND_STACK_DEREGISTER(c->valgrind_stack_id);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MY_CONTEXT_USE_AARCH64_GCC_ASM */
|
||||
|
||||
|
||||
#ifdef MY_CONTEXT_USE_WIN32_FIBERS
|
||||
int
|
||||
my_context_yield(struct my_context *c)
|
||||
|
@@ -54,12 +54,9 @@ size_t mariadb_time_to_string(const MYSQL_TIME *tm, char *time_str, size_t len,
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
if (digits && (len < length))
|
||||
{
|
||||
char helper[16];
|
||||
snprintf(helper, 16, ".%%0%du", digits);
|
||||
length+= snprintf(time_str + length, len - length, helper, digits);
|
||||
}
|
||||
if (digits && len > length + 1)
|
||||
length+= snprintf(time_str + length, len - length, ".%0*lu", digits,
|
||||
tm->second_part);
|
||||
return length;
|
||||
}
|
||||
|
||||
|
@@ -1465,8 +1465,8 @@ mysql_real_connect(MYSQL *mysql, const char *host, const char *user,
|
||||
|
||||
reset_tls_error(mysql);
|
||||
|
||||
/* if host contains a semicolon, we need to parse connection string */
|
||||
if (host && strchr(host, ';'))
|
||||
/* if host contains a semicolon or equal sign, we need to parse connection string */
|
||||
if (host && (strchr(host, ';') || strchr(host, '=')))
|
||||
{
|
||||
if (parse_connection_string(mysql, NULL, host, strlen(host)))
|
||||
return NULL;
|
||||
@@ -2122,7 +2122,9 @@ my_bool STDCALL mariadb_reconnect(MYSQL *mysql)
|
||||
my_context_install_suspend_resume_hook(ctxt, my_suspend_hook, &hook_data);
|
||||
}
|
||||
|
||||
if (!mysql_real_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd,
|
||||
if (!mysql_real_connect(&tmp_mysql,
|
||||
mysql->options.host ? NULL : mysql->host,
|
||||
mysql->user,mysql->passwd,
|
||||
mysql->db, mysql->port, mysql->unix_socket,
|
||||
mysql->client_flag | CLIENT_REMEMBER_OPTIONS) ||
|
||||
mysql_set_character_set(&tmp_mysql, mysql->charset->csname))
|
||||
|
@@ -27,14 +27,14 @@ ENDIF()
|
||||
|
||||
#native password
|
||||
REGISTER_PLUGIN(TARGET mysql_native_password
|
||||
TYPE MARIADB_CLIENT_PLUGIN_AUTH
|
||||
TYPE AUTH
|
||||
CONFIGURATIONS STATIC
|
||||
DEFAULT STATIC
|
||||
SOURCES ${AUTH_DIR}/my_auth.c)
|
||||
|
||||
#Dialog client authentication plugin
|
||||
REGISTER_PLUGIN(TARGET dialog
|
||||
TYPE MARIADB_CLIENT_PLUGIN_AUTH
|
||||
TYPE AUTH
|
||||
CONFIGURATIONS DYNAMIC STATIC OFF
|
||||
DEFAULT DYNAMIC
|
||||
SOURCES ${AUTH_DIR}/dialog.c
|
||||
@@ -72,7 +72,7 @@ IF(CRYPTO_PLUGIN)
|
||||
ENDIF()
|
||||
|
||||
REGISTER_PLUGIN(TARGET client_ed25519
|
||||
TYPE MARIADB_CLIENT_PLUGIN_AUTH
|
||||
TYPE AUTH
|
||||
CONFIGURATIONS DYNAMIC STATIC OFF
|
||||
DEFAULT DYNAMIC
|
||||
SOURCES ${AUTH_DIR}/ed25519.c
|
||||
@@ -89,7 +89,7 @@ IF(CRYPTO_PLUGIN)
|
||||
|
||||
# SHA256 caching plugin for MySQL 8.0 connection
|
||||
REGISTER_PLUGIN(TARGET caching_sha2_password
|
||||
TYPE MARIADB_CLIENT_PLUGIN_AUTH
|
||||
TYPE AUTH
|
||||
CONFIGURATIONS DYNAMIC STATIC OFF
|
||||
DEFAULT DYNAMIC
|
||||
SOURCES ${AUTH_DIR}/caching_sha2_pw.c
|
||||
@@ -100,7 +100,7 @@ IF(CRYPTO_PLUGIN)
|
||||
MESSAGE1(SHA256_PASSWORD "sha256_password not supported by GnuTLS due to missing OAEP padding")
|
||||
ELSE()
|
||||
REGISTER_PLUGIN(TARGET sha256_password
|
||||
TYPE MARIADB_CLIENT_PLUGIN_AUTH
|
||||
TYPE AUTH
|
||||
CONFIGURATIONS DYNAMIC STATIC OFF
|
||||
DEFAULT DYNAMIC
|
||||
SOURCES ${AUTH_DIR}/sha256_pw.c
|
||||
@@ -140,7 +140,7 @@ ELSE()
|
||||
ENDIF()
|
||||
IF(GSSAPI_SOURCES)
|
||||
REGISTER_PLUGIN(TARGET auth_gssapi_client
|
||||
TYPE MARIADB_CLIENT_PLUGIN_AUTH
|
||||
TYPE AUTH
|
||||
CONFIGURATIONS DYNAMIC STATIC OFF DYNAMIC_AND_STATIC
|
||||
DEFAULT ${AUTH_GSSAPI_DEFAULT_CONFIG}
|
||||
SOURCES ${GSSAPI_SOURCES}
|
||||
@@ -156,7 +156,7 @@ ENDIF()
|
||||
|
||||
# old_password plugin
|
||||
REGISTER_PLUGIN(TARGET mysql_old_password
|
||||
TYPE MARIADB_CLIENT_PLUGIN_AUTH
|
||||
TYPE AUTH
|
||||
CONFIGURATIONS STATIC DYNAMIC OFF
|
||||
DEFAULT STATIC
|
||||
DISABLED YES
|
||||
@@ -164,7 +164,7 @@ REGISTER_PLUGIN(TARGET mysql_old_password
|
||||
|
||||
# Cleartext
|
||||
REGISTER_PLUGIN(TARGET mysql_clear_password
|
||||
TYPE MARIADB_CLIENT_PLUGIN_AUTH
|
||||
TYPE AUTH
|
||||
CONFIGURATIONS DYNAMIC STATIC OFF
|
||||
DEFAULT DYNAMIC
|
||||
SOURCES ${AUTH_DIR}/mariadb_cleartext.c)
|
||||
|
@@ -6,7 +6,7 @@ INCLUDE_DIRECTORIES(${CC_SOURCE_DIR}/include)
|
||||
#zlib compression
|
||||
|
||||
REGISTER_PLUGIN(TARGET zlib
|
||||
TYPE MARIADB_CLIENT_COMPRESSION_PLUGIN
|
||||
TYPE COMPRESSION
|
||||
CONFIGURATIONS STATIC
|
||||
DEFAULT STATIC
|
||||
SOURCES ${COMPRESS_PLUGIN_DIR}/c_zlib.c)
|
||||
@@ -15,7 +15,7 @@ REGISTER_PLUGIN(TARGET zlib
|
||||
IF(${ZSTD_FOUND})
|
||||
INCLUDE_DIRECTORIES(${ZSTD_INCLUDE_DIRS})
|
||||
REGISTER_PLUGIN(TARGET zstd
|
||||
TYPE MARIADB_CLIENT_COMPRESSION_PLUGIN
|
||||
TYPE COMPRESSION
|
||||
CONFIGURATIONS DYNAMIC STATIC OFF
|
||||
DEFAULT DYNAMIC
|
||||
SOURCES ${COMPRESS_PLUGIN_DIR}/c_zstd.c
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# Replication
|
||||
REGISTER_PLUGIN(TARGET replication
|
||||
TYPE MARIADB_CLIENT_PLUGIN_CONNECTION
|
||||
TYPE CONNECTION
|
||||
CONFIGURATIONS STATIC DYNAMIC OFF
|
||||
DEFAULT OFF
|
||||
SOURCES ${CC_SOURCE_DIR}/plugins/connection/replication.c)
|
||||
|
@@ -5,7 +5,7 @@ IF (WITH_CURL)
|
||||
ADD_DEFINITIONS(-DHAVE_REMOTEIO=1)
|
||||
#remote io plugin
|
||||
REGISTER_PLUGIN(TARGET remote_io
|
||||
TYPE MARIADB_CLIENT_PLUGIN_IO
|
||||
TYPE REMOTEIO
|
||||
CONFIGURATIONS DYNAMIC STATIC OFF
|
||||
DEFAULT DYNAMIC
|
||||
SOURCES ${CC_SOURCE_DIR}/plugins/io/remote_io.c
|
||||
|
@@ -5,7 +5,7 @@ INCLUDE_DIRECTORIES(${CC_SOURCE_DIR}/include)
|
||||
|
||||
#native password
|
||||
REGISTER_PLUGIN(TARGET pvio_socket
|
||||
TYPE MARIADB_CLIENT_PLUGIN_PVIO
|
||||
TYPE PVIO
|
||||
CONFIGURATIONS STATIC DYNAMIC DEFAULT
|
||||
DEFAULT STATIC
|
||||
SOURCES ${CC_SOURCE_DIR}/plugins/pvio/pvio_socket.c)
|
||||
@@ -13,14 +13,14 @@ REGISTER_PLUGIN(TARGET pvio_socket
|
||||
IF(WIN32)
|
||||
# named pipe
|
||||
REGISTER_PLUGIN(TARGET pvio_npipe
|
||||
TYPE MARIADB_CLIENT_PLUGIN_PVIO
|
||||
TYPE PVIO
|
||||
CONFIGURATIONS STATIC DYNAMIC DEFAULT
|
||||
DEFAULT STATIC
|
||||
SOURCES ${CC_SOURCE_DIR}/plugins/pvio/pvio_npipe.c)
|
||||
|
||||
# shared memory
|
||||
REGISTER_PLUGIN(TARGET pvio_shmem
|
||||
TYPE MARIADB_CLIENT_PLUGIN_PVIO
|
||||
TYPE PVIO
|
||||
CONFIGURATIONS STATIC DYNAMIC DEFAULT
|
||||
DEFAULT DYNAMIC
|
||||
SOURCES ${CC_SOURCE_DIR}/plugins/pvio/pvio_shmem.c)
|
||||
|
Reference in New Issue
Block a user