Emulator.cpp 5.84 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/* 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 */

17 18
#include <ndb_global.h>

19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
#include "Emulator.hpp"
#include <FastScheduler.hpp>
#include <SignalLoggerManager.hpp>
#include <TransporterRegistry.hpp>
#include <TimeQueue.hpp>

#include "Configuration.hpp"
#include "WatchDog.hpp"
#include "ThreadConfig.hpp"
#include "SimBlockList.hpp"

#include <NodeState.hpp>

#include <NdbMem.h>
#include <NdbOut.hpp>
#include <NdbMutex.h>
#include <NdbSleep.h>
#include <new>

38 39
#include <signal.h>        // For process signals

40 41 42 43
extern "C" {
  extern void (* ndb_new_handler)();
}

44 45 46 47
/**
 * Declare the global variables 
 */

unknown's avatar
unknown committed
48 49 50 51 52
#ifndef NO_EMULATED_JAM
Uint8 theEmulatedJam[EMULATED_JAM_SIZE * 4];
Uint32 theEmulatedJamIndex = 0;
Uint32 theEmulatedJamBlockNumber = 0;
#endif
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75

   GlobalData globalData;

   TimeQueue globalTimeQueue;
   FastScheduler globalScheduler;
   TransporterRegistry globalTransporterRegistry;

#ifdef VM_TRACE
   SignalLoggerManager globalSignalLoggers;
#endif

EmulatorData globalEmulatorData;
NdbMutex * theShutdownMutex = 0;

EmulatorData::EmulatorData(){
  theConfiguration = 0;
  theWatchDog      = 0;
  theThreadConfig  = 0;
  theSimBlockList  = 0;
  theShutdownMutex = 0;
}

void
76
ndb_new_handler_impl(){
77 78 79 80 81 82 83 84 85 86 87 88 89 90
  ERROR_SET(fatal, ERR_MEMALLOC, "New handler", "");
}

void
EmulatorData::create(){
  NdbMem_Create();

  theConfiguration = new Configuration();
  theWatchDog      = new WatchDog();
  theThreadConfig  = new ThreadConfig();
  theSimBlockList  = new SimBlockList();

  theShutdownMutex = NdbMutex_Create();

91
  ndb_new_handler = ndb_new_handler_impl;
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
}

void
EmulatorData::destroy(){
  if(theConfiguration)
    delete theConfiguration; theConfiguration = 0;
  if(theWatchDog)
    delete theWatchDog; theWatchDog = 0;
  if(theThreadConfig)
    delete theThreadConfig; theThreadConfig = 0;
  if(theSimBlockList)
    delete theSimBlockList; theSimBlockList = 0;
  
  NdbMem_Destroy();
}

void
NdbShutdown(NdbShutdownType type,
	    NdbRestartType restartType){
  
  if(type == NST_ErrorInsert){
    type = NST_Restart;
    restartType = (NdbRestartType)
      globalEmulatorData.theConfiguration->getRestartOnErrorInsert();
    if(restartType == NRT_Default){
      type = NST_ErrorHandler;
      globalEmulatorData.theConfiguration->stopOnError(true);
    }
  }
  
  if(NdbMutex_Trylock(theShutdownMutex) == 0){
    globalData.theRestartFlag = perform_stop;

    bool restart = false;
#if ! ( defined NDB_OSE || defined NDB_SOFTOSE) 
    if((type != NST_Normal && 
	globalEmulatorData.theConfiguration->stopOnError() == false) ||
       type == NST_Restart) {
      
      restart  = true;
    }
#endif
    
    const char * shutting = "shutting down";
    if(restart){
      shutting = "restarting";
    }
    
    switch(type){
    case NST_Normal:
      ndbout << "Shutdown initiated" << endl;
      break;
    case NST_Watchdog:
      ndbout << "Watchdog " << shutting << " system" << endl;
      break;
    case NST_ErrorHandler:
      ndbout << "Error handler " << shutting << " system" << endl;
      break;
    case NST_Restart:
      ndbout << "Restarting system" << endl;
      break;
    default:
      ndbout << "Error handler " << shutting << " system"
	     << " (unknown type: " << type << ")" << endl;
      type = NST_ErrorHandler;
      break;
    }
    
    const char * exitAbort = 0;
#if defined VM_TRACE && ( ! ( defined NDB_OSE || defined NDB_SOFTOSE) )
    exitAbort = "aborting";
#else
    exitAbort = "exiting";
#endif
    
    if(type == NST_Watchdog){
      /**
169
       * Very serious, don't attempt to free, just die!!
170 171 172
       */
      ndbout << "Watchdog shutdown completed - " << exitAbort << endl;
#if defined VM_TRACE && ( ! ( defined NDB_OSE || defined NDB_SOFTOSE) )
173
      signal(6, SIG_DFL);
174 175
      abort();
#else
176
      exit(-1);
177 178
#endif
    }
179
    
180 181 182 183 184 185 186 187 188 189 190 191
    globalEmulatorData.theWatchDog->doStop();
    
#ifdef VM_TRACE
    FILE * outputStream = globalSignalLoggers.setOutputStream(0);
    if(outputStream != 0)
      fclose(outputStream);
#endif
    
    globalTransporterRegistry.stopSending();
    globalTransporterRegistry.stopReceiving();
    
    globalTransporterRegistry.removeAll();
192
    
193 194 195 196 197 198 199 200 201
#ifdef VM_TRACE
#define UNLOAD (type != NST_ErrorHandler && type != NST_Watchdog)
#else
#define UNLOAD true
#endif
    if(UNLOAD){
      globalEmulatorData.theSimBlockList->unload();    
      globalEmulatorData.destroy();
    }
202 203
    
    if(type != NST_Normal && type != NST_Restart){
204 205
      ndbout << "Error handler shutdown completed - " << exitAbort << endl;
#if defined VM_TRACE && ( ! ( defined NDB_OSE || defined NDB_SOFTOSE) )
206
      signal(6, SIG_DFL);
207 208
      abort();
#else
209
      exit(-1);
210 211 212 213
#endif
    }
    
    /**
214
     * This is a normal restart, depend on angel
215 216
     */
    if(type == NST_Restart){
217
      exit(restartType);
218
    }
219
    
220 221 222 223 224
    ndbout << "Shutdown completed - exiting" << endl;
  } else {
    /**
     * Shutdown is already in progress
     */
225
    
226 227 228 229 230 231
    /** 
     * If this is the watchdog, kill system the hard way
     */
    if (type== NST_Watchdog){
      ndbout << "Watchdog is killing system the hard way" << endl;
#if defined VM_TRACE && ( ! ( defined NDB_OSE || defined NDB_SOFTOSE) )
232
      signal(6, SIG_DFL);
233 234
      abort();
#else
235
      exit(-1);
236 237
#endif
    }
238
    
239 240 241 242 243
    while(true)
      NdbSleep_MilliSleep(10);
  }
}