Mutual exclusion between processes using flock and lockf. A file is considered locked if either of these mechanisms works.
These locks are OS-level but are Local (will not work across computers even if they mount the same directory).
create ?close_on_exec ?message path
tries to create a file at path
containing the
text message
, which defaults to the pid of the locking process. It returns true on
success, false on failure. Note: there is no way to release the lock or the fd
created inside! It will only be released when the process dies. If close_on_exec is
false, then the lock will not be released until children created via fork and exec
also terminate. If not specified, close_on_exec=true. Note that by default, the lock
file is not cleaned up for you when the process exits. If you pass
unlink_on_exit:true
, an at_exit handler will be set up to remove the lock-file on
program termination.
The lock file is created with mode 664, so will not be world-writable even with umask 0.
create_exn ?message path
is like create
except that it throws an exception on
failure instead of returning a boolean value
blocking_create t
tries to create the lock. If another process holds the lock this
function will wait until it is released or until timeout expires.
is_locked path
returns true when the file at path
exists and is locked, false
otherwise. Requires write permission for the lock file.
An implementation neutral NFS lock file scheme that relies on the atomicity of link over NFS (see NFS Illustrated, atomicity for more information). Rather than relying on a working traditional advisory lock system over NFS we create a hard link between the file given to the create call and a new file <filename>.nfs_lock. This link call is atomic (in that it succeeds or fails) across all systems that have the same filesystem mounted. The link file must be cleaned up on program exit (normally accomplished by an at_exit handler, but see caveats below).
There are a few caveats compared to local file locks:
Use cases outside of this may push on/break assumptions used for easy lock cleanup/taking and may lead to double taking the lock. If you have such an odd use case you should test it carefully/consider a different locking mechanism.
create ?message path
tries to create and lock the file at path
by creating a hard
link to path
.nfs_lock. The contents of path
will be replaced with a sexp
containing the caller's hostname and pid, and the optional message
.
Efforts will be made to release this lock when the calling program exits. But there is no guarantee that this will occur under some types of program crash. If the program crashes without removing the lock file an attempt will be made to clean up on restart by checking the hostname and pid stored in the lockfile.
create_exn ?message path
like create, but throws an exception when it fails to
obtain the lock
blocking_create ?message path
like create, but sleeps for 1 second between lock
attempts and does not return until it succeeds or timeout expires. Timeout defaults
to wait indefinitely
critical_section ?message ~timeout path ~f
wrap function f
(including exceptions
escaping it) by first locking (using blocking_create) and then unlocking the
given lock file.
get_hostname_and_pid path
reads the lock file at path
and returns the hostname
and path in the file. Returns None
if the file cannot be read.
get_message path
reads the lock file at path
and returns the message in the
file. Returns None
if the file cannot be read.
unlock_exn path
unlocks path
if path
was locked from the same host and the pid
in the file is either the current pid or not the pid of a running process. It will
raise if for some reason the lock at the given path cannot be unlocked, for example
if the lock is taken by somebody else that is still alive on the same box, or taken
by a process on a different host, or unix permissions issues, etc. This function
should be used only by programs that need to release their lock before exiting. If
releasing the lock can or should wait till the end of the running process, do not
call this function -- this library already takes care of releasing at exit all the
locks taken.