diff options
author | Bernard Normier <bernard@zeroc.com> | 2004-05-13 20:08:02 +0000 |
---|---|---|
committer | Bernard Normier <bernard@zeroc.com> | 2004-05-13 20:08:02 +0000 |
commit | d0e4508ba9e2e54f79100366f67e86b6ea570102 (patch) | |
tree | 7399d0d5ebf08c5c87bf6540889e3b1f21ccbdaf /cpp/src/Freeze/EvictorI.cpp | |
parent | Small fixes (diff) | |
download | ice-d0e4508ba9e2e54f79100366f67e86b6ea570102.tar.bz2 ice-d0e4508ba9e2e54f79100366f67e86b6ea570102.tar.xz ice-d0e4508ba9e2e54f79100366f67e86b6ea570102.zip |
Added fatalerrorcallback
Diffstat (limited to 'cpp/src/Freeze/EvictorI.cpp')
-rw-r--r-- | cpp/src/Freeze/EvictorI.cpp | 124 |
1 files changed, 120 insertions, 4 deletions
diff --git a/cpp/src/Freeze/EvictorI.cpp b/cpp/src/Freeze/EvictorI.cpp index 654cc24240a..abba41d3845 100644 --- a/cpp/src/Freeze/EvictorI.cpp +++ b/cpp/src/Freeze/EvictorI.cpp @@ -61,6 +61,35 @@ Freeze::createEvictor(const ObjectAdapterPtr& adapter, return new EvictorI(adapter, envName, dbEnv, filename, initializer, indices, createDb); } +// +// Fatal error callback +// + +static Freeze::FatalErrorCallback fatalErrorCallback = 0; +static IceUtil::StaticMutex fatalErrorCallbackMutex = ICE_STATIC_MUTEX_INITIALIZER; + +Freeze::FatalErrorCallback +Freeze::registerFatalErrorCallback(Freeze::FatalErrorCallback cb) +{ + IceUtil::StaticMutex::Lock lock(fatalErrorCallbackMutex); + FatalErrorCallback result = fatalErrorCallback; + return result; +} + +static void +handleFatalError(const Freeze::EvictorPtr& evictor, const Ice::CommunicatorPtr& communicator) +{ + IceUtil::StaticMutex::Lock lock(fatalErrorCallbackMutex); + if(fatalErrorCallback != 0) + { + fatalErrorCallback(evictor, communicator); + } + else + { + ::abort(); + } +} + // // Helper functions @@ -180,6 +209,65 @@ Freeze::DeactivateController::deactivationComplete() notifyAll(); } +// +// WatchDogThread +// + +Freeze::WatchDogThread::WatchDogThread(long timeout, EvictorI& evictor) : + _timeout(IceUtil::Time::milliSeconds(timeout)), + _evictor(evictor), + _done(false), + _active(false) +{ +} + + +void +Freeze::WatchDogThread::run() +{ + Lock sync(*this); + + while(!_done) + { + if(_active) + { + if(timedWait(_timeout) == false && _active && !_done) + { + Error out(_evictor.communicator()->getLogger()); + out << "Fatal error: streaming watch dog thread timed out."; + out.flush(); + handleFatalError(&_evictor, _evictor.communicator()); + } + } + else + { + wait(); + } + } +} + +void Freeze::WatchDogThread::activate() +{ + Lock sync(*this); + _active = true; + notify(); +} + +void Freeze::WatchDogThread::deactivate() +{ + Lock sync(*this); + _active = false; + notify(); +} + +void +Freeze::WatchDogThread::terminate() +{ + Lock sync(*this); + _done = true; + notify(); +} + // // EvictorI @@ -327,6 +415,18 @@ Freeze::EvictorI::init(const string& envName, const vector<IndexPtr>& indices) } // + // By default, no stream timeout + // + long streamTimeout = _communicator->getProperties()-> + getPropertyAsIntWithDefault(propertyPrefix+ ".StreamTimeout", 0) * 1000; + + if(streamTimeout > 0) + { + _watchDogThread = new WatchDogThread(streamTimeout, *this); + _watchDogThread->start(); + } + + // // Start saving thread // start(); @@ -1181,6 +1281,12 @@ Freeze::EvictorI::deactivate(const string&) sync.release(); getThreadControl().join(); + if(_watchDogThread != 0) + { + _watchDogThread->terminate(); + _watchDogThread->getThreadControl().join(); + } + for(StoreMap::iterator p = _storeMap.begin(); p != _storeMap.end(); ++p) { (*p).second->close(); @@ -1346,11 +1452,21 @@ Freeze::EvictorI::run() if(!lockServant.acquired()) { lockElement.release(); + + if(_watchDogThread != 0) + { + _watchDogThread->activate(); + } lockServant.acquire(); + if(_watchDogThread != 0) + { + _watchDogThread->deactivate(); + } + lockElement.acquire(); status = element->status; } - + switch(status) { case EvictorElement::created: @@ -1550,21 +1666,21 @@ Freeze::EvictorI::run() Error out(_communicator->getLogger()); out << "Saving thread killed by exception: " << ex; out.flush(); - ::abort(); + handleFatalError(this, _communicator); } catch(const std::exception& ex) { Error out(_communicator->getLogger()); out << "Saving thread killed by std::exception: " << ex.what(); out.flush(); - ::abort(); + handleFatalError(this, _communicator); } catch(...) { Error out(_communicator->getLogger()); out << "Saving thread killed by unknown exception"; out.flush(); - ::abort(); + handleFatalError(this, _communicator); } } |