2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-02-07 23:09:26 +00:00

Blocking.pm: Fix race condition (not verified)

git-svn-id: https://svn.fhem.de/fhem/trunk@15200 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig 2017-10-05 08:27:30 +00:00
parent 41ae2c72f7
commit 5e5b5b0796

View File

@ -23,7 +23,7 @@ use IO::Socket::INET;
sub BlockingCall($$@); sub BlockingCall($$@);
sub BlockingExit(); sub BlockingExit();
sub BlockingKill($); sub BlockingKill($);
sub BlockingInformParent($;$$); sub BlockingInformParent($;$$$);
sub BlockingStart(;$); sub BlockingStart(;$);
our $BC_telnetDevice; our $BC_telnetDevice;
@ -82,7 +82,8 @@ BlockingInfo($$@)
my $fn = (ref($h->{fn}) ? ref($h->{fn}) : $h->{fn}); my $fn = (ref($h->{fn}) ? ref($h->{fn}) : $h->{fn});
my $arg = (ref($h->{arg}) ? ref($h->{arg}) : $h->{arg}); my $arg = (ref($h->{arg}) ? ref($h->{arg}) : $h->{arg});
my $to = ($h->{timeout} ? $h->{timeout} : "N/A"); my $to = ($h->{timeout} ? $h->{timeout} : "N/A");
push @ret, "Pid:$h->{pid} Fn:$fn Arg:$arg Timeout:$to"; my $conn= ($h->{telnet} ? $h->{telnet} : "N/A");
push @ret, "Pid:$h->{pid} Fn:$fn Arg:$arg Timeout:$to ConnectedVia:$conn";
} }
push @ret, "No BlockingCall processes running currently" if(!@ret); push @ret, "No BlockingCall processes running currently" if(!@ret);
return join("\n", @ret); return join("\n", @ret);
@ -135,7 +136,8 @@ BlockingStart(;$)
use POSIX ":sys_wait_h"; use POSIX ":sys_wait_h";
waitpid(-1, WNOHANG); # Forum #58867 waitpid(-1, WNOHANG); # Forum #58867
} }
if(!kill(0, $h->{pid})) { if(!kill(0, $h->{pid}) &&
(!$h->{telnet} || !$defs{$h->{telnet}})) {
$h->{pid} = "DEAD:$h->{pid}"; $h->{pid} = "DEAD:$h->{pid}";
if(!$h->{terminated} && $h->{abortFn}) { if(!$h->{terminated} && $h->{abortFn}) {
no strict "refs"; no strict "refs";
@ -184,6 +186,8 @@ BlockingStart(;$)
} }
# Child here # Child here
BlockingInformParent("BlockingRegisterTelnet", "\$cl,$h->{bc_pid}", 1, 1)
if($h->{abortFn});
no strict "refs"; no strict "refs";
my $ret = &{$h->{fn}}($h->{arg}); my $ret = &{$h->{fn}}($h->{arg});
use strict "refs"; use strict "refs";
@ -199,9 +203,20 @@ BlockingStart(;$)
} }
sub sub
BlockingInformParent($;$$) BlockingRegisterTelnet($$)
{ {
my ($informFn, $param, $waitForRead) = @_; my ($cl,$idx) = @_;
return 0 if(ref($cl) ne "HASH" || !$cl->{NAME} || !$defs{$cl->{NAME}} ||
!$BC_hash{$idx});
$BC_hash{$idx}{telnet} = $cl->{NAME};
$defs{$cl->{NAME}}{BlockingCall} = $BC_hash{$idx}{fn};
return 1;
}
sub
BlockingInformParent($;$$$)
{
my ($informFn, $param, $waitForRead, $noEscape) = @_;
my $ret = undef; my $ret = undef;
$waitForRead = 1 if (!defined($waitForRead)); $waitForRead = 1 if (!defined($waitForRead));
@ -216,12 +231,14 @@ BlockingInformParent($;$$)
} }
if(defined($param)) { if(defined($param)) {
if(ref($param) eq "ARRAY") { if(!$noEscape) {
$param = join(",", map { $_ =~ s/'/\\'/g; "'$_'" } @{$param}); if(ref($param) eq "ARRAY") {
$param = join(",", map { $_ =~ s/'/\\'/g; "'$_'" } @{$param});
} else { } else {
$param =~ s/'/\\'/g; $param =~ s/'/\\'/g;
$param = "'$param'" $param = "'$param'"
}
} }
} else { } else {
$param = ""; $param = "";