MCE
view release on metacpan or search on metacpan
lib/MCE/Signal.pm view on Meta::CPAN
}
sub defer {
$MCE::Signal::SIG = $_[0] if $_[0];
return;
}
my %_sig_name_lkup = map { $_ => 1 } qw(
__DIE__ ABRT HUP INT PIPE QUIT TERM __WARN__
);
my $_count = 0;
my $_handler_count = $INC{'threads/shared.pm'}
? threads::shared::share($_count)
: \$_count;
sub stop_and_exit {
shift @_ if (defined $_[0] && $_[0] eq 'MCE::Signal');
return MCE::Signal::defer($_[0]) if $MCE::Signal::IPC;
my ($_exit_status, $_is_sig, $_sig_name) = ($?, 0, $_[0] || 0);
$SIG{__DIE__} = $SIG{__WARN__} = sub {};
if (exists $_sig_name_lkup{$_sig_name}) {
$_exit_status = $MCE::Signal::KILLED = $_is_sig = 1;
$_exit_status = 255, $_sig_name = 'TERM' if ($_sig_name eq '__DIE__');
$_exit_status = 0 if ($_sig_name eq 'PIPE');
$SIG{INT} = $SIG{$_sig_name} = sub {};
}
else {
$_exit_status = $_sig_name if ($_sig_name =~ /^\d+$/);
$MCE::Signal::STOPPED = 1;
}
## Main process.
if ($$ == $main_proc_id) {
if (++${ $_handler_count } == 1) {
## Kill process group if signaled.
if ($_is_sig == 1) {
($_sig_name eq 'PIPE')
? CORE::kill('PIPE', $_is_MSWin32 ? -$$ : -getpgrp)
: CORE::kill('INT' , $_is_MSWin32 ? -$$ : -getpgrp);
if ($_sig_name eq 'PIPE') {
for my $_i (1..2) { Time::HiRes::sleep(0.015); }
} else {
for my $_i (1..3) { Time::HiRes::sleep(0.060); }
}
}
## Remove temp directory.
_remove_tmpdir() if defined($tmp_dir);
## Signal process group to die.
if ($_is_sig == 1) {
if ($_sig_name eq 'INT' && -t STDIN) { ## no critic
print {*STDERR} "\n";
}
if ($INC{'threads.pm'} && ($] lt '5.012000' || threads->tid())) {
($_no_kill9 == 1 || $_sig_name eq 'PIPE')
? CORE::kill('INT', $_is_MSWin32 ? -$$ : -getpgrp)
: CORE::kill('KILL', -$$);
}
else {
CORE::kill('INT', $_is_MSWin32 ? -$$ : -getpgrp);
}
}
}
}
## Child processes.
elsif ($_is_sig) {
## Windows support, from nested workers.
if ($_is_MSWin32) {
_remove_tmpdir() if defined($tmp_dir);
CORE::kill('KILL', $main_proc_id, -$$);
}
## Real child processes.
else {
CORE::kill($_sig_name, $main_proc_id, -$$);
CORE::kill('KILL', -$$, $$);
}
}
## Exit with status.
CORE::exit($_exit_status);
}
###############################################################################
## ----------------------------------------------------------------------------
## Run command via the system(...) function.
##
## The system function in Perl ignores SIGINT and SIGQUIT. These 2 signals
## are sent to the command being executed via system() but not back to
## the underlying Perl script. The code below will ensure the Perl script
## receives the same signal in order to raise an exception immediately
## after the system call.
##
## Returns the actual exit status.
##
###############################################################################
sub sys_cmd {
shift @_ if (defined $_[0] && $_[0] eq 'MCE::Signal');
_croak('MCE::Signal::sys_cmd: no arguments were specified') if (@_ == 0);
my $_status = system(@_);
my $_sig_no = $_status & 127;
my $_exit_status = $_status >> 8;
## Kill the process group if command caught SIGINT or SIGQUIT.
CORE::kill('INT', $main_proc_id, $_is_MSWin32 ? -$$ : -getpgrp)
if $_sig_no == 2;
CORE::kill('QUIT', $main_proc_id, $_is_MSWin32 ? -$$ : -getpgrp)
( run in 0.547 second using v1.01-cache-2.11-cpan-a49fcb8fa48 )