1
0
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:
Georg Richter
2024-10-22 13:50:24 +02:00
15 changed files with 561 additions and 45 deletions

View File

@@ -16,8 +16,6 @@ IF(COMMAND CMAKE_POLICY)
ENDIF() ENDIF()
PROJECT(mariadb-connector-c C)
# Is C/C built as subproject? # Is C/C built as subproject?
get_directory_property(IS_SUBPROJECT PARENT_DIRECTORY) get_directory_property(IS_SUBPROJECT PARENT_DIRECTORY)
@@ -25,11 +23,29 @@ get_directory_property(IS_SUBPROJECT PARENT_DIRECTORY)
SET_PROPERTY(DIRECTORY PROPERTY INCLUDE_DIRECTORIES) SET_PROPERTY(DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
FOREACH(V WITH_MYSQLCOMPAT WITH_MSI WITH_SIGNCODE WITH_RTC WITH_UNIT_TESTS 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 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) DEFAULT_SSL_VERIFY_SERVER_CERT)
SET(${V} ${${OPT}${V}}) SET(${V} ${${OPT}${V}})
ENDFOREACH() 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_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
SET(CC_BINARY_DIR ${CMAKE_CURRENT_BINARY_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_MINOR} * 100 +
${CPACK_PACKAGE_VERSION_PATCH}") ${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 ### ### Options ###
IF(NOT WIN32) IF(NOT WIN32)
ADD_OPTION(WITH_MYSQLCOMPAT "creates libmysql* symbolic links" OFF) ADD_OPTION(WITH_MYSQLCOMPAT "creates libmysql* symbolic links" OFF)
@@ -367,6 +375,11 @@ IF(NOT WITH_SSL STREQUAL "OFF")
MARK_AS_ADVANCED(SSL_SOURCES) MARK_AS_ADVANCED(SSL_SOURCES)
ENDIF() 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)") 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) MARK_AS_ADVANCED(ENABLED_LOCAL_INFILE)
IF (ENABLED_LOCAL_INFILE MATCHES "^(0|FALSE)$") IF (ENABLED_LOCAL_INFILE MATCHES "^(0|FALSE)$")

View File

@@ -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/stat.h HAVE_SYS_STAT_H)
CHECK_INCLUDE_FILES (sys/un.h HAVE_SYS_UN_H) CHECK_INCLUDE_FILES (sys/un.h HAVE_SYS_UN_H)
CHECK_INCLUDE_FILES (unistd.h HAVE_UNISTD_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) IF(APPLE)
SET(CMAKE_REQUIRED_DEFINITIONS -D_XOPEN_SOURCE=600) SET(CMAKE_REQUIRED_DEFINITIONS -D_XOPEN_SOURCE=600)

View File

@@ -50,7 +50,7 @@ FUNCTION(REGISTER_PLUGIN)
endif() endif()
if(NOT ${CC_PLUGIN_DEFAULT} STREQUAL "OFF") 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") if(${CC_PLUGIN_DEFAULT} MATCHES "DYNAMIC")

View File

@@ -29,6 +29,7 @@
#cmakedefine HAVE_SYS_UN_H 1 #cmakedefine HAVE_SYS_UN_H 1
#cmakedefine HAVE_UNISTD_H 1 #cmakedefine HAVE_UNISTD_H 1
#cmakedefine HAVE_UCONTEXT_H 1 #cmakedefine HAVE_UCONTEXT_H 1
#cmakedefine HAVE_BOOST_CONTEXT_H 1
/* /*
* function definitions - processed in LibmysqlFunctions.txt * function definitions - processed in LibmysqlFunctions.txt

View File

@@ -32,12 +32,20 @@
#define MY_CONTEXT_USE_X86_64_GCC_ASM #define MY_CONTEXT_USE_X86_64_GCC_ASM
#elif defined(__GNUC__) && __GNUC__ >= 3 && defined(__i386__) #elif defined(__GNUC__) && __GNUC__ >= 3 && defined(__i386__)
#define MY_CONTEXT_USE_I386_GCC_ASM #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) #elif defined(HAVE_UCONTEXT_H)
#define MY_CONTEXT_USE_UCONTEXT #define MY_CONTEXT_USE_UCONTEXT
#else #else
#define MY_CONTEXT_DISABLE #define MY_CONTEXT_DISABLE
#endif #endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef MY_CONTEXT_USE_WIN32_FIBERS #ifdef MY_CONTEXT_USE_WIN32_FIBERS
struct my_context { struct my_context {
void (*user_func)(void *); void (*user_func)(void *);
@@ -107,6 +115,49 @@ struct my_context {
#endif #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 #ifdef MY_CONTEXT_DISABLE
struct my_context { struct my_context {
int dummy; int dummy;
@@ -240,3 +291,7 @@ struct mysql_async_context {
*/ */
struct my_context async_context; struct my_context async_context;
}; };
#ifdef __cplusplus
}
#endif

View File

@@ -298,7 +298,7 @@ MESSAGE(STATUS "SYSTEM_LIBS: ${SYSTEM_LIBS}")
INCLUDE_DIRECTORIES(${LIBMARIADB_PLUGIN_INCLUDES}) INCLUDE_DIRECTORIES(${LIBMARIADB_PLUGIN_INCLUDES})
ADD_DEFINITIONS(${LIBMARIADB_PLUGIN_DEFS}) ADD_DEFINITIONS(${LIBMARIADB_PLUGIN_DEFS})
FOREACH(plugin ${PLUGINS_STATIC}) 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") SET(BUILTIN_PLUGINS "${BUILTIN_PLUGINS} (struct st_mysql_client_plugin *)&${plugin}_client_plugin,\n")
ENDFOREACH() ENDFOREACH()
CONFIGURE_FILE(${CC_SOURCE_DIR}/libmariadb/ma_client_plugin.c.in CONFIGURE_FILE(${CC_SOURCE_DIR}/libmariadb/ma_client_plugin.c.in
@@ -394,6 +394,9 @@ IF(WITH_DYNCOL)
ENDIF() ENDIF()
SET(LIBMARIADB_SOURCES ${LIBMARIADB_SOURCES} mariadb_async.c ma_context.c) 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}) SET(MARIADB_LIB_SYMBOLS ${MARIADB_LIB_SYMBOLS} ${MARIADB_NONBLOCK_SYMBOLS})
INCLUDE(${CC_SOURCE_DIR}/cmake/export.cmake) INCLUDE(${CC_SOURCE_DIR}/cmake/export.cmake)

View 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 */

View File

@@ -21,6 +21,9 @@
swapcontext(). swapcontext().
*/ */
#include <stdint.h>
#include <stdlib.h>
#include "ma_global.h" #include "ma_global.h"
#include "ma_string.h" #include "ma_string.h"
#include "ma_context.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). 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. Layout of saved registers etc.
Since this is accessed through gcc inline assembler, it is simpler to just 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 %%rsp, (%[save])\n\t"
"movq %[stack], %%rsp\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 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 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). 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. Layout of saved registers etc.
Since this is accessed through gcc inline assembler, it is simpler to just 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 %%esp, (%[save])\n\t"
"movl %[stack], %%esp\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 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 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 */ #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 #ifdef MY_CONTEXT_USE_WIN32_FIBERS
int int
my_context_yield(struct my_context *c) my_context_yield(struct my_context *c)

View File

@@ -54,12 +54,9 @@ size_t mariadb_time_to_string(const MYSQL_TIME *tm, char *time_str, size_t len,
return 0; return 0;
break; break;
} }
if (digits && (len < length)) if (digits && len > length + 1)
{ length+= snprintf(time_str + length, len - length, ".%0*lu", digits,
char helper[16]; tm->second_part);
snprintf(helper, 16, ".%%0%du", digits);
length+= snprintf(time_str + length, len - length, helper, digits);
}
return length; return length;
} }

View File

@@ -1465,8 +1465,8 @@ mysql_real_connect(MYSQL *mysql, const char *host, const char *user,
reset_tls_error(mysql); reset_tls_error(mysql);
/* if host contains a semicolon, we need to parse connection string */ /* if host contains a semicolon or equal sign, we need to parse connection string */
if (host && strchr(host, ';')) if (host && (strchr(host, ';') || strchr(host, '=')))
{ {
if (parse_connection_string(mysql, NULL, host, strlen(host))) if (parse_connection_string(mysql, NULL, host, strlen(host)))
return NULL; 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); 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->db, mysql->port, mysql->unix_socket,
mysql->client_flag | CLIENT_REMEMBER_OPTIONS) || mysql->client_flag | CLIENT_REMEMBER_OPTIONS) ||
mysql_set_character_set(&tmp_mysql, mysql->charset->csname)) mysql_set_character_set(&tmp_mysql, mysql->charset->csname))

View File

@@ -27,14 +27,14 @@ ENDIF()
#native password #native password
REGISTER_PLUGIN(TARGET mysql_native_password REGISTER_PLUGIN(TARGET mysql_native_password
TYPE MARIADB_CLIENT_PLUGIN_AUTH TYPE AUTH
CONFIGURATIONS STATIC CONFIGURATIONS STATIC
DEFAULT STATIC DEFAULT STATIC
SOURCES ${AUTH_DIR}/my_auth.c) SOURCES ${AUTH_DIR}/my_auth.c)
#Dialog client authentication plugin #Dialog client authentication plugin
REGISTER_PLUGIN(TARGET dialog REGISTER_PLUGIN(TARGET dialog
TYPE MARIADB_CLIENT_PLUGIN_AUTH TYPE AUTH
CONFIGURATIONS DYNAMIC STATIC OFF CONFIGURATIONS DYNAMIC STATIC OFF
DEFAULT DYNAMIC DEFAULT DYNAMIC
SOURCES ${AUTH_DIR}/dialog.c SOURCES ${AUTH_DIR}/dialog.c
@@ -72,7 +72,7 @@ IF(CRYPTO_PLUGIN)
ENDIF() ENDIF()
REGISTER_PLUGIN(TARGET client_ed25519 REGISTER_PLUGIN(TARGET client_ed25519
TYPE MARIADB_CLIENT_PLUGIN_AUTH TYPE AUTH
CONFIGURATIONS DYNAMIC STATIC OFF CONFIGURATIONS DYNAMIC STATIC OFF
DEFAULT DYNAMIC DEFAULT DYNAMIC
SOURCES ${AUTH_DIR}/ed25519.c SOURCES ${AUTH_DIR}/ed25519.c
@@ -89,7 +89,7 @@ IF(CRYPTO_PLUGIN)
# SHA256 caching plugin for MySQL 8.0 connection # SHA256 caching plugin for MySQL 8.0 connection
REGISTER_PLUGIN(TARGET caching_sha2_password REGISTER_PLUGIN(TARGET caching_sha2_password
TYPE MARIADB_CLIENT_PLUGIN_AUTH TYPE AUTH
CONFIGURATIONS DYNAMIC STATIC OFF CONFIGURATIONS DYNAMIC STATIC OFF
DEFAULT DYNAMIC DEFAULT DYNAMIC
SOURCES ${AUTH_DIR}/caching_sha2_pw.c 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") MESSAGE1(SHA256_PASSWORD "sha256_password not supported by GnuTLS due to missing OAEP padding")
ELSE() ELSE()
REGISTER_PLUGIN(TARGET sha256_password REGISTER_PLUGIN(TARGET sha256_password
TYPE MARIADB_CLIENT_PLUGIN_AUTH TYPE AUTH
CONFIGURATIONS DYNAMIC STATIC OFF CONFIGURATIONS DYNAMIC STATIC OFF
DEFAULT DYNAMIC DEFAULT DYNAMIC
SOURCES ${AUTH_DIR}/sha256_pw.c SOURCES ${AUTH_DIR}/sha256_pw.c
@@ -140,7 +140,7 @@ ELSE()
ENDIF() ENDIF()
IF(GSSAPI_SOURCES) IF(GSSAPI_SOURCES)
REGISTER_PLUGIN(TARGET auth_gssapi_client REGISTER_PLUGIN(TARGET auth_gssapi_client
TYPE MARIADB_CLIENT_PLUGIN_AUTH TYPE AUTH
CONFIGURATIONS DYNAMIC STATIC OFF DYNAMIC_AND_STATIC CONFIGURATIONS DYNAMIC STATIC OFF DYNAMIC_AND_STATIC
DEFAULT ${AUTH_GSSAPI_DEFAULT_CONFIG} DEFAULT ${AUTH_GSSAPI_DEFAULT_CONFIG}
SOURCES ${GSSAPI_SOURCES} SOURCES ${GSSAPI_SOURCES}
@@ -156,7 +156,7 @@ ENDIF()
# old_password plugin # old_password plugin
REGISTER_PLUGIN(TARGET mysql_old_password REGISTER_PLUGIN(TARGET mysql_old_password
TYPE MARIADB_CLIENT_PLUGIN_AUTH TYPE AUTH
CONFIGURATIONS STATIC DYNAMIC OFF CONFIGURATIONS STATIC DYNAMIC OFF
DEFAULT STATIC DEFAULT STATIC
DISABLED YES DISABLED YES
@@ -164,7 +164,7 @@ REGISTER_PLUGIN(TARGET mysql_old_password
# Cleartext # Cleartext
REGISTER_PLUGIN(TARGET mysql_clear_password REGISTER_PLUGIN(TARGET mysql_clear_password
TYPE MARIADB_CLIENT_PLUGIN_AUTH TYPE AUTH
CONFIGURATIONS DYNAMIC STATIC OFF CONFIGURATIONS DYNAMIC STATIC OFF
DEFAULT DYNAMIC DEFAULT DYNAMIC
SOURCES ${AUTH_DIR}/mariadb_cleartext.c) SOURCES ${AUTH_DIR}/mariadb_cleartext.c)

View File

@@ -6,7 +6,7 @@ INCLUDE_DIRECTORIES(${CC_SOURCE_DIR}/include)
#zlib compression #zlib compression
REGISTER_PLUGIN(TARGET zlib REGISTER_PLUGIN(TARGET zlib
TYPE MARIADB_CLIENT_COMPRESSION_PLUGIN TYPE COMPRESSION
CONFIGURATIONS STATIC CONFIGURATIONS STATIC
DEFAULT STATIC DEFAULT STATIC
SOURCES ${COMPRESS_PLUGIN_DIR}/c_zlib.c) SOURCES ${COMPRESS_PLUGIN_DIR}/c_zlib.c)
@@ -15,7 +15,7 @@ REGISTER_PLUGIN(TARGET zlib
IF(${ZSTD_FOUND}) IF(${ZSTD_FOUND})
INCLUDE_DIRECTORIES(${ZSTD_INCLUDE_DIRS}) INCLUDE_DIRECTORIES(${ZSTD_INCLUDE_DIRS})
REGISTER_PLUGIN(TARGET zstd REGISTER_PLUGIN(TARGET zstd
TYPE MARIADB_CLIENT_COMPRESSION_PLUGIN TYPE COMPRESSION
CONFIGURATIONS DYNAMIC STATIC OFF CONFIGURATIONS DYNAMIC STATIC OFF
DEFAULT DYNAMIC DEFAULT DYNAMIC
SOURCES ${COMPRESS_PLUGIN_DIR}/c_zstd.c SOURCES ${COMPRESS_PLUGIN_DIR}/c_zstd.c

View File

@@ -1,6 +1,6 @@
# Replication # Replication
REGISTER_PLUGIN(TARGET replication REGISTER_PLUGIN(TARGET replication
TYPE MARIADB_CLIENT_PLUGIN_CONNECTION TYPE CONNECTION
CONFIGURATIONS STATIC DYNAMIC OFF CONFIGURATIONS STATIC DYNAMIC OFF
DEFAULT OFF DEFAULT OFF
SOURCES ${CC_SOURCE_DIR}/plugins/connection/replication.c) SOURCES ${CC_SOURCE_DIR}/plugins/connection/replication.c)

View File

@@ -5,7 +5,7 @@ IF (WITH_CURL)
ADD_DEFINITIONS(-DHAVE_REMOTEIO=1) ADD_DEFINITIONS(-DHAVE_REMOTEIO=1)
#remote io plugin #remote io plugin
REGISTER_PLUGIN(TARGET remote_io REGISTER_PLUGIN(TARGET remote_io
TYPE MARIADB_CLIENT_PLUGIN_IO TYPE REMOTEIO
CONFIGURATIONS DYNAMIC STATIC OFF CONFIGURATIONS DYNAMIC STATIC OFF
DEFAULT DYNAMIC DEFAULT DYNAMIC
SOURCES ${CC_SOURCE_DIR}/plugins/io/remote_io.c SOURCES ${CC_SOURCE_DIR}/plugins/io/remote_io.c

View File

@@ -5,7 +5,7 @@ INCLUDE_DIRECTORIES(${CC_SOURCE_DIR}/include)
#native password #native password
REGISTER_PLUGIN(TARGET pvio_socket REGISTER_PLUGIN(TARGET pvio_socket
TYPE MARIADB_CLIENT_PLUGIN_PVIO TYPE PVIO
CONFIGURATIONS STATIC DYNAMIC DEFAULT CONFIGURATIONS STATIC DYNAMIC DEFAULT
DEFAULT STATIC DEFAULT STATIC
SOURCES ${CC_SOURCE_DIR}/plugins/pvio/pvio_socket.c) SOURCES ${CC_SOURCE_DIR}/plugins/pvio/pvio_socket.c)
@@ -13,14 +13,14 @@ REGISTER_PLUGIN(TARGET pvio_socket
IF(WIN32) IF(WIN32)
# named pipe # named pipe
REGISTER_PLUGIN(TARGET pvio_npipe REGISTER_PLUGIN(TARGET pvio_npipe
TYPE MARIADB_CLIENT_PLUGIN_PVIO TYPE PVIO
CONFIGURATIONS STATIC DYNAMIC DEFAULT CONFIGURATIONS STATIC DYNAMIC DEFAULT
DEFAULT STATIC DEFAULT STATIC
SOURCES ${CC_SOURCE_DIR}/plugins/pvio/pvio_npipe.c) SOURCES ${CC_SOURCE_DIR}/plugins/pvio/pvio_npipe.c)
# shared memory # shared memory
REGISTER_PLUGIN(TARGET pvio_shmem REGISTER_PLUGIN(TARGET pvio_shmem
TYPE MARIADB_CLIENT_PLUGIN_PVIO TYPE PVIO
CONFIGURATIONS STATIC DYNAMIC DEFAULT CONFIGURATIONS STATIC DYNAMIC DEFAULT
DEFAULT DYNAMIC DEFAULT DYNAMIC
SOURCES ${CC_SOURCE_DIR}/plugins/pvio/pvio_shmem.c) SOURCES ${CC_SOURCE_DIR}/plugins/pvio/pvio_shmem.c)