On Mon, Sep 30, 2002 at 08:01:54PM -0400, Matthew O. Persico wrote: > On Mon, 30 Sep 2002 09:56:20 +0100, Tim Bunce spaketh: > >On Sun, Sep 29, 2002 at 06:37:01PM -0400, Matthew O. Persico wrote: > > [snippage] > > >Q: How do I share a database handle between a parent and its child > >process? ??? > > > >You should distinguish between "share" and "pass". Many > >drivers/database > >will work well in the child after a fork() so long as the parent > >doesn't do anything with the handle (including destroying it). > >See the InactiveDestroy attribute. > > > >As for sharing a handle (where both processes try to use it), > >I'm not aware of any drivers where that would work. > > You are correct. I was writting in the more strict form because I didn't really want >to get into a too-detailed discussion of the difference. But better to be accurate >than over-protective. I will re-phrase the question as: > > Can I share or pass a database handle between a parent and its child processes? > > The answer will boil down to > > <answer> > Only if you're really careful and follow these rules:
s/Only/Maybe/ > You may only pass it to one child at a time. (Just as a parent and a child cannot >"share", certainly two children can't either.) > > The parent cannot use it, not even to destroy it after it is used by the child, not >even when the child is complete. > </answer> Mention InactiveDestroy as well. > Thought experminent: > Now, although I'm not putting this into the FAQ and I have no idea why you'd want to >do this, but what if you serialized the handle in the child (Data::Dumper or >Storable), passed the string back to the parent (open pipe communication) and set >InactivateDestroy in the child. Could you somehow thaw that string into the parent's >handle and carry on? No. Much magic is hidden behind a DBI handle. Tim. > > > >>Q: How do I share a database handle between threads of a single > >>process? > > > >The same "share" vs "pass" distinction should be made here. > > > >>A: Carefully. You share a database connection in the same manner as > >>you share any other piece of data, carefully locking the handle > >>before accessing it and releasing it after accessing it. HOWEVER, > >>before you can use a particular DBD:: module in a threaded > >>environment, you must determine if the underlying client libraries > >>are thread safe. > > > >DBI handles can't be passed between threads using threads::shared > >(same goes for all extensions that attache 'magic' to perl > >variables). > > > >Handles can be 'inherited' by child threads. However, the DBI > >currently treats any use of an inherited handle as an error > >(because there's no way to guarantee that internal pointers within > >the handle that refer to DBI and driver data structures have been > >updated to > >refer to the cloned copies owned by the new thread). > > > >The curent recommended approach is for drivers to be extended to > >support a new connection attribute that passes a reference to a > >threads::shared variable. If the value of the variable is undef > >then the driver updates it with information about the internal > >pointers being used. If the variable not undef then the contents > >are used to populate the internal pointers rather than making calls > >to the database API. In this way multiple distinct DBI handles can > >refer to the same database connection, for example. > > > >However, those handles can't be used at the same time unless the > >database API is fully thread safe. Few are. > > I just might include that verbatim in that answer. Is that OK by you (with proper >credit attached)? > > -- > Matthew O. Persico > >
