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

Reply via email to