LCFG::Lock - Perl routines to lock/unlock component semaphore
This documentation refers to LCFG::Lock version 1.20.8
use LCFG::Lock;
# Create a lock object
my $lock = LCFG::Lock->new( $comp_name );
# Acquire the semaphore
$lock->acquire();
# Relinquish the semaphore
$lock->relinquish();
The LCFG::Lock class can be used to prevent multiple simultaneous executions of LCFG component methods.
The semaphore is based on the simple existence of a file with the specified component name. The semaphore file contains the process identifier (PID) of the owner process and the timestamp of when it was created. Waiting processes will have a lock file named like component.PID
in the same directory, that will be hardlinked to the semaphore filename upon successful locking. Note that this use of hard links means that it will not work on filesystems where that is not supported (e.g. distributed filesystems such as AFS).
By default the process of acquiring a lock will wait forever but it can be configured to not block or to fail after a certain has been exceeded. If a stale lockfile is detected then it will be removed.
The process of relinquishing a lock can be configured to forcibly break any existing lock, rather than just a lock for the current process.
It is important to note that if a lock has been acquired then when the Perl lock object goes out of scope the lockfile will be removed automatically. This is designed for when your code dies between the calls to acquire
and relinquish
to make error handling easier.
Creates a new instance of a lock object for the specified LCFG component name. It is important to note that this does NOT create the semaphore lock file, that happens when the acquire
method is called.
This optionally takes a hash of extra parameters which will alter the lock file used:
Use the specified process ID, note that this must be an integer. Otherwise the default is the value of the PID for the parent process as returned by the getppid(2) function.
A message which should be inserted into the lock file when the lock is acquired. This is used by LCFG::Component to record the name of the component method being called.
Use an alternative lock directory, note that this location must already exist and be writable, it must also be located in a filesystem which supports hardlinks. The default directory location is found using the CompLockDir
method in the LCFG::Client::FileLocator
class.
By default when a lock file has been acquired and the last reference to the Perl object goes out of scope the lock file is removed. This behaviour can be avoided by setting the cleanup parameter to a defined-but-false value (e.g. zero).
This method can be used to acquire the semaphore lock file for the specified combination of LCFG component and process ID. Firstly, a file is created in the target directory named like comp_name.pid
, that file contains the process ID and the time of creation. Secondly, an attempt is made to hardlink this file to the target lock file. If the linking fails because the lock file already exists but the lock is stale it will be removed and another attempt will be made. Otherwise the response to a link failure will depend on the settings for the block and timeout parameters. By default the method will block forever awaiting a chance to successfully acquire the lock.
If the hardlink fails for any reason other than due to being owned by another active process (e.g. permissions issues) this method will die.
If no-block has been requested or a timeout is reached this method will die.
The behaviour of the lock acquisition method can be altered by passing a reference to a hash of the following supported parameters:
By default the method will block until a timeout is reached (or forever) awaiting a chance to successfully acquire the lock. To change this behaviour so that only a single attempt at locking is made set this parameter to a defined-but-false value (e.g. zero).
The time in seconds after which the attempt to acquire the lock will fail. By default this is set to zero which means that the method will wait forever.
The time in seconds to wait between attempts to acquire the lock. The default is 1 second.
This option can be set to a true value to have additional debugging messages sent to STDERR.
When this is set to a true value the method will not fail if the lock file has already been successfully acquired for the specified LCFG component and process ID.
This option can be set to a true value to have information about any time spent waiting sent to STDERR.
This method can be used to remove the semaphore lock file for the specified LCFG component and process ID.
If the file cannot be removed for any reason other than it no longer exists (e.g. permissions issues) this method will die.
If the file exists but is not owned by the specified process ID this method will die (unless the break parameter is specified).
The behaviour of the lock relinquish method can be altered by passing a reference to a hash of the following supported parameters:
If this option is set to a true value then the lock file will be removed if it exists but does not belong to the specified process ID.
This option can be set to a true value to have additional debugging messages sent to STDERR.
When this is set to a true value the method will not fail if the lock file has already been removed.
Read/Write accessor for the cleanup attribute.
LCFG::Component(3), lcfg-ngeneric(8), lcfglock(8)
This module requires LCFG::Profile::Component(3) and Try::Tiny(3). The LCFG::Client::FileLocator(3) class will also be used if the lock directory is not explicitly specified.
This is the list of platforms on which we have tested this software. We expect this software to work on any Unix-like platform which is supported by Perl.
ScientificLinux6, EnterpriseLinux7, MacOSX
Please report any bugs or problems (or praise!) to bugs@lcfg.org, feedback and patches are also always very welcome.
Stephen Quinney <squinney@inf.ed.ac.uk>, Paul Anderson <dcspaul@inf.ed.ac.uk>
Copyright (C) 2001-2019 University of Edinburgh. All rights reserved.
This library is free software; you can redistribute it and/or modify it under the terms of the GPL, version 2 or later.