in reply to Re: Order of flock and open
in thread Order of flock and open

You are absolutely right -- you must watch out in this case. Most of the other replies don't bring up the fact that you must lock the entire process (read/write/rename). If you do this with a separate file, it is rather straightforard.

UPDATE: merlyn is right that the "code" below is fishy and should not be used. Take it as an example of what can go wrong if you try to get too tricky with locking. There are almost always conditions you will overlook (as I have.)

That said, I believe you can do this by locking both files, but you must pay attention to the order you perform the operations. You should be able to do the following in order...

open and lock the input file open lock the output file read the input file write the output file rename the input file rename the output file close both files (which unlocks them) delete old renamed input file

I'm not sure this works on all operating systems, but should work for Unix/Linux. You must use a non-blocking lock for the input file and you must close/reopen it in a loop if it is already locked. This is because someone can completely replace the input file before you get the lock for it and then your open file descriptor is pointing to the old stale (possibly deleted) input file. You should probably also use unique names (i.e. that don't collide with other processes) for the output file and the old input file.

This all seems rather complicated, which is why locking a separate file is much simpler. But, YMMV...

bluto

Replies are listed 'Best First'.
•Re: Re: Re: Order of flock and open
by merlyn (Sage) on Apr 30, 2003 at 20:12 UTC
      I agree that it is fishy and I would never use it in practice (the reason for the lack of real code and the disclaimer in the last line of the post) since over the years I've learned that once you start messing around with operation ordering too much, and start requiring non-blocking locks, chances are good the locking strategy is incorrect.

      That said, I'm not entirely convinced that it can't be fixed, perhaps by using only a single rename, only that it isn't worth it. Your solution is more elegant in any case.

      bluto