Emulator.cpp

Go to the documentation of this file.
00001 /* Copyright (C) 2003 MySQL AB
00002 
00003    This program is free software; you can redistribute it and/or modify
00004    it under the terms of the GNU General Public License as published by
00005    the Free Software Foundation; either version 2 of the License, or
00006    (at your option) any later version.
00007 
00008    This program is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011    GNU General Public License for more details.
00012 
00013    You should have received a copy of the GNU General Public License
00014    along with this program; if not, write to the Free Software
00015    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
00016 
00017 #include <ndb_global.h>
00018 
00019 #include "Emulator.hpp"
00020 #include <FastScheduler.hpp>
00021 #include <SignalLoggerManager.hpp>
00022 #include <TransporterRegistry.hpp>
00023 #include <TimeQueue.hpp>
00024 
00025 #include "Configuration.hpp"
00026 #include "WatchDog.hpp"
00027 #include "ThreadConfig.hpp"
00028 #include "SimBlockList.hpp"
00029 
00030 #include <NodeState.hpp>
00031 
00032 #include <NdbMem.h>
00033 #include <NdbOut.hpp>
00034 #include <NdbMutex.h>
00035 #include <NdbSleep.h>
00036 
00037 extern "C" {
00038   extern void (* ndb_new_handler)();
00039 }
00040 
00045 #ifndef NO_EMULATED_JAM
00046 Uint8 theEmulatedJam[EMULATED_JAM_SIZE * 4];
00047 Uint32 theEmulatedJamIndex = 0;
00048 Uint32 theEmulatedJamBlockNumber = 0;
00049 #endif
00050 
00051    GlobalData globalData;
00052 
00053    TimeQueue globalTimeQueue;
00054    FastScheduler globalScheduler;
00055    TransporterRegistry globalTransporterRegistry;
00056 
00057 #ifdef VM_TRACE
00058    SignalLoggerManager globalSignalLoggers;
00059 #endif
00060 
00061 EmulatorData globalEmulatorData;
00062 NdbMutex * theShutdownMutex = 0;
00063 int simulate_error_during_shutdown= 0;
00064 
00065 EmulatorData::EmulatorData(){
00066   theConfiguration = 0;
00067   theWatchDog      = 0;
00068   theThreadConfig  = 0;
00069   theSimBlockList  = 0;
00070   theShutdownMutex = 0;
00071   m_socket_server = 0;
00072 }
00073 
00074 void
00075 ndb_new_handler_impl(){
00076   ERROR_SET(fatal, ERR_MEMALLOC, "New handler", "");
00077 }
00078 
00079 void
00080 EmulatorData::create(){
00081   NdbMem_Create();
00082 
00083   theConfiguration = new Configuration();
00084   theWatchDog      = new WatchDog();
00085   theThreadConfig  = new ThreadConfig();
00086   theSimBlockList  = new SimBlockList();
00087   m_socket_server  = new SocketServer();
00088 
00089   theShutdownMutex = NdbMutex_Create();
00090 
00091   ndb_new_handler = ndb_new_handler_impl;
00092 }
00093 
00094 void
00095 EmulatorData::destroy(){
00096   if(theConfiguration)
00097     delete theConfiguration; theConfiguration = 0;
00098   if(theWatchDog)
00099     delete theWatchDog; theWatchDog = 0;
00100   if(theThreadConfig)
00101     delete theThreadConfig; theThreadConfig = 0;
00102   if(theSimBlockList)
00103     delete theSimBlockList; theSimBlockList = 0;
00104   if(m_socket_server)
00105     delete m_socket_server; m_socket_server = 0;
00106   NdbMem_Destroy();
00107 }
00108 
00109 void
00110 NdbShutdown(NdbShutdownType type,
00111             NdbRestartType restartType){
00112   
00113   if(type == NST_ErrorInsert){
00114     type = NST_Restart;
00115     restartType = (NdbRestartType)
00116       globalEmulatorData.theConfiguration->getRestartOnErrorInsert();
00117     if(restartType == NRT_Default){
00118       type = NST_ErrorHandler;
00119       globalEmulatorData.theConfiguration->stopOnError(true);
00120     }
00121   }
00122   
00123   if((type == NST_ErrorHandlerSignal) || // Signal handler has already locked mutex
00124      (NdbMutex_Trylock(theShutdownMutex) == 0)){
00125     globalData.theRestartFlag = perform_stop;
00126 
00127     bool restart = false;
00128 #if ! ( defined NDB_OSE || defined NDB_SOFTOSE) 
00129     if((type != NST_Normal && 
00130         globalEmulatorData.theConfiguration->stopOnError() == false) ||
00131        type == NST_Restart) {
00132       
00133       restart  = true;
00134     }
00135 #endif
00136     
00137     const char * shutting = "shutting down";
00138     if(restart){
00139       shutting = "restarting";
00140     }
00141     
00142     switch(type){
00143     case NST_Normal:
00144       ndbout << "Shutdown initiated" << endl;
00145       break;
00146     case NST_Watchdog:
00147       ndbout << "Watchdog " << shutting << " system" << endl;
00148       break;
00149     case NST_ErrorHandler:
00150       ndbout << "Error handler " << shutting << " system" << endl;
00151       break;
00152     case NST_ErrorHandlerSignal:
00153       ndbout << "Error handler signal " << shutting << " system" << endl;
00154       break;
00155     case NST_Restart:
00156       ndbout << "Restarting system" << endl;
00157       break;
00158     default:
00159       ndbout << "Error handler " << shutting << " system"
00160              << " (unknown type: " << (unsigned)type << ")" << endl;
00161       type = NST_ErrorHandler;
00162       break;
00163     }
00164     
00165     const char * exitAbort = 0;
00166 #if defined VM_TRACE && ( ! ( defined NDB_OSE || defined NDB_SOFTOSE) )
00167     exitAbort = "aborting";
00168 #else
00169     exitAbort = "exiting";
00170 #endif
00171     
00172     if(type == NST_Watchdog){
00176       ndbout << "Watchdog shutdown completed - " << exitAbort << endl;
00177 #if defined VM_TRACE && ( ! ( defined NDB_OSE || defined NDB_SOFTOSE) )
00178       signal(6, SIG_DFL);
00179       abort();
00180 #else
00181       exit(-1);
00182 #endif
00183     }
00184 
00185 #ifndef NDB_WIN32
00186     if (simulate_error_during_shutdown) {
00187       kill(getpid(), simulate_error_during_shutdown);
00188       while(true)
00189         NdbSleep_MilliSleep(10);
00190     }
00191 #endif
00192 
00193     globalEmulatorData.theWatchDog->doStop();
00194     
00195 #ifdef VM_TRACE
00196     FILE * outputStream = globalSignalLoggers.setOutputStream(0);
00197     if(outputStream != 0)
00198       fclose(outputStream);
00199 #endif
00200     
00204     globalEmulatorData.m_socket_server->stopServer();
00205     globalEmulatorData.m_socket_server->stopSessions();
00206     globalTransporterRegistry.stop_clients();
00207 
00211     globalTransporterRegistry.stopSending();
00212     globalTransporterRegistry.stopReceiving();
00213     
00217     globalTransporterRegistry.removeAll();
00218     
00219 #ifdef VM_TRACE
00220 #define UNLOAD (type != NST_ErrorHandler && type != NST_Watchdog)
00221 #else
00222 #define UNLOAD true
00223 #endif
00224     if(UNLOAD){
00225       globalEmulatorData.theSimBlockList->unload();    
00226       globalEmulatorData.destroy();
00227     }
00228     
00229     if(type != NST_Normal && type != NST_Restart){
00230       ndbout << "Error handler shutdown completed - " << exitAbort << endl;
00231 #if ( defined VM_TRACE || defined ERROR_INSERT ) && ( ! ( defined NDB_OSE || defined NDB_SOFTOSE) )
00232       signal(6, SIG_DFL);
00233       abort();
00234 #else
00235       exit(-1);
00236 #endif
00237     }
00238     
00242     if(type == NST_Restart){
00243       exit(restartType);
00244     }
00245     
00246     ndbout << "Shutdown completed - exiting" << endl;
00247   } else {
00255     if (type== NST_Watchdog){
00256       ndbout << "Watchdog is killing system the hard way" << endl;
00257 #if defined VM_TRACE && ( ! ( defined NDB_OSE || defined NDB_SOFTOSE) )
00258       signal(6, SIG_DFL);
00259       abort();
00260 #else
00261       exit(-1);
00262 #endif
00263     }
00264     
00265     while(true)
00266       NdbSleep_MilliSleep(10);
00267   }
00268 }
00269 

Generated on Wed Jul 20 21:05:38 2005 for MySQL 5.0.9 Beta by  doxygen 1.4.3