summaryrefslogtreecommitdiff
path: root/ndb/src/kernel/vm/WatchDog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ndb/src/kernel/vm/WatchDog.cpp')
-rw-r--r--ndb/src/kernel/vm/WatchDog.cpp143
1 files changed, 143 insertions, 0 deletions
diff --git a/ndb/src/kernel/vm/WatchDog.cpp b/ndb/src/kernel/vm/WatchDog.cpp
new file mode 100644
index 00000000000..a90f63aff37
--- /dev/null
+++ b/ndb/src/kernel/vm/WatchDog.cpp
@@ -0,0 +1,143 @@
+/* Copyright (C) 2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+#include "WatchDog.hpp"
+#include "GlobalData.hpp"
+#include <NdbOut.hpp>
+#include <NdbSleep.h>
+#include <ErrorHandlingMacros.hpp>
+
+extern "C"
+void*
+runWatchDog(void* w){
+ ((WatchDog*)w)->run();
+ NdbThread_Exit(0);
+ return NULL;
+}
+
+WatchDog::WatchDog(Uint32 interval) :
+ theIPValue(globalData.getWatchDogPtr())
+{
+ setCheckInterval(interval);
+ theStop = false;
+ theThreadPtr = 0;
+}
+
+WatchDog::~WatchDog(){
+ doStop();
+}
+
+Uint32
+WatchDog::setCheckInterval(Uint32 interval){
+ // An interval of less than 70ms is not acceptable
+ return theInterval = (interval < 70 ? 70 : interval);
+}
+
+void
+WatchDog::doStart(){
+ theStop = false;
+ theThreadPtr = NdbThread_Create(runWatchDog,
+ (void**)this,
+ 32768,
+ "ndb_watchdog",
+ NDB_THREAD_PRIO_HIGH);
+}
+
+void
+WatchDog::doStop(){
+ void *status;
+ theStop = true;
+ if(theThreadPtr){
+ NdbThread_WaitFor(theThreadPtr, &status);
+ NdbThread_Destroy(&theThreadPtr);
+ }
+}
+
+void
+WatchDog::run(){
+ unsigned int anIPValue;
+ unsigned int alerts = 0;
+ unsigned int oldIPValue = 0;
+
+ // WatchDog for the single threaded NDB
+ while(!theStop){
+ Uint32 tmp = theInterval / 500;
+ tmp= (tmp ? tmp : 1);
+
+ while(!theStop && tmp > 0){
+ NdbSleep_MilliSleep(500);
+ tmp--;
+ }
+
+ if(theStop)
+ break;
+
+ // Verify that the IP thread is not stuck in a loop
+ anIPValue = *theIPValue;
+ if(anIPValue != 0) {
+ oldIPValue = anIPValue;
+ globalData.incrementWatchDogCounter(0);
+ alerts = 0;
+ } else {
+ alerts++;
+ ndbout << "Ndb kernel is stuck in: ";
+ switch (oldIPValue) {
+ case 1:
+ ndbout << "Job Handling" << endl;
+ break;
+ case 2:
+ ndbout << "Scanning Timers" << endl;
+ break;
+ case 3:
+ ndbout << "External I/O" << endl;
+ break;
+ case 4:
+ ndbout << "Print Job Buffers at crash" << endl;
+ break;
+ case 5:
+ ndbout << "Checking connections" << endl;
+ break;
+ case 6:
+ ndbout << "Performing Send" << endl;
+ break;
+ case 7:
+ ndbout << "Polling for Receive" << endl;
+ break;
+ case 8:
+ ndbout << "Performing Receive" << endl;
+ break;
+ default:
+ ndbout << "Unknown place" << endl;
+ break;
+ }//switch
+ if(alerts == 3){
+ shutdownSystem();
+ }
+ }
+ }
+ return;
+}
+
+void
+WatchDog::shutdownSystem(){
+
+ ErrorReporter::handleError(ecError,
+ ERR_PROGRAMERROR,
+ "WatchDog terminate",
+ __FILE__,
+ NST_Watchdog);
+}