On Sat, Apr 09, 2005 at 01:08:40AM -0400, Stas Bekman wrote:
> Tim,
> 
> I've a pretty well working prototype now. There is one problem though.
> 
> Before take_imp_data can be called all $sth must be destroyed. for example 
> the following code:
> 
>     my $dbh = DBI->connect('dbi:mysql:test', '', '', {});
>     my $sth0 = $dbh->prepare("show tables");
>     $sth0->execute();
>     while (my @row = $sth0->fetchrow_array) {
>         $dbh->do("DROP TABLE $table") if $row[0] eq $table;
>     }
>     $dbh->disconnect;
> 
> fails:
> 
> DBD::mysql::db take_imp_data failed: Can't take_imp_data from handle while 
> it still has kids at /home/stas/work/modules/DBI-Pool/blib/lib/DBI/Pool.pm 
> line 96.
> 
> since I try to call take_imp_data in the overridden DBI::Pool::disconnect. 
> This fixes the problem in the caller script:
> 
>     undef $sth0;
>     $dbh->disconnect;
> 
> but it requires an unusual modification to the original script and 
> DBI::Pool should be able to work transparently to the user.
> 
> So how can we eliminate this problem?

Tricky. The risk is that child statement handles may contain pointers
to their parents data structures which may be used when the statement
handle is destroyed.

The restriction could be relaxed to check ActiveKids instead of Kids.
That would reduce the risk - but not eliminate it.

Another good thing to do would be to have take_imp_data not detach and
return the original imp_xxh structure, but make a copy, then zero out
(or poison?) the original one, before returning the copy. That way if
the statement handle DESTROY does try to access the parents imp_xxh
structure we'll find out about it very clearly :)

Feel free to make both those changes and see how it goes...

Tim.

Reply via email to