> At 22:11 10/12/2000 +0100, Stas Bekman wrote:
> >Am I correct to say that it's wrong to tie the dbm file in startup.pl and
> >than share it across the children? 
> > [snip]
> >I think that unexpected things may happen since %My::Tied::btree has only
> >one file descriptor, and different processes accessing the dbm file at the
> >same time will mess it up, since the dbm iterator (or think of it as
> >seek() ) will jump wildly to satisfy requests from different processes and
> >wrecking havoc with methods like keys(), each() and similar...
> >
> >Am I correct here? If so there is a bad suggestion in the guide which
> >should be corrected :(
> 
> I don't know whether or not you're correct as I haven't tested this (which
> I guess is the only way to really know :). I don't much about fd's either,
> but one thing that I think could cause trouble is indeed each() and keys(),
> and this applies to any kind of tied hash, not just dbm tied hashes. Behind
> the scenes, each() is implemented in tied interface through FIRSTKEY() and
> NEXTKEY(). Typically, those two methods will do some housekeeping in order
> to emulate a rational behaviour for each().
> 
> Say for instance you have a tied hash that's internally represented as an
> array (for whatever reason). The first time you call each() on your tied
> hash, it will call FIRSTKEY(). FIRSTKEY will return the first element of
> the array, and in order for NEXTKEY() to know what it must return, it will
> set an attribute of the tied object to 0, ie the position in the array of
> the element that was last returned. The next time each() is called,
> NEXTKEY() will return the next element and increment that attribute, and so
> on until there are no elements left and NEXTKEY returns undef. If another
> process jumps in and FIRSTKEY is called again while the first one is
> accessing the keys, the attribute will get reset, and then it will call
> NEXTKEY too and you will get strange increments.

Yup, that's exactly what I was talking about without going into details
:) thanks for expanding on this!

> This does not affect cases where you'd never call each() or keys(), but you
> see the kind of mess one could get into. However, in order to avoid a tie()
> on all requests it might be possible to put the tie()ing code inside a
> ChildInitHandler (untested).

I suppose that this is pretty much what should be advised. It doesn't give
you much benefit anyway to have only one shared fd, since the data is in
the dbm files and it's not shared per se. The situation is of course
different if you copy the whole dbm into a memory. Then it makes sense to
do it once for all processes to share (read-only case).


_____________________________________________________________________
Stas Bekman              JAm_pH     --   Just Another mod_perl Hacker
http://stason.org/       mod_perl Guide  http://perl.apache.org/guide 
mailto:[EMAIL PROTECTED]   http://apachetoday.com http://logilune.com/
http://singlesheaven.com http://perl.apache.org http://perlmonth.com/  


Reply via email to