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: 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> 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? >>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
