From 9306dd5ddc8f449c7fc02d83550796727675c4a7 Mon Sep 17 00:00:00 2001 From: ntruchsess Date: Mon, 19 May 2014 15:11:06 +0000 Subject: [PATCH] OWX_ASYNC: handle Exceptions in ProtoThreads, lower loglevel of Alarms-logging git-svn-id: svn://svn.code.sf.net/p/fhem/code/trunk@5902 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/00_OWX_ASYNC.pm | 13 +++++++++---- fhem/FHEM/21_OWAD.pm | 20 +++++++++++++------- fhem/FHEM/21_OWCOUNT.pm | 20 +++++++++++++------- fhem/FHEM/21_OWLCD.pm | 26 +++++++++++++++++--------- fhem/FHEM/21_OWMULTI.pm | 6 ++++-- fhem/FHEM/21_OWSWITCH.pm | 14 +++++++++----- fhem/FHEM/21_OWTHERM.pm | 14 +++++++++----- fhem/FHEM/OWX_SER.pm | 14 +++++++------- fhem/FHEM/lib/ProtoThreads.pm | 6 +++--- 9 files changed, 84 insertions(+), 49 deletions(-) diff --git a/fhem/FHEM/00_OWX_ASYNC.pm b/fhem/FHEM/00_OWX_ASYNC.pm index f32fe75b1..e945c8d39 100644 --- a/fhem/FHEM/00_OWX_ASYNC.pm +++ b/fhem/FHEM/00_OWX_ASYNC.pm @@ -128,7 +128,7 @@ my %attrs = ( ); #-- some globals needed for the 1-Wire module -$owx_async_version=5.2; +$owx_async_version=5.3; #-- Debugging 0,1,2,3 $owx_async_debug=0; @@ -1133,11 +1133,16 @@ sub OWX_ASYNC_RunTasks($) { while ( ( $owx_dev, $queue ) = each %{$master->{tasks}} ) { if (@$queue) { my $task = $queue->[0]; - unless ($task->PT_SCHEDULE(@{$task->{ExecuteArgs}})) { + my $ret; + eval { + $ret = $task->PT_SCHEDULE(@{$task->{ExecuteArgs}}); + }; + if (!$ret or $@) { shift @$queue; delete $master->{tasks}->{$owx_dev} unless @$queue; - if ($task->PT_RETVAL()) { - Log3 ($master->{NAME},2,"OWX_ASYNC: Error running task for $owx_dev: ".$task->PT_RETVAL()); + my $msg = ($@) ? GP_Catch($@) : $task->PT_RETVAL(); + if (defined $msg) { + Log3 ($master->{NAME},2,"OWX_ASYNC: Error running task for $owx_dev: $msg"); } } OWX_ASYNC_Poll( $master ); diff --git a/fhem/FHEM/21_OWAD.pm b/fhem/FHEM/21_OWAD.pm index f77fc3847..fe7c75c1a 100644 --- a/fhem/FHEM/21_OWAD.pm +++ b/fhem/FHEM/21_OWAD.pm @@ -90,7 +90,7 @@ use ProtoThreads; no warnings 'deprecated'; sub Log($$); -my $owx_version="5.14"; +my $owx_version="5.15"; #-- fixed raw channel name, flexible channel name my @owg_fixed = ("A","B","C","D"); my @owg_channel = ("A","B","C","D"); @@ -597,8 +597,10 @@ sub OWAD_Get($@) { }elsif( $interface eq "OWX_ASYNC" ){ #TODO use OWX_ASYNC_Schedule instead my $task = PT_THREAD(\&OWXAD_PT_GetPage); - while ($task->PT_SCHEDULE($hash,"reading",1)) { OWX_ASYNC_Poll($hash->{IODev}); }; - $ret = $task->PT_RETVAL(); + eval { + while ($task->PT_SCHEDULE($hash,"reading",1)) { OWX_ASYNC_Poll($hash->{IODev}); }; + }; + $ret = ($@) ? GP_Catch($@) : $task->PT_RETVAL(); #-- OWFS interface }elsif( $interface eq "OWServer" ){ $ret = OWFSAD_GetPage($hash,"reading",1); @@ -626,8 +628,10 @@ sub OWAD_Get($@) { }elsif( $interface eq "OWX_ASYNC" ){ #TODO use OWX_ASYNC_Schedule instead my $task = PT_THREAD(\&OWXAD_PT_GetPage); - while ($task->PT_SCHEDULE($hash,"alarm",1)) { OWX_ASYNC_Poll($hash->{IODev}); }; - $ret = $task->PT_RETVAL(); + eval { + while ($task->PT_SCHEDULE($hash,"alarm",1)) { OWX_ASYNC_Poll($hash->{IODev}); }; + }; + $ret = ($@) ? GP_Catch($@) : $task->PT_RETVAL(); #-- OWFS interface }elsif( $interface eq "OWServer" ){ $ret = OWFSAD_GetPage($hash,"alarm",1); @@ -663,8 +667,10 @@ sub OWAD_Get($@) { }elsif( $interface eq "OWX_ASYNC" ){ #TODO use OWX_ASYNC_Schedule instead my $task = PT_THREAD(\&OWXAD_PT_GetPage); - while ($task->PT_SCHEDULE($hash,"status",1)) { OWX_ASYNC_Poll($hash->{IODev}); }; - $ret = $task->PT_RETVAL(); + eval { + while ($task->PT_SCHEDULE($hash,"status",1)) { OWX_ASYNC_Poll($hash->{IODev}); }; + }; + $ret = ($@) ? GP_Catch($@) : $task->PT_RETVAL(); #-- OWFS interface }elsif( $interface eq "OWServer" ){ $ret = OWFSAD_GetPage($hash,"status",1); diff --git a/fhem/FHEM/21_OWCOUNT.pm b/fhem/FHEM/21_OWCOUNT.pm index 4ce42713f..858038854 100644 --- a/fhem/FHEM/21_OWCOUNT.pm +++ b/fhem/FHEM/21_OWCOUNT.pm @@ -99,7 +99,7 @@ no warnings 'deprecated'; sub Log3($$$); -my $owx_version="5.21"; +my $owx_version="5.22"; #-- fixed raw channel name, flexible channel name my @owg_fixed = ("A","B"); my @owg_channel = ("A","B"); @@ -817,8 +817,10 @@ sub OWCOUNT_GetPage ($$$@) { if ($sync) { #TODO use OWX_ASYNC_Schedule instead my $task = PT_THREAD(\&OWXCOUNT_PT_GetPage); - while ($task->PT_SCHEDULE($hash,$page,$final)) { OWX_ASYNC_Poll($hash->{IODev}); }; - $ret = $task->PT_RETVAL(); + eval { + while ($task->PT_SCHEDULE($hash,$page,$final)) { OWX_ASYNC_Poll($hash->{IODev}); }; + }; + $ret = ($@) ? GP_Catch($@) : $task->PT_RETVAL(); } else { eval { OWX_ASYNC_Schedule( $hash, PT_THREAD(\&OWXCOUNT_PT_GetPage),$hash,$page,$final ); @@ -1123,8 +1125,10 @@ sub OWCOUNT_InitializeDevice($) { }elsif( $interface eq "OWX_ASYNC" ){ #TODO use OWX_ASYNC_Schedule instead my $task = PT_THREAD(\&OWXCOUNT_PT_InitializeDevicePage); - while ($task->PT_SCHEDULE($hash,14,$newdata)) { OWX_ASYNC_Poll($hash->{IODev}); }; - $ret = $task->PT_RETVAL(); + eval { + while ($task->PT_SCHEDULE($hash,14,$newdata)) { OWX_ASYNC_Poll($hash->{IODev}); }; + }; + $ret = ($@) ? GP_Catch($@) : $task->PT_RETVAL(); #-- OWFS interface }elsif( $interface eq "OWServer" ){ $ret = OWFSCOUNT_GetPage($hash,14,0); @@ -1148,8 +1152,10 @@ sub OWCOUNT_InitializeDevice($) { }elsif( $interface eq "OWX_ASYNC" ){ #TODO use OWX_ASYNC_Schedule instead my $task = PT_THREAD(\&OWXCOUNT_PT_InitializeDevicePage); - while ($task->PT_SCHEDULE($hash,0,$newdata)) { OWX_ASYNC_Poll($hash->{IODev}); }; - $ret = $task->PT_RETVAL(); + eval { + while ($task->PT_SCHEDULE($hash,0,$newdata)) { OWX_ASYNC_Poll($hash->{IODev}); }; + }; + $ret = ($@) ? GP_Catch($@) : $task->PT_RETVAL(); #-- OWFS interface }elsif( $interface eq "OWServer" ){ $ret = OWFSCOUNT_GetPage($hash,0,0); diff --git a/fhem/FHEM/21_OWLCD.pm b/fhem/FHEM/21_OWLCD.pm index 4377d2838..d216b6395 100644 --- a/fhem/FHEM/21_OWLCD.pm +++ b/fhem/FHEM/21_OWLCD.pm @@ -76,7 +76,7 @@ no warnings 'deprecated'; sub Log3($$$); -my $owx_version="3.36"; +my $owx_version="3.37"; #-- controller may be HD44780 or KS0073 # these values have to be changed for different display # geometries or memory maps @@ -320,8 +320,10 @@ sub OWLCD_Get($@) { if($a[1] eq "gpio") { if ($hash->{ASYNC}) { my $task = PT_THREAD(\&OWXLCD_PT_Get); - while ($task->PT_SCHEDULE($hash,"gpio")) { OWX_ASYNC_Poll($hash->{IODev}); }; - $ret = $task->PT_RETVAL(); + eval { + while ($task->PT_SCHEDULE($hash,"gpio")) { OWX_ASYNC_Poll($hash->{IODev}); }; + }; + $ret = ($@) ? GP_Catch($@) : $task->PT_RETVAL(); return $ret if $ret; return "$name.gpio => ".main::ReadingsVal($hash->{NAME},"gpio",""); } else { @@ -334,8 +336,10 @@ sub OWLCD_Get($@) { if($a[1] eq "counter") { if ($hash->{ASYNC}) { my $task = PT_THREAD(\&OWXLCD_PT_Get); - while ($task->PT_SCHEDULE($hash,"counter")) { OWX_ASYNC_Poll($hash->{IODev}); }; - $ret = $task->PT_RETVAL(); + eval { + while ($task->PT_SCHEDULE($hash,"counter")) { OWX_ASYNC_Poll($hash->{IODev}); }; + }; + $ret = ($@) ? GP_Catch($@) : $task->PT_RETVAL(); return $ret if $ret; return "$name.counter => ".main::ReadingsVal($hash->{NAME},"counter",""); } else { @@ -348,8 +352,10 @@ sub OWLCD_Get($@) { if($a[1] eq "version") { if ($hash->{ASYNC}) { my $task = PT_THREAD(\&OWXLCD_PT_Get); - while ($task->PT_SCHEDULE($hash,"version")) { OWX_ASYNC_Poll($hash->{IODev}); }; - $ret = $task->PT_RETVAL(); + eval { + while ($task->PT_SCHEDULE($hash,"version")) { OWX_ASYNC_Poll($hash->{IODev}); }; + }; + $ret = ($@) ? GP_Catch($@) : $task->PT_RETVAL(); return $ret if $ret; return "$name.gpio => ".main::ReadingsVal($hash->{NAME},"version",""); } else { @@ -364,8 +370,10 @@ sub OWLCD_Get($@) { Log3 $name,1,"Calling GetMemory with page $page"; if ($hash->{ASYNC}) { my $task = PT_THREAD(\&OWXLCD_PT_GetMemory); - while ($task->PT_SCHEDULE($hash,$page)) { OWX_ASYNC_Poll($hash->{IODev}); }; - $ret = $task->PT_RETVAL(); + eval { + while ($task->PT_SCHEDULE($hash,$page)) { OWX_ASYNC_Poll($hash->{IODev}); }; + }; + $ret = ($@) ? GP_Catch($@) : $task->PT_RETVAL(); return $ret if $ret; return "$name $reading $page => ".main::ReadingsVal($hash->{NAME},"memory$page",""); } else { diff --git a/fhem/FHEM/21_OWMULTI.pm b/fhem/FHEM/21_OWMULTI.pm index d88d3fd82..df7deda1e 100644 --- a/fhem/FHEM/21_OWMULTI.pm +++ b/fhem/FHEM/21_OWMULTI.pm @@ -486,8 +486,10 @@ sub OWMULTI_Get($@) { }elsif( $interface eq "OWX_ASYNC"){ #TODO use OWX_ASYNC_Schedule instead my $task = PT_THREAD(\&OWXMULTI_PT_GetValues); - while ($task->PT_SCHEDULE($hash)) { OWX_ASYNC_Poll($hash->{IODev}); }; - $ret = $task->PT_RETVAL(); + eval { + while ($task->PT_SCHEDULE($hash)) { OWX_ASYNC_Poll($hash->{IODev}); }; + }; + $ret = ($@) ? GP_Catch($@) : $task->PT_RETVAL(); #-- OWFS interface not yet implemented }elsif( $interface eq "OWServer" ){ $ret = OWFSMULTI_GetValues($hash); diff --git a/fhem/FHEM/21_OWSWITCH.pm b/fhem/FHEM/21_OWSWITCH.pm index f9409d911..cefbd0e9f 100644 --- a/fhem/FHEM/21_OWSWITCH.pm +++ b/fhem/FHEM/21_OWSWITCH.pm @@ -89,7 +89,7 @@ no warnings 'deprecated'; sub Log($$); -my $owx_version="5.15"; +my $owx_version="5.16"; #-- fixed raw channel name, flexible channel name my @owg_fixed = ("A","B","C","D","E","F","G","H"); my @owg_channel = ("A","B","C","D","E","F","G","H"); @@ -508,8 +508,10 @@ sub OWSWITCH_Get($@) { }elsif( $interface eq "OWX_ASYNC") { #TODO use OWX_ASYNC_Schedule instead my $task = PT_THREAD(\&OWXSWITCH_PT_GetState); - while ($task->PT_SCHEDULE($hash)) { OWX_ASYNC_Poll($hash->{IODev}); }; - $ret = $task->PT_RETVAL(); + eval { + while ($task->PT_SCHEDULE($hash)) { OWX_ASYNC_Poll($hash->{IODev}); }; + }; + $ret = ($@) ? GP_Catch($@) : $task->PT_RETVAL(); #-- OWFS interface }elsif( $interface eq "OWFS" ){ $ret = OWFSSWITCH_GetState($hash); @@ -530,8 +532,10 @@ sub OWSWITCH_Get($@) { }elsif( $interface eq "OWX_ASYNC" ){ #TODO use OWX_ASYNC_Schedule instead my $task = PT_THREAD(\&OWXSWITCH_PT_GetState); - while ($task->PT_SCHEDULE($hash)) { OWX_ASYNC_Poll($hash->{IODev}); }; - $ret = $task->PT_RETVAL(); + eval { + while ($task->PT_SCHEDULE($hash)) { OWX_ASYNC_Poll($hash->{IODev}); }; + }; + $ret = ($@) ? GP_Catch($@) : $task->PT_RETVAL(); }elsif( $interface eq "OWServer" ){ $ret = OWFSSWITCH_GetState($hash); }else{ diff --git a/fhem/FHEM/21_OWTHERM.pm b/fhem/FHEM/21_OWTHERM.pm index 7a20bb113..eb65271ca 100755 --- a/fhem/FHEM/21_OWTHERM.pm +++ b/fhem/FHEM/21_OWTHERM.pm @@ -86,7 +86,7 @@ no warnings 'deprecated'; sub Log3($$$); sub AttrVal($$$); -my $owx_version="5.18"; +my $owx_version="5.19"; my %gets = ( "id" => "", @@ -465,8 +465,10 @@ sub OWTHERM_Get($@) { }elsif( $interface eq "OWX_ASYNC" ){ #TODO use OWX_ASYNC_Schedule instead my $task = PT_THREAD(\&OWXTHERM_PT_GetValues); - while ($task->PT_SCHEDULE($hash)) { OWX_ASYNC_Poll($hash->{IODev}); }; - $ret = $task->PT_RETVAL(); + eval { + while ($task->PT_SCHEDULE($hash)) { OWX_ASYNC_Poll($hash->{IODev}); }; + }; + $ret = ($@) ? GP_Catch($@) : $task->PT_RETVAL(); #-- OWFS interface }elsif( $interface eq "OWServer" ){ $ret = OWFSTHERM_GetValues($hash); @@ -633,8 +635,10 @@ sub OWTHERM_InitializeDevice($) { }elsif( $interface eq "OWX_ASYNC" ){ #TODO use OWX_ASYNC_Schedule instead my $task = PT_THREAD(\&OWXTHERM_PT_SetValues); - while ($task->PT_SCHEDULE($hash,$args)) { OWX_ASYNC_Poll($hash->{IODev}); }; - $ret = $task->PT_RETVAL(); + eval { + while ($task->PT_SCHEDULE($hash,$args)) { OWX_ASYNC_Poll($hash->{IODev}); }; + }; + $ret = ($@) ? GP_Catch($@) : $task->PT_RETVAL(); #-- OWFS interface }elsif( $interface eq "OWServer" ){ $ret = OWFSTHERM_SetValues($hash,$args); diff --git a/fhem/FHEM/OWX_SER.pm b/fhem/FHEM/OWX_SER.pm index 378bad7d1..ebf1a65b8 100644 --- a/fhem/FHEM/OWX_SER.pm +++ b/fhem/FHEM/OWX_SER.pm @@ -58,7 +58,7 @@ sub new() { $self->{LastFamilyDiscrepancy} = 0; $self->{LastDeviceFlag} = 0; #-- module version - $self->{version} = 4.0; + $self->{version} = 4.1; $self->{alarmdevs} = []; $self->{devs} = []; $self->{pt_alarms} = PT_THREAD(\&pt_alarms); @@ -128,7 +128,7 @@ sub pt_alarms () { PT_WAIT_UNTIL($self->response_ready()); PT_EXIT unless $self->next_response("alarm"); } while( $self->{LastDeviceFlag}==0 ); - main::Log3($self->{name},1, " Alarms = ".join(' ',@{$self->{alarmdevs}})); + main::Log3($self->{name},5, " Alarms = ".join(' ',@{$self->{alarmdevs}})); PT_EXIT($self->{alarmdevs}); PT_END; } @@ -196,7 +196,7 @@ sub pt_execute($$$$$$$) { #-- for debugging if( $main::owx_async_debug > 1){ - main::Log3($self->{name},3,"OWX_SER::Execute: Sending out ".unpack ("H*",$select)); + main::Log3($self->{name},5,"OWX_SER::Execute: Sending out ".unpack ("H*",$select)); } $self->block($select); } @@ -208,7 +208,7 @@ sub pt_execute($$$$$$$) { my $res = $self->{string_in}; #-- for debugging if( $main::owx_async_debug > 1){ - main::Log3($self->{name},3,"OWX_SER::Execute: Receiving ".unpack ("H*",$res)); + main::Log3($self->{name},5,"OWX_SER::Execute: Receiving ".unpack ("H*",$res)); } PT_EXIT($res); @@ -260,7 +260,7 @@ sub initialize($) { if(!defined($hwdevice)){ die $msg." not defined: $!"; } else { - main::Log3($hash->{NAME},1,$msg." defined"); + main::Log3($hash->{NAME},2,$msg." defined"); } $hwdevice->reset_error(); @@ -338,7 +338,7 @@ sub initialize($) { $k=ord(substr($res,$i,1))%16; $ress.=sprintf "0x%1x%1x ",$j,$k; } - main::Log3($hash->{NAME},1, $ress); + main::Log3($hash->{NAME},4, $ress); $ress = $ress0; #-- sleeping for some time select(undef,undef,undef,0.5); @@ -353,7 +353,7 @@ sub initialize($) { } } $self->{interface} = $interface; - main::Log3($hash->{NAME},1, $ress); + main::Log3($hash->{NAME},3, $ress); if ($interface eq "DS2480") { return $ds2480; } elsif ($interface eq "DS9097") { diff --git a/fhem/FHEM/lib/ProtoThreads.pm b/fhem/FHEM/lib/ProtoThreads.pm index 7f7804fc0..81e070779 100644 --- a/fhem/FHEM/lib/ProtoThreads.pm +++ b/fhem/FHEM/lib/ProtoThreads.pm @@ -1,4 +1,4 @@ -# Perl Protothreads +# Perl Protothreads Version 1.01 # # a lightwight pseudo-threading framework for perl that is # heavily inspired by Adam Dunkels protothreads for the c-language @@ -128,7 +128,7 @@ FILTER_ONLY ($success,$before,$arg,$after) = PT_NEXTCOMMAND($code,"PT_BEGIN"); if ($success) { $thread = $arg; - $code=$before."{ my \$PT_YIELD_FLAG = 1; goto ".$thread."->{PT_THREAD_STATE} if ".$thread."->{PT_THREAD_STATE};".$after; + $code=$before."my \$PT_THREAD_STATE = eval { my \$PT_YIELD_FLAG = 1; goto ".$thread."->{PT_THREAD_STATE} if ".$thread."->{PT_THREAD_STATE};".$after; while (1) { ($success,$before,$arg,$after) = PT_NEXTCOMMAND($code,"PT_YIELD_UNTIL"); if ($success) { @@ -177,7 +177,7 @@ FILTER_ONLY next; } if ($code =~ /PT_END\s*;/s) { - $code = $`."} ".$thread."->{PT_THREAD_STATE} = 0; delete ".$thread."->{PT_THREAD_RETURN}; return PT_ENDED;".$'; + $code = $`.$thread."->{PT_THREAD_STATE} = 0; delete ".$thread."->{PT_THREAD_RETURN}; return PT_ENDED; }; die \$\@ if \$\@; return \$PT_THREAD_STATE;".$'; } last; }