From a5b881594da4258257b18cc42f5ce7be3524e02c Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 20 Sep 2011 12:49:25 +0200 Subject: MWL#192: Non-blocking client API for libmysqlclient. All client functions that can block on I/O have alternate _start() and _cont() versions that do not block but return control back to the application, which can then issue I/O wait in its own fashion and later call back into the library to continue the operation. Works behind the scenes by spawning a co-routine/fiber to run the blocking operation and suspend it while waiting for I/O. This co-routine/fiber use is invisible to applications. For i368/x86_64 on GCC, uses very fast assembler co-routine support. On Windows uses native Win32 Fibers. Falls back to POSIX ucontext on other platforms. Assembler routines for more platforms are relatively easy to add by extending mysys/my_context.c, eg. similar to the Lua lcoco library. For testing, mysqltest and mysql_client_test are extended with the option --non-blocking-api. This causes the programs to use the non-blocking API for database access. mysql-test-run.pl has a similar option --non-blocking-api that uses this, as well as additional testcases. An example program tests/async_queries.c is included that uses the new non-blocking API with libevent to show how, in a single-threaded program, to issue many queries in parallel against a database. client/async_example.c: Fix const warning ****** Fix bug with wrong timeout value for poll(). include/Makefile.am: Fix missing include for `make dist` include/mysql.h: Add prototypes for all non-blocking API calls. include/mysql.h.pp: Add prototypes for all non-blocking API calls. mysys/my_context.c: Fix type warning for makecontext() function pointer argument. sql-common/mysql_async.c: Fix crashes in the non-blocking API for functions that can take MYSQL argument that is NULL. tests/Makefile.am: Add header file to `make dist` tests/mysql_client_test.c: Replace blocking calls with wrappers around the non-blocking calls, used in mysql_client_test to test the new non-blocking API. tests/nonblock-wrappers.h: Replace blocking calls with wrappers around the non-blocking calls, used in mysql_client_test to test the new non-blocking API. --- tests/mysql_client_test.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'tests/mysql_client_test.c') diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index c6efdca60f6..1ca70fd972a 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -36,6 +36,18 @@ #include #include +/* + If non_blocking_api_enabled is true, we will re-define all the blocking + API functions as wrappers that call the corresponding non-blocking API + and use poll()/select() to wait for them to complete. This way we can get + a good coverage testing of the non-blocking API as well. +*/ +static my_bool non_blocking_api_enabled= 0; +#if !defined(EMBEDDED_LIBRARY) +#define WRAP_NONBLOCK_ENABLED non_blocking_api_enabled +#include "nonblock-wrappers.h" +#endif + #define VER "2.1" #define MAX_TEST_QUERY_LENGTH 300 /* MAX QUERY BUFFER LENGTH */ #define MAX_KEY MAX_INDEXES @@ -18614,6 +18626,10 @@ static struct my_option client_test_long_options[] = #endif {"vardir", 'v', "Data dir for tests.", (char**) &opt_vardir, (char**) &opt_vardir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"non-blocking-api", 'n', + "Use the non-blocking client API for communication.", + &non_blocking_api_enabled, &non_blocking_api_enabled, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"getopt-ll-test", 'g', "Option for testing bug in getopt library", &opt_getopt_ll_test, &opt_getopt_ll_test, 0, GET_LL, REQUIRED_ARG, 0, 0, LONGLONG_MAX, 0, 0, 0}, -- cgit v1.2.1 From 17940b652d0a078f5a28b089aa0f5362756d438e Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Jan 2012 12:43:18 +0100 Subject: MWL#192: non-blocking client API, after-review fixes. Main change is that non-blocking operation is now an option that must be explicitly enabled with mysql_option(mysql, MYSQL_OPT_NONBLOCK, ...) before any non-blocing operation can be used. Also the CLIENT_REMEMBER_OPTIONS flag is now always enabled and thus effectively ignored (it was not really useful anyway, and this simplifies things when non-blocking mysql_real_connect() fails). --- tests/mysql_client_test.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tests/mysql_client_test.c') diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 1ca70fd972a..8ceeaf57399 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -260,6 +260,8 @@ static MYSQL *mysql_client_init(MYSQL* con) if (res && shared_memory_base_name) mysql_options(res, MYSQL_SHARED_MEMORY_BASE_NAME, shared_memory_base_name); #endif + if (res && non_blocking_api_enabled) + mysql_options(res, MYSQL_OPT_NONBLOCK, 0); return res; } -- cgit v1.2.1