NAME

Dir::Flock - advisory locking of a dedicated directory

VERSION

0.01

SYNOPSIS

use Dir::Flock;
my $dir = Dir::Flock::getDir("/home/mob/projects/foo");
my $success = Dir::Flock::lock($dir);
# ... synchronized code
$success = Dir::Flock::unlock($dir);

DESCRIPTION

Dir::Flock implements advisory locking of a directory. The use case is to execute synchronized code (code that should only be executed by one process or thread at a time) or provide exclusive access to a file or other resource. Dir::Flock has more overhead than some of the other synchronization techniques available to Perl programmers, but it might be the only technique that works on NFS (Networked File System).

Algorithm

File locking is difficult on NFS because, as I understand it, each node maintains its own cache of filesystem contents. When a system call checks whether a lock exists on a file, the filesystem driver might just inspect the cached file rather than the file on the server, and it might miss an action taken by another node to lock a file.

The cache is not used, again, as I understand it, when the filesystem driver reads a directory. If advisory locking is accomplished through reading the contents of a directory, it will not be affected by NFS's caching behavior.

To acquire a lock in a directory, this module writes a small file into the directory. Then it checks if this new file is the "oldest" file in the directory. If it is the oldest file, then the process has acquired the lock. If there is already an older file in the directory, than that file specifies what process has a lock on the directory, and we have to wait and try again later. To unlock the directory, the module simply deletes the file in the directory that represents its lock.

FUNCTIONS

lock

$success = Dir::Flock::lock( $directory [, $timeout ] )

Attempts to obtain an exclusive lock on the given directory. While the directory is locked, the lock call on the same directory from other processes or threads will block until the directory is unlocked (see "unlock"). Returns true if the lock was successfully acquired.

If an optional $timeout argument is provided, the function will try for at least $timeout seconds to acquire the lock, and return a false value if it is not successful in that time. Use a timeout of zero to make a "non-blocking" lock request.

unlock

$success = Dir::Flock::unlock( $directory )

Releases the exclusive lock on the given directory held by this process. Returns a false value if the current process did not possess the lock on the directory.

getDir

$tmp_directory = getDir( $root )

Creates a temporary and empty directory in a subdirectory of $root that is suitable for use as a synchronization object. The directory will automatically be cleaned up when the process that called this function exits.

flock

$success = flock( $dir, $op )

If you prefer the semantics of "flock" in perlfunc, the flock function from this package provides them in terms of the "lock" and "unlock" functions. Shared locks are not supported in this version.

LIMITATIONS

Requires a version of Time::HiRes with the stat function, namely v1.92 or better (though later versions seem to have some fixes related to the stat function). Requires operating system support for subsecond file timestamp (output &Time::HiRes::d_hires_stat and look for a positive value to indicate that your system has such support) and filesystem support (FAT is not likely to work).