Re: using cdb for 'update' without race condition?

ari edelkind <[email protected]> Fri, 11 Apr 2008 09:34:08 -0400
Newsgroups gmane.comp.djb.cdb
Message-ID <[email protected]>
[email protected] wrote:

> ari edelkind <[email protected]> wrote:
> > Actually, the output file to which i was referring becomes the new
> > master file, not the new database file.
> 
> Locking that won't work either.  The lock file must never be renamed,
> or else you can have two processes locking different files (even if
> they had the same name at different times), and both proceeding
> concurrently.

Of course it would work.  And that's correct, you would not rename the
lock file while the lock is active, unless your intent is to invalidate
the lock by doing so.  There's nothing in "you'd use the same name every
time" to suggest that the lock file would be arbitrarily named.

Here's a basic example (no error checking), implemented in ksh.
Perhaps this will clarify things for you.


The scenario:
- You have a compiled cdb file.
- You do not have the source.
- You want to alter the contents in some way.
----------------------------------------
#!/usr/bin/ksh

CDB_DIR="/path/to/db/subdir"
CDB_FILE="$CDB_DIR/file.cdb"
REMASTER_FILE="$CDB_DIR/file.remaster"

set -o noclobber

while ! (exec >"$REMASTER_FILE") 2>&-
do
	sleep 1
done

cdbdump <"$CDB_FILE" | alter_cdb_data >| "$REMASTER_FILE"
cdbmake "$CDB_FILE" "$CDB_FILE.tmp" <"$REMASTER_FILE"
rm -f "$REMASTER_FILE"  # or rename it for a history log

# Note: you could dump the cdb file in one operation instead, using
#     cat "$CDB_FILE" |cdbdump |... >"$REMASTER_FILE"
# in the 'while' statement (in which case ksh would open the output file
# before executing the initial `cat`), but the semantics are less
# obvious.
----------------------------------------

ari