This commit improves brings two improvements to the lock file
implementation:
1. Support for long-lived locks.
2. Support for non-blocking lock acquisition.
There are now two types of lock file classes: ShortLivedLockFile and
LongLivedLockFile. On Windows the implementations are identical. On
other systems, LongLivedLockFile creates a separate "alive file" whose
mtime will be updated regularly by a helper thread until the lock is
released. This makes it possible for another process to wait for the
lock indefinitely but also to know then a lock is stale and can be
broken. The ShortLivedLockFile class works like the lock file class used
to work before: it considers a lock stale after waiting for two seconds
and noticing that the symlink target has not changed during that time.
ShortLivedLockFile is to be used when the lock is expected to be held
for a very short time so that it's a waste of resources to start a
helper thread to keep the lock alive.
On some systems it would be possible to update mtime of the symlink
itself instead of a separate file, but that does not seem to be portable
enough.
Also worth mentioning is that the reason to not use proper fcntl/flock
locks on non-Windows systems is to continue supporting a cache directory
on NFS since file locks on NFS don't have a good track record.