Thorium
view release on metacpan or search on metacpan
lib/Thorium/Utils.pm view on Meta::CPAN
$Thorium::Utils::VERSION = '0.510';
}
BEGIN {
$Thorium::Utils::AUTHORITY = 'cpan:AFLOTT';
}
# ABSTRACT: additional utilities
use Thorium::Protection;
# core
use Fcntl ':flock';
use FindBin qw();
use Time::HiRes qw();
# CPAN
use File::Slurp qw(read_file);
use IPC::Cmd qw();
use Params::Util qw();
use Proc::ProcessTable;
use Sub::Exporter;
my @funcs_names = qw(block_new_invocations unblock_new_invocations page execute already_running halt run);
Sub::Exporter::setup_exporter(
{
'exports' => \@funcs_names,
'groups' => {'default' => \@funcs_names}
}
);
our $Lock_FH;
our $Lock_Filename;
my %old_sig_int_handlers;
for my $sig_name (qw(INT TERM)) {
if ($SIG{$sig_name} && defined(&{$SIG{$sig_name}})) {
$old_sig_int_handlers{$sig_name} = $SIG{$sig_name};
}
}
# Allows the END {} block below to be called
sub _sig_handler {
my ($sig_name) = @_;
if ($old_sig_int_handlers{$sig_name}) {
$old_sig_int_handlers{$sig_name}->(@_);
}
die("Caught $sig_name, aborting\n");
}
local $SIG{'INT'} = \&_sig_handler;
local $SIG{'TERM'} = \&_sig_handler;
sub block_new_invocations {
my ($lock_file) = @_;
unless ($lock_file) {
my $username = getlogin || getpwuid($<) || 'unknown';
my $s = $FindBin::Script;
# clean up the filename so it's easier to read and Unix-safe
$s =~ s/[.\-]/_/g;
$s =~ s/[\{\[\(\<>)\]\}~\|\/]/_/g;
$s =~ s/[\p{Zs}\t]+/_/g;
$s =~ s/\&+/_and_/g;
$s =~ s/[^\p{Alphabetic}\p{Nd}\-\.\+_]//g;
$lock_file = sprintf('/tmp/thorium_utils_lock_file_%s_%s.lock', $username, $s);
}
if (-e $lock_file) {
die("The lock file, $lock_file, already exists, most likely this process ($FindBin::Script) is already running. If not, delete the file and run again.\n");
}
if ($Lock_FH && Params::Utils::_HANDLE($Lock_FH)) {
warn('The global file handle has already been initialized. Call Thorium::Utils::unblock_new_invocations() to release lock.');
return;
}
open($Lock_FH, '>', $lock_file) or die("Could not create/open lock file '$lock_file' - $!\n");
unless (flock($Lock_FH, LOCK_EX | LOCK_NB)) {
$Lock_FH = undef;
die("flock() failed - $!\n");
}
$Lock_Filename = $lock_file;
return $Lock_FH;
}
sub unblock_new_invocations {
if ($Lock_FH) {
flock($Lock_FH, LOCK_UN);
close($Lock_FH);
unlink($Lock_Filename);
}
return;
}
sub already_running {
my $filename = Params::Util::_STRING(shift(@_)) or die("Please pass the full file path to the pid file as the first argument to already_running()\n");
my $executable = Params::Util::_STRING(shift(@_)) or die("Please pass the full executable file path as the second argument to already_running()\n");
if (-e -r -s $filename) {
my $pt = Proc::ProcessTable->new;
my $pid = read_file($filename);
foreach my $p (@{$pt->table}) {
if ($p->pid == $pid && $p->cmndline =~ $executable) {
return 1;
}
}
}
( run in 1.506 second using v1.01-cache-2.11-cpan-39bf76dae61 )