(I apologize in advance for the horrible line wrapping my mailer will do.)
Stas Bekman [mailto:[EMAIL PROTECTED]] wrote:
> > Now you have a concern with upgrading locks from shared to exclusive:
> >
> > > David, please consider this scenario:
> > >
> > > ... At some point in time, processes A and B both read from the dbm
via SH
> > > lock.
> > >
> > > 1. A completes its reading and unlocks the DBM, while still having the
> > > first 4k cached. (A still has the dbm tie()'d.
> > >
> > > 2. B wants to write, so it requests an EX lock and gets it granted.
> >
> > This will not happen. When B requests the EX lock it will block until
all of
> > the other shared locks have been released. Process A has to release the
SH
> > lock somehow for B to get the EX lock. Either A simply finishes and
releases
> > the lock, or A requests an upgrade, is denied, and handles this by
releasing
> > the lock.
>
> That's if you code it that way. Nothing prevents you from unlocking A, and
> then asking for some lock later. You always want to make the critical
> section as short as possible. So if you need to access the dbm file twice
> through the request. You may go through this scenario:
>
> A: flock SH
> B: flock SH
> A: flock UN
> B: flock EX
> B: flock SH
> A: flock SH
>
> 'A' still have the data cached and possibly invalid.
>
> Your proposed system is clean only in this case:
>
> You can never explicitly unlock dbm and then relock it without calling
> untie(). You can safely upgrade the lock from SH to EX and downgrade from
> EX to SH though, without using UN (sort of semi-atomically).
Perhaps we have a misunderstanding here. I would NEVER flock(UN) without
having just previously untie()d the database. And I would ALWAYS acquire a
lock immediately before tie()ing the database.
I would never drop the lock while keeping the database open (but not writing
to it) and then reacquire a lock at a later date and start reading or
writing the database. Perhaps this _could_ be done in some cases (even
though it seems it invalidate the whole idea of a lock on a resource IMHO),
however, since sync() does not re-read data from disk it can't be done in
this case.
When I said:
}} Process A has to release the SH
}} lock somehow for B to get the EX lock. Either A simply finishes and
releases
}} the lock, or A requests an upgrade, is denied, and handles this by
releasing
}} the lock.
I assumed that the if A releases the SH lock, it has closed the database.
Releasing the lock is a guarantee that A no longer has the database open. If
A at some future time reacquires a lock, it then just reopen the database.
> > When the EX lock is granted (whether from an upgrade or not), by
definition
> > no other processes can have a SH lock and be reading the database. No
other
> > processes can have a first 4k cached because no other processes can have
the
> > file open.
>
> They can, if there weren't untie()d per my above explanation.
Just don't unlock without untie()ing first and you are fine.
Like I said, this was my assumption, just never stated. Sorry for not being
clear.
David Harris
President, DRH Internet Inc.
[EMAIL PROTECTED]
http://www.drh.net/