Further review and thoughts on this...

Each thread using the DBI directly must have it's own DBI instance,
either loaded itself or cloned from parent thread, because handles
can't be shared or passed across threads or between parent and child.
So each threads needs to have it's own connection to the database.

The DBI needs a CLONE sub to 'isolate' the cloned dbistate struct
from the parent by creating a new one, initializing it, and doing
sv_setiv(get_sv(DBISTATE_PERLNAME,1), (IV)DBIS); to 'publish' the new
address.

The DBI_LOCK mutex can be removed because it's not needed now there's
only one thread using an instance of the dbistate struct.

Add the 'owner' thread id to the dbistate struct.

The dbi_last_h should be moved into the dbistate struct (but that
can wait as it's not really related to threads, just a cleanup).

%DBI::installed_drh holds the handles of loaded drivers.
It needs to be cleared by the CLONE sub so that the next connect()
will re-call the drivers driver() method to get a new driver handle
that's associated with the new instance of the DBI for that thread.

To make that work each driver needs a CLONE sub that clears the
$drh variable that holds the drivers own driver handle.

To check that drivers have actually done that, the DBI's setup_handle
function can check the current thread id matches the thread id in
the dbistate struct. If not then warn.

I've probably missed stuff here but I'm pretty sure it's in the
right direction.

Tim.

Reply via email to