mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
a5b881594d
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.
73 lines
2.2 KiB
Perl
73 lines
2.2 KiB
Perl
#! /usr/bin/perl
|
|
|
|
# Read the output of async_queries.c. Run the queries again serially, using
|
|
# the normal (not asynchronous) API. Compare the two results for correctness.
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use DBI;
|
|
|
|
my $D= [];
|
|
|
|
die "Usage: $0 <host> <user> <password> <database>\n"
|
|
unless @ARGV == 4;
|
|
|
|
my $dbh= DBI->connect("DBI:mysql:database=$ARGV[3];host=$ARGV[0]",
|
|
$ARGV[1], $ARGV[2],
|
|
{ RaiseError => 1, PrintError => 0 });
|
|
|
|
while (<STDIN>) {
|
|
chomp;
|
|
if (/^([0-9]+) ! (.*);$/) {
|
|
my ($index, $query)= ($1, $2);
|
|
$D->[$index]= { QUERY => $query, OUTPUT => [] };
|
|
} elsif (/^([0-9]+) - (.*)$/) {
|
|
my ($index, $data)= ($1, $2);
|
|
push @{$D->[$index]{OUTPUT}}, $data;
|
|
} elsif (/^([0-9]+) \| Error: (.*)$/) {
|
|
my ($index, $errmsg)= ($1, $2);
|
|
my $rows;
|
|
my $res= eval {
|
|
my $stm= $dbh->prepare($D->[$index]{QUERY});
|
|
$stm->execute();
|
|
$rows= $stm->fetchall_arrayref();
|
|
1;
|
|
};
|
|
if ($res) {
|
|
die "Query $index succeeded, but should have failed with error.\nquery=$D->[$index]{QUERY}\nerror=$errmsg\n";
|
|
}
|
|
my $errmsg2= $@;
|
|
if ($errmsg2 =~ /^DBD::.*failed: (.*) at .*$/s) {
|
|
$errmsg2= $1;
|
|
} else {
|
|
die "Unexpected DBD error message format: '$errmsg2'\n";
|
|
}
|
|
if ($errmsg2 ne $errmsg) {
|
|
die "Query $index failed with different error message\nquery=$D->[$index]{QUERY}\nerror1=$errmsg\nerror2=$errmsg2\n";
|
|
}
|
|
print "OK $index\n";
|
|
delete $D->[$index];
|
|
} elsif (/^([0-9]+) \| EOF$/) {
|
|
my $index= $1;
|
|
my $rows;
|
|
my $res= eval {
|
|
my $stm= $dbh->prepare($D->[$index]{QUERY});
|
|
$stm->execute();
|
|
$rows= $stm->fetchall_arrayref();
|
|
1;
|
|
};
|
|
if (!$res) {
|
|
die "Query $index failed, but should have succeeded.\nquery=$D->[$index]{QUERY}\nerror=$@\n";
|
|
}
|
|
my $result_string= join("\n", sort @{$D->[$index]{OUTPUT}});
|
|
my $result_string2= join("\n", sort(map(join("\t", map((defined($_) ? $_ : "(null)"), @$_)), @$rows)));
|
|
if ($result_string ne $result_string2) {
|
|
die "Query $index result difference.\nquery=$D->[$index]{QUERY}\noutput1=\n$$result_string\noutput2=\n$result_string2\n";
|
|
}
|
|
delete $D->[$index];
|
|
} else {
|
|
die "Unexpected line: '$_'\n";
|
|
}
|
|
}
|
|
$dbh->disconnect();
|