--- Coro-Mysql/Mysql.pm 2019/03/04 05:44:43 1.23 +++ Coro-Mysql/Mysql.pm 2019/03/04 06:19:16 1.24 @@ -11,12 +11,14 @@ =head1 DESCRIPTION (Note that in this manual, "thread" refers to real threads as implemented -by the Coro module, not to the built-in windows process emulation which -unfortunately is also called "threads") +by the L module, not to the built-in windows process emulation which +unfortunately is also called "threads"). This module replaces the I/O handlers for a database connection, with the -effect that "patched" database handles no longer block the all threads of -a process, but only the thread that does the request. +effect that "patched" database handles no longer block all threads of a +process, but only the thread that does the request. It should work for +both L and L connections and a wide range of +mariadb/mysql client libraries. This can be used to make parallel sql requests using Coro, or to do other stuff while mariadb is rumbling in the background. @@ -25,7 +27,7 @@ Note that this module must be linked against exactly the same (shared, possibly not working with all OSes) F/F -library as L, otherwise it will not work. +library as L/L, otherwise it will not work. Also, while this module makes database handles non-blocking, you still cannot run multiple requests in parallel on the same database handle. If @@ -70,7 +72,7 @@ =head1 FUNCTIONS -Coro::Mysql offers a single user-accessible function: +Coro::Mysql offers these functions, the only one that oyu usually need is C: =over 4 @@ -125,23 +127,59 @@ sub unblock { my ($DBH) = @_; - if ($DBH && $DBH->{Driver}{Name} eq "mysql") { - my $sock = $DBH->{sock}; + if ($DBH) { + my $mariadb = $DBH->{Driver}{Name} eq "MariaDB"; + if ($mariadb or $DBH->{Driver}{Name} eq "mysql") { + my $sock = $mariadb ? $DBH->{mariadb_sock} : $DBH->{sock}; + my $sockfd = $mariadb ? $DBH->mariadb_sockfd : $DBH->{sockfd}; + my $cvers = $mariadb ? $DBH->{mariadb_clientversion} : $DBH->{mysql_clientversion}; + + open my $fh, "+>&$sockfd" + or croak "Coro::Mysql unable to dup mariadb/mysql fd"; + + if (AnyEvent::detect ne "AnyEvent::Impl::EV" || !_use_ev) { + require Coro::Handle; + $fh = Coro::Handle::unblock ($fh); + } - open my $fh, "+>&" . $DBH->{sockfd} - or croak "Coro::Mysql unable to clone mysql fd"; - - if (AnyEvent::detect ne "AnyEvent::Impl::EV" || !_use_ev) { - require Coro::Handle; - $fh = Coro::Handle::unblock ($fh); + _patch $sock, $sockfd, $cvers, $fh, tied *$$fh; } - - _patch $sock, $DBH->{sockfd}, $DBH->{mysql_clientversion}, $fh, tied *$$fh; } $DBH } +=item $bool = Coro::Mysql::is_unblocked $DBH + +Returns true iff the database handle was successfully patched for +non-blocking operations. + +=cut + +sub is_unblocked { + my ($DBH) = @_; + + if ($DBH) { + my $mariadb = $DBH->{Driver}{Name} eq "MariaDB"; + if ($mariadb or $DBH->{Driver}{Name} eq "mysql") { + my $sock = $mariadb ? $DBH->{mariadb_sock} : $DBH->{sock}; + return _is_patched $sock + } + } + + 0 +} + +=item $bool = Coro::Mysql::have_ev + +Returns true if this Coro::Mysql installation is compiled with special +support for L or not. + +Even if compiled in, it will only be used if L is actually the +AnyEvent event backend. + +=cut + 1; =back