Small fix to AnyEvent::DBI, does not close correctly on DESTROY/kill_child

Jerry Lundström jerry.lundstrom at iis.se
Mon Aug 26 15:53:19 CEST 2013


On Aug 26, 2013, at 14:55 , Jerry Lundström wrote:

> Added shutdown (both read/write) and it seems to have solved this issue.


That was apparently not all, somehow SQLite still corrupts the database if all fds are closed after fork. Using exec_server for SQLite works.

Here is a suggested patch for opt out of closing all fds, grabbing the signals, doing disconnect on exit and adding a manual close call.

diff -ur AnyEvent-DBI-2.3.orig/DBI.pm AnyEvent-DBI-2.3/DBI.pm
--- AnyEvent-DBI-2.3.orig/DBI.pm	2013-08-26 14:34:45.780104460 +0200
+++ AnyEvent-DBI-2.3/DBI.pm	2013-08-26 15:47:58.319851994 +0200
@@ -80,6 +80,7 @@
 # this is the forked server code, could/should be bundled as it's own file

 our $DBH;
+our $CLOSE;

 sub req_open {
    my (undef, $dbi, $user, $pass, %attr) = @{+shift};
@@ -132,6 +133,16 @@
    return [1, $rc, $DBI::err, $DBI::errstr];
 }

+sub req_close {
+   $CLOSE = 1;
+   [1, ($DBH->disconnect || die [$DBI::errstr])]
+}
+
+sub close_dbh {
+   $DBH->disconnect if defined $DBH;
+   $CLOSE = 1;
+}
+
 sub serve_fh($$) {
    my ($fh, $version) = @_;

@@ -143,10 +154,16 @@
       return;
    }

+   $SIG{TERM} => \&close_dbh;
+   $SIG{PIPE} => \&close_dbh;
+   $SIG{QUIT} => \&close_dbh;
+
    eval {
       my $rbuf;

       while () {
+         last if $CLOSE;
+
          sysread $fh, $rbuf, 16384, length $rbuf
             or last;

@@ -169,6 +186,8 @@
             }
          }
       }
+
+      close_dbh;
    };
 }

@@ -400,8 +419,10 @@
               $INC{"AnyEvent/DBI.pm"};
          POSIX::_exit 124;
       } else {
-         ($_ != $serv_fno) && POSIX::close $_
-            for $^F+1..$FD_MAX;
+         unless (exists $self->{close_fds} and !$self->{close_fds}) {
+            ($_ != $serv_fno) && POSIX::close $_
+               for $^F+1..$FD_MAX;
+         }
          serve_fh $server, $VERSION;

          # no other way on the broken windows platform, even this leaks
@@ -612,7 +634,7 @@

 =cut

-for my $cmd_name (qw(exec attr begin_work commit rollback func)) {
+for my $cmd_name (qw(exec attr begin_work commit rollback func close)) {
    eval 'sub ' . $cmd_name . '{
       my $cb = pop;
       splice @_, 1, 0, $cb, (caller)[1,2], "req_' . $cmd_name . '";



/Jerry

--
Jerry Lundström - Software Engineer
.SE - The Internet Infrastructure Foundation
http://www.iis.se/

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 495 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://lists.schmorp.de/pipermail/anyevent/attachments/20130826/155fde79/attachment.sig>


More information about the anyevent mailing list