I’ve been using flock(2) — a system call for advisory locking — in a library I’ve been porting to Rust. The original library ran only on Linux but I wanted to support macOS too, so I set about checking my assumptions.
Ubuntu 17.04’s man page for flock(2) says:
A process may hold only one type of lock (shared or exclusive) on a file. Subsequent flock() calls on an already locked file will convert an existing lock to the new lock mode.
macOS Sierra’s man page for flock(2) says:
A shared lock may be upgraded to an exclusive lock, and vice versa, simply by specifying the appropriate lock type; this results in the previous lock being released and the new lock applied (possibly after other processes have gained and released the lock).
To me this reads that, on Linux, we can switch between shared and exclusive locks without losing out to another process1 that’s trying to grab an exclusive lock.
But on macOS it reads like other processes will be able to wriggle in.
This rang little alarm bells, so I investigated some more. It turned out to make sense in the end and be consistent between the platforms, but have more nuanced behaviour than the man pages hint at.
I also had the feeling that I’ve investigated this before, so this time I’m writing it down.[Read More]