Everything you never wanted to know about file locking
apenwarr.ca
apenwarr.ca
Note that all of these locking schemes fall down hard on NFS, depending on client and server, regardless of what any man pages say about support. Homework question: How does a stateless protocol like NFS remember when one client locks a file and a different client tries locking it?
The failure mode on NFS can vary from "lock always succeeds, regardless of actual status" to "lock always fails, hanging forever", or my favorite, "locks work, unless your process crashes, and then you can never lock that file again until you reboot the NFS server".
Still not convinced [that you shouldn't use mandatory locking]? Man, you really must like punishment. Look, imagine someone is holding a mandatory lock on a file, so you try to read() from it and get blocked. Then he releases his lock, and your read() finishes, but some other guy reacquires the lock. You fiddle with your block, modify it, and try to write() it back, but you get held up for a bit, because the guy holding the lock isn't done yet. He does his own write() to that section of the file, and releases his lock, so your write() promptly resumes and overwrites what he just did.
If you're going to read some data and then potentially write modified data back over what you just read, shouldn't the first step before you even read it be to get a lock on the file or that range? Or, if your calculation might take a long time, at least get a lock right before you write it back, verifying first that you're writing over data that hasn't changed while you were off calculating?
But I'm pretty sure I'm misunderstanding what the author was trying to say.
Also, mandatory locks are used in Windows. Ever try to delete that virus.exe while it's still running? Yeah.
[1] acquire lock for maximum level of operations you might need and hold it all the way through to completion, or to avoid holding a lock on the object for too long, get and release multiple locks verifying as needed that the data hasn't changed each time
"I guess lockfiles are the answer after all."
Yup. Don't use the locking APIs. Just use lockfiles be done with it.
I'd actually go a step further and suggest only using lock directories. Using lockfiles assumes O_CREAT|O_EXCL works properly everywhere (which is probably a safe assumption, but...). mkdir() will return EEXIST if you fail to acquire the 'lock'.
This is apparently because some versions of Windows don't understand shared locks
Which versions? It seems even the Windows 95 had FILE_SHARE_READ and FILE_SHARE_WRITE which are effectively shared locks (it just didn't have the FILE_SHARE_DELETE)