From 8d245ba595a8a064bd7f8a755ff93d5f10b9f1a2 Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Mon, 11 May 2009 22:50:06 +0000 Subject: [PATCH] added try/catch blocks so that we hopefully can bridge periods where the new general time provides (unexpectedly considering its advertised benfits) no time at all. --- src/libCom/timer/epicsTimer.cpp | 7 ++++- src/libCom/timer/timer.cpp | 7 ++++- src/libCom/timer/timerPrivate.h | 3 ++ src/libCom/timer/timerQueue.cpp | 22 +++++++++++---- src/libCom/timer/timerQueueActive.cpp | 40 ++++++++++++++++++++++++--- 5 files changed, 67 insertions(+), 12 deletions(-) diff --git a/src/libCom/timer/epicsTimer.cpp b/src/libCom/timer/epicsTimer.cpp index 2364074ce..f063706bc 100644 --- a/src/libCom/timer/epicsTimer.cpp +++ b/src/libCom/timer/epicsTimer.cpp @@ -173,7 +173,12 @@ extern "C" void epicsShareAPI extern "C" double epicsShareAPI epicsTimerQueuePassiveProcess ( epicsTimerQueuePassiveId pQueue ) { - return pQueue->process ( epicsTime::getCurrent() ); + try { + return pQueue->process ( epicsTime::getCurrent() ); + } + catch ( ... ) { + return 1.0; + } } extern "C" epicsTimerId epicsShareAPI epicsTimerQueuePassiveCreateTimer ( diff --git a/src/libCom/timer/timer.cpp b/src/libCom/timer/timer.cpp index a17b434f6..441afda21 100644 --- a/src/libCom/timer/timer.cpp +++ b/src/libCom/timer/timer.cpp @@ -197,7 +197,12 @@ void timer::show ( unsigned int level ) const } double delay; if ( this->curState == statePending || this->curState == stateActive ) { - delay = this->exp - epicsTime::getCurrent(); + try { + delay = this->exp - epicsTime::getCurrent(); + } + catch ( ... ) { + delay = - DBL_MAX; + } } else { delay = -DBL_MAX; diff --git a/src/libCom/timer/timerPrivate.h b/src/libCom/timer/timerPrivate.h index 6760d1bf2..67648d08a 100644 --- a/src/libCom/timer/timerPrivate.h +++ b/src/libCom/timer/timerPrivate.h @@ -156,6 +156,9 @@ private: void run (); void reschedule (); double quantum (); + void _printLastChanceExceptionMessage ( + const char * pExceptionTypeName, + const char * pExceptionContext ); epicsTimerQueue & getEpicsTimerQueue (); timerQueueActive ( const timerQueueActive & ); timerQueueActive & operator = ( const timerQueueActive & ); diff --git a/src/libCom/timer/timerQueue.cpp b/src/libCom/timer/timerQueue.cpp index 548300307..5f7929118 100644 --- a/src/libCom/timer/timerQueue.cpp +++ b/src/libCom/timer/timerQueue.cpp @@ -14,7 +14,8 @@ * 505 665 1831 */ -#include +#include +#include #define epicsExportSharedSymbols #include "epicsGuard.h" @@ -46,13 +47,22 @@ timerQueue::~timerQueue () void timerQueue :: printExceptMsg ( const char * pName, const type_info & type ) { - epicsTime cur = epicsTime :: getCurrent (); - double delay = cur - this->exceptMsgTimeStamp; - if ( delay >= exceptMsgMinPeriod ) { - this->exceptMsgTimeStamp = cur; - char date[64]; + char date[64]; + double delay; + try { + epicsTime cur = epicsTime :: getCurrent (); + delay = cur - this->exceptMsgTimeStamp; cur.strftime ( date, sizeof ( date ), "%a %b %d %Y %H:%M:%S.%f" ); + if ( delay >= exceptMsgMinPeriod ) { + this->exceptMsgTimeStamp = cur; + } + } + catch ( ... ) { + delay = DBL_MAX; + strcpy ( date, "UKN DATE" ); + } + if ( delay >= exceptMsgMinPeriod ) { // we dont touch the typeid for the timer expiration // notify interface here because they might have // destroyed the timer during its callback diff --git a/src/libCom/timer/timerQueueActive.cpp b/src/libCom/timer/timerQueueActive.cpp index c9db12043..fd4c2bfea 100644 --- a/src/libCom/timer/timerQueueActive.cpp +++ b/src/libCom/timer/timerQueueActive.cpp @@ -18,6 +18,7 @@ #define epicsExportSharedSymbols #include "timerPrivate.h" +#include "errlog.h" #ifdef _MSC_VER # pragma warning ( push ) @@ -63,13 +64,44 @@ timerQueueActive::~timerQueueActive () this->exitEvent.signal (); } -void timerQueueActive::run () +void timerQueueActive :: _printLastChanceExceptionMessage ( + const char * pExceptionTypeName, + const char * pExceptionContext ) +{ + char date[64]; + try { + epicsTime cur = epicsTime :: getCurrent (); + cur.strftime ( date, sizeof ( date ), "%a %b %d %Y %H:%M:%S.%f"); + } + catch ( ... ) { + strcpy ( date, "" ); + } + errlogPrintf ( + "timerQueueActive: Unexpected C++ exception \"%s\" with type \"%s\" " + "while processing timer queue, at %s\n", + pExceptionContext, pExceptionTypeName, date ); +} + + +void timerQueueActive :: run () { this->exitFlag = false; while ( ! this->terminateFlag ) { - double delay = this->queue.process ( epicsTime::getCurrent() ); - debugPrintf ( ( "timer thread sleeping for %g sec (max)\n", delay ) ); - this->rescheduleEvent.wait ( delay ); + try { + double delay = this->queue.process ( epicsTime::getCurrent() ); + debugPrintf ( ( "timer thread sleeping for %g sec (max)\n", delay ) ); + this->rescheduleEvent.wait ( delay ); + } + catch ( std :: exception & except ) { + _printLastChanceExceptionMessage ( + typeid ( except ).name (), except.what () ); + epicsThreadSleep ( 10.0 ); + } + catch ( ... ) { + _printLastChanceExceptionMessage ( + "catch ( ... )", "Non-standard C++ exception" ); + epicsThreadSleep ( 10.0 ); + } } this->exitFlag = true; this->exitEvent.signal (); // no access to queue after exitEvent signal