Sign in to PrePAN

Lock::Socket application lock/mutex module based on sockets



### Function API
use Lock::Socket qw/lock_socket try_lock_socket/;

# Raises exception if cannot lock
my $lock = lock_socket(15151);

# Or just return undef
my $lock2 = try_lock_socket(15151) or
    die "handle your own error";

### Object API
use Lock::Socket;

# Create a socket
my $sock = Lock::Socket->new(port => 15151);

# Lock or raise an exception

# Can check its status in case you forgot
my $status = $sock->is_locked; # 1 (or 0)

# Re-locking changes nothing

# New lock on same port fails
my $sock2 = Lock::Socket->new(port => 15151);
eval { $sock2->lock }; # exception

# But trying to get a lock is ok
my $status = $sock2->try_lock;       # 0
my $same_status = $sock2->is_locked; # 0

# If you need the underlying filehandle
my $fh = $sock->fh;

# You can manually unlock
# ... or unlocking is automatic on scope exit
undef $sock;


Lock::Socket provides cooperative inter-process locking for applications that need to ensure that only one process is running at a time. This module works by binding an INET socket to a port on a loopback ( address which the operating system conveniently restricts to a single process.

The "lock_socket()" and "try_lock_socket()" functions both take a mandatory port number and an optional IP address as arguments, and return a Lock::Socket object on success. "lock_socket()" will raise an exception if the lock cannot be taken whereas "try_lock_socket()" will return "undef".

Objects are instantiated manually as follows:

    port => $PORT, # required
    addr => $ADDR, # defaults to 127.X.Y.1

On most systems the $PORT number needs to be greater than 1024 unless you are running as root.

If $ADDR is not provided then it is calculated as follows:

Octet   Value
------  ------------------------------
1       127
2       First byte of user ID
3       Second byte of user ID
4       1

This scheme provides something of an automatic per-user lock for a given $PORT, provided there is no user ID greater than 65536. The calculated address can be read back via the "addr()" method.

As soon as the Lock::Socket object goes out of scope the port is closed and the lock can be obtained by someone else.

If you want to keep holding onto a lock socket after a call to "exec" (perhaps after forking) read about the $^F variable in perlvar, as you have to set it before creating a lock socket to ensure the it will not be closed on exec. See the example/solo file in the distribution for a demonstration:

usage: solo PORT COMMAND...

# terminal 1
example/solo 1414 sleep 10  # Have lock on

# terminal 2
example/solo 1414 sleep 10  # bind error


Please sign up to post a review.