On Thu, Jul 04, 2002 at 02:40:03PM +0200, Gerald Richter - ecos gmbh wrote:
> 
> So for now I have made a patch that makes DBI ithread safe, the way you
> suggested it. That means that every thread has it's own DBI enviroment and
> doesn't share any data or handles...

Great.

> > 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.
> 
> I didn't have removed anything of the old thread code, because I don't know
> if anybody using it.

The old perl5005 threading model is badly flawed and dangerous.
The DBI shouldn't support it now there's something better.
It's dead - rip it out!  Anyone still needing it can stick with DBI 1.28.

> thr_user is added which holds the pointer to the PerlInterpreter struct.
> thr_user in dbih_com_std_st is now also a PerlInterpreter pointer in case of
> USE_ITHREAD.

Do the safety checks you've put in work? Can you trigger them by
using an inherited handle in a new thread?


> > To make that work each driver needs a CLONE sub that clears the
> > $drh variable that holds the drivers own driver handle.
> 
> Yes, each driver needs
> 
>     sub CLONE {
>     $drh = undef ;
>     }
> 
> Addtionaly the driver must make sure it does not use any C globals.
> 
> If you see a message like
> 
> FATAL: DBI handle (type=1) is not owned by current thread in call to
> DBD::ODBC::dr::default_user (is 15d42a4, should 1c6c814)
> 
> then you properbly have fogotten to add this to the driver.

Can you change the message to be more like:

"%s %s failed: handle %s is owned by thread %x not current thread %x (handles can't be 
shared between threads and your driver may need a CLONE method added)"

where the first two %s's are HvNAME(DBIc_IMP_STASH(imp_xxh)), meth_name;


> The thing you missed and which had added me some new grey hairs is, that
> because all C structs are allocated as an SV, they also get cloned. A
> problem arises when Perl tries to destroy such a cloned handle. This always
> happens when you have any open handle, while the CLONE is happen. Perl
> clones the handle (there is no way to avoid this) and because we don't use
> it in the new thread/Perl interpreter it get's destroyed, but since Perl
> does a stupid copy of the C struct, the data still points to the old thread.
> So it segfaults. I have solved this problem, that in case DESTROY and/or a
> dbi_clearcom is called for a handle that doesn't belongs to the current
> thread, they just do nothing.

One day we might be able to do something clever with CLONE methods
added to DBI::_::common and DBI::_::common_mem. But that's a story
for another day.

> I append the patch. I have tested it with DBD::ODBC and DBD::Oracle on
> windows with Perl 5.8.0RC2. DBD::ODBC just needs to get the
> 
>     sub CLONE {
>     $drh = undef ;
>     }
> 
> added.

Great.

> DBD::Oracle needs addtionaly the patch I had send some days ago (I
> didn't had the time to implement the CLONE patch we have discussed for
> DBD::Orcale, because it's some more work, because I need to move the global
> variables into the driver or any other handle to make it threads safe)

I may be working on Oracle in the next week or so. If you get the time
then a fresh (complete) patch would be great.

> I have written a small test program that starts an increasing number of
> threads which do some random database operations.
> It's a quick and dirty script, but I also append it. Maybe it usefull for
> somebody.
> 
> Any comments are welcome :-)

This is great work Gerald!

Keep it up!  :-)

Tim.

Reply via email to