mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-16 16:56:04 +00:00
HttpUtils: extend timeout in blocking situations (Forum #54697)
git-svn-id: https://svn.fhem.de/fhem/trunk@11715 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
989445d5c2
commit
bdc12f8b12
@ -73,19 +73,21 @@ HttpUtils_Close($)
|
||||
}
|
||||
|
||||
sub
|
||||
HttpUtils_Err($$)
|
||||
HttpUtils_Err($)
|
||||
{
|
||||
my ($hash, $errtxt) = @_;
|
||||
$hash = $hash->{hash};
|
||||
my ($lhash, $errtxt) = @_;
|
||||
my $hash = $lhash->{hash};
|
||||
|
||||
if($lhash->{sts} && $lhash->{sts} == $selectTimestamp) { # busy loop check
|
||||
Log 4, "extending '$lhash->{msg} $hash->{addr}' timeout due to busy loop";
|
||||
InternalTimer(gettimeofday()+1, "HttpUtils_Err", $lhash);
|
||||
return;
|
||||
}
|
||||
return if(!defined($hash->{FD})); # Already closed
|
||||
HttpUtils_Close($hash);
|
||||
$hash->{callback}($hash, "$errtxt $hash->{addr} timed out", "");
|
||||
$hash->{callback}($hash, "$lhash->{msg} $hash->{addr} timed out", "");
|
||||
}
|
||||
|
||||
sub HttpUtils_ConnErr($) { my ($hash) = @_; HttpUtils_Err($hash, "connect to");}
|
||||
sub HttpUtils_ReadErr($) { my ($hash) = @_; HttpUtils_Err($hash, "read from"); }
|
||||
sub HttpUtils_WriteErr($){ my ($hash) = @_; HttpUtils_Err($hash, "write to"); }
|
||||
|
||||
sub
|
||||
HttpUtils_File($)
|
||||
{
|
||||
@ -154,11 +156,10 @@ HttpUtils_gethostbyname($$$)
|
||||
|
||||
my %dh = ( conn=>$c, FD=>$c->fileno(), NAME=>"DNS", origHash=>$hash,
|
||||
addr=>$dnsServer, callback=>$fn );
|
||||
my %timerHash = ( hash => \%dh );
|
||||
my %timerHash = ( hash=>\%dh, msg=>"DNS" );
|
||||
my $bhost = join("", map { pack("CA*",length($_),$_) } split(/\./, $host));
|
||||
my $qry = pack("nnnnnn", 0x7072,0x0100,1,0,0,0) . $bhost . pack("Cnn", 0,1,1);
|
||||
my $ql = length($qry);
|
||||
my $dnsTo = 0.25;
|
||||
|
||||
$dh{directReadFn} = sub() { # Parse the answer
|
||||
RemoveInternalTimer(\%timerHash);
|
||||
@ -177,17 +178,20 @@ HttpUtils_gethostbyname($$$)
|
||||
$selectlist{\%dh} = \%dh;
|
||||
|
||||
my $dnsQuery;
|
||||
my $dnsTo = 0.25;
|
||||
my $lSelectTs = $selectTimestamp;
|
||||
$dnsQuery = sub()
|
||||
{
|
||||
$dnsTo *= 2;
|
||||
return HttpUtils_Err(\%timerHash, "DNS") if($dnsTo > $hash->{timeout}/2);
|
||||
$dnsTo *= 2 if($lSelectTs != $selectTimestamp);
|
||||
$lSelectTs = $selectTimestamp;
|
||||
return HttpUtils_Err(\%timerHash) if($dnsTo > $hash->{timeout}/2);
|
||||
my $ret = syswrite $dh{conn}, $qry;
|
||||
if(!$ret || $ret != $ql) {
|
||||
my $err = $!;
|
||||
HttpUtils_Close(\%dh);
|
||||
return $fn->($hash, "DNS write error: $err", undef);
|
||||
}
|
||||
InternalTimer(gettimeofday()+$dnsTo, $dnsQuery, \%timerHash, 0);
|
||||
InternalTimer(gettimeofday()+$dnsTo, $dnsQuery, \%timerHash);
|
||||
};
|
||||
$dnsQuery->();
|
||||
|
||||
@ -241,7 +245,7 @@ HttpUtils_Connect($)
|
||||
(int($!)==140 && $^O eq "MSWin32")) { # Nonblocking connect
|
||||
|
||||
$hash->{FD} = $hash->{conn}->fileno();
|
||||
my %timerHash = ( hash => $hash );
|
||||
my %timerHash=(hash=>$hash,sts=>$selectTimestamp,msg=>"connect to");
|
||||
$hash->{directWriteFn} = sub() {
|
||||
delete($hash->{FD});
|
||||
delete($hash->{directWriteFn});
|
||||
@ -262,7 +266,7 @@ HttpUtils_Connect($)
|
||||
$hash->{NAME}="" if(!defined($hash->{NAME}));#Delete might check it
|
||||
$selectlist{$hash} = $hash;
|
||||
InternalTimer(gettimeofday()+$hash->{timeout},
|
||||
"HttpUtils_ConnErr", \%timerHash, 0);
|
||||
"HttpUtils_Err", \%timerHash);
|
||||
return undef;
|
||||
} else {
|
||||
$hash->{callback}($hash, "connect to $hash->{addr}: $!", "");
|
||||
@ -379,7 +383,7 @@ HttpUtils_Connect2($)
|
||||
$hash->{FD} = $hash->{conn}->fileno();
|
||||
$hash->{buf} = "";
|
||||
$hash->{NAME} = "" if(!defined($hash->{NAME}));
|
||||
my %timerHash = ( hash => $hash );
|
||||
my %timerHash = (hash=>$hash, checkSTS=>$selectTimestamp, msg=>"write to");
|
||||
$hash->{directReadFn} = sub() {
|
||||
my $buf;
|
||||
my $len = sysread($hash->{conn},$buf,65536);
|
||||
@ -409,13 +413,13 @@ HttpUtils_Connect2($)
|
||||
shutdown($hash->{conn}, 1) if($s);
|
||||
delete($hash->{directWriteFn});
|
||||
RemoveInternalTimer(\%timerHash);
|
||||
$timerHash{msg} = "read from";
|
||||
InternalTimer(gettimeofday()+$hash->{timeout},
|
||||
"HttpUtils_ReadErr", \%timerHash, 0);
|
||||
"HttpUtils_Err", \%timerHash);
|
||||
}
|
||||
};
|
||||
$selectlist{$hash} = $hash;
|
||||
InternalTimer(gettimeofday()+$hash->{timeout},
|
||||
"HttpUtils_WriteErr", \%timerHash, 0);
|
||||
InternalTimer(gettimeofday()+$hash->{timeout}, "HttpUtils_Err",\%timerHash);
|
||||
return undef;
|
||||
|
||||
} else {
|
||||
|
35
fhem/fhem.pl
35
fhem/fhem.pl
@ -198,13 +198,19 @@ sub cfgDB_WriteFile($@);
|
||||
# VOLATILE- Set if the definition should be saved to the "statefile"
|
||||
# NOTIFYDEV - if set, the notifyFn will only be called for this device
|
||||
|
||||
use vars qw($auth_refresh);
|
||||
use vars qw($cmdFromAnalyze); # used by the warnings-sub
|
||||
use vars qw($cvsid); # used in 98_version.pm
|
||||
use vars qw($devcount); # Maximum device number, used for storing
|
||||
use vars qw($featurelevel);
|
||||
use vars qw($fhem_started); # used for uptime calculation
|
||||
use vars qw($init_done); #
|
||||
use vars qw($internal_data); # FileLog/DbLog -> SVG data transport
|
||||
use vars qw($lastDefChange); # number of last def/attr change
|
||||
use vars qw($nextat); # Time when next timer will be triggered.
|
||||
use vars qw($readytimeout); # Polling interval. UNIX: device search only
|
||||
use vars qw($reread_active);
|
||||
use vars qw($selectTimestamp); # used to check last select exit timestamp
|
||||
use vars qw($winService); # the Windows Service object
|
||||
use vars qw(%attr); # Attributes
|
||||
use vars qw(%cmds); # Global command name hash.
|
||||
@ -212,22 +218,19 @@ use vars qw(%data); # Hash for user data
|
||||
use vars qw(%defaultattr); # Default attributes, used by FHEM2FHEM
|
||||
use vars qw(%defs); # FHEM device/button definitions
|
||||
use vars qw(%inform); # Used by telnet_ActivateInform
|
||||
use vars qw(%logInform); # Used by FHEMWEB/Event-Monitor
|
||||
use vars qw(%intAt); # Internal at timer hash, global for benchmark
|
||||
use vars qw(%logInform); # Used by FHEMWEB/Event-Monitor
|
||||
use vars qw(%modules); # List of loaded modules (device/log/etc)
|
||||
use vars qw(%ntfyHash); # hash of devices needed to be notified.
|
||||
use vars qw(%oldvalue); # Old values, see commandref.html
|
||||
use vars qw(%readyfnlist); # devices which want a "readyfn"
|
||||
use vars qw(%selectlist); # devices which want a "select"
|
||||
use vars qw(%value); # Current values, see commandref.html
|
||||
use vars qw($lastDefChange); # number of last def/attr change
|
||||
use vars qw(@structChangeHist); # Contains the last 10 structural changes
|
||||
use vars qw($cmdFromAnalyze); # used by the warnings-sub
|
||||
use vars qw($featurelevel);
|
||||
use vars qw(@authorize); # List of authorization devices
|
||||
use vars qw(@authenticate); # List of authentication devices
|
||||
use vars qw($auth_refresh);
|
||||
use vars qw($cvsid); # used in 98_version.pm
|
||||
use vars qw(@authorize); # List of authorization devices
|
||||
use vars qw(@structChangeHist); # Contains the last 10 structural changes
|
||||
|
||||
$selectTimestamp = gettimeofday();
|
||||
$cvsid = '$Id$';
|
||||
|
||||
my $AttrList = "verbose:0,1,2,3,4,5 room group comment:textField-long alias ".
|
||||
@ -2767,7 +2770,10 @@ HandleTimeout()
|
||||
return undef if(!$nextat);
|
||||
|
||||
my $now = gettimeofday();
|
||||
return ($nextat-$now) if($now < $nextat);
|
||||
if($now < $nextat) {
|
||||
$selectTimestamp = $now;
|
||||
return ($nextat-$now);
|
||||
}
|
||||
|
||||
$now += 0.01;# need to cover min delay at least
|
||||
$nextat = 0;
|
||||
@ -2792,9 +2798,14 @@ HandleTimeout()
|
||||
}
|
||||
}
|
||||
|
||||
return undef if(!$nextat);
|
||||
$now = gettimeofday(); # possibly some tasks did timeout in the meantime
|
||||
# we will cover them
|
||||
if(!$nextat) {
|
||||
$selectTimestamp = $now;
|
||||
return undef;
|
||||
}
|
||||
|
||||
$now = gettimeofday(); # if some callbacks took longer
|
||||
$selectTimestamp = $now;
|
||||
|
||||
return ($now+ 0.01 < $nextat) ? ($nextat-$now) : 0.01;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user