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.