Int32 runESP(Int32 argc, char** argv, GuaReceiveFastStart *guaReceiveFastStart) { // initialize ESP global data StatsGlobals * statsGlobals; XCONTROLMESSAGESYSTEM(XCTLMSGSYS_SETRECVLIMIT, XMAX_SETTABLE_RECVLIMIT_H); CliGlobals *cliGlobals = NULL; cliGlobals = CliGlobals::createCliGlobals(TRUE); // TRUE indicates a non-master process (WAIT on LREC) if (cliGlobals == NULL) // Sanity check NAExit(1); // Abend Int32 shmid; statsGlobals = shareStatsSegment(shmid); cliGlobals->setSharedMemId(shmid); //Lng32 numCliCalls = cliGlobals->incrNumOfCliCalls(); cliGlobals->setIsESPProcess(TRUE); NAHeap *espExecutorHeap = cliGlobals->getExecutorMemory(); // must create default context after set IpcEnvironment in CliGlobals first // because context's ExSqlComp object needs IpcEnvironment cliGlobals->initiateDefaultContext(); NAHeap *espIpcHeap = cliGlobals->getIpcHeap(); IpcEnvironment *ipcEnvPtr = cliGlobals->getEnvironment(); if (statsGlobals != NULL) cliGlobals->setMemoryMonitor(statsGlobals->getMemoryMonitor()); else { // Start the memory monitor for dynamic memory management Lng32 memMonitorWindowSize = 10; Lng32 memMonitorSampleInterval = 10; MemoryMonitor *memMonitor = new (espExecutorHeap) MemoryMonitor(memMonitorWindowSize, memMonitorSampleInterval, espExecutorHeap); cliGlobals->setMemoryMonitor(memMonitor); } // After CLI globals are initialized but before we begin ESP message // processing, have the CLI context set its user identity based on // the OS user identity. ContextCli *context = cliGlobals->currContext(); ex_assert(context, "Invalid context pointer"); context->initializeUserInfoFromOS(); ExEspFragInstanceDir espFragInstanceDir(cliGlobals, espExecutorHeap, (StatsGlobals *)statsGlobals); ExEspControlMessage espIpcControlMessage(&espFragInstanceDir, ipcEnvPtr, espIpcHeap); // handle startup (command line args, control connection) DoEspStartup(argc,argv,*ipcEnvPtr,espFragInstanceDir,guaReceiveFastStart); // the control message stream talks through the control connection espIpcControlMessage.addRecipient( ipcEnvPtr->getControlConnection()->getConnection()); // start the first receive operation espIpcControlMessage.receive(FALSE); NABoolean timeout; Int64 prevWaitTime = 0; // while there are requesters while (espFragInstanceDir.getNumMasters() > 0) { // ----------------------------------------------------------------- // The ESPs most important line of code: DO THE WORK // ----------------------------------------------------------------- espFragInstanceDir.work(prevWaitTime); // ----------------------------------------------------------------- // After we have done work, it's necessary to wait for some I/O // (the frag instance dir work procedure works until it is blocked). // ----------------------------------------------------------------- ipcEnvPtr->getAllConnections()-> waitOnAll(IpcInfiniteTimeout, TRUE, &timeout, &prevWaitTime); // TRUE means: Called by ESP main } // nobody wants us anymore, right now that means that we stop return 0; }
void runServer(Int32 argc, char **argv) { Int32 shmid; jmp_buf sscpJmpBuf; StatsGlobals *statsGlobals = NULL; void *statsGlobalsAddr; NABoolean createStatsGlobals = FALSE; CliGlobals *cliGlobals = CliGlobals::createCliGlobals(FALSE); char tmbuf[64]; time_t now; struct tm *nowtm; long maxSegSize = STATS_MAX_SEG_SIZE; char *envSegSize = getenv("MX_RTS_STATS_SEG_SIZE"); if (envSegSize) { maxSegSize = (long) str_atoi(envSegSize, str_len(envSegSize)); if (maxSegSize < 32) maxSegSize = 32; else if (maxSegSize > 256) maxSegSize = 256; maxSegSize *= 1024 * 1024; } long enableHugePages = 0; int shmFlag = RMS_SHMFLAGS; char *envShmHugePages = getenv("SQ_RMS_ENABLE_HUGEPAGES"); if (envShmHugePages != NULL) { enableHugePages = (long) str_atoi(envShmHugePages, str_len(envShmHugePages)); if (enableHugePages > 0) shmFlag = shmFlag | SHM_HUGETLB; } now = time(NULL); nowtm = localtime(&now); strftime(tmbuf, sizeof tmbuf, "%Y-%m-%d %H:%M:%S ", nowtm); if ((shmid = shmget((key_t)getStatsSegmentId(), 0, // size doesn't matter unless we are creating. shmFlag)) == -1) { if (errno == ENOENT) { // Normal case, segment does not exist yet. Try to create. bool didCreate = true; if ((shmid = shmget((key_t)getStatsSegmentId(), maxSegSize, shmFlag | IPC_CREAT)) == -1) { if (enableHugePages > 0) { enableHugePages = 0; // try again withouf hugepages shmFlag = shmFlag & ~SHM_HUGETLB; if ((shmid = shmget((key_t)getStatsSegmentId(), maxSegSize, shmFlag | IPC_CREAT)) == -1) didCreate = false; } else didCreate = false; } if (didCreate) { cout << tmbuf << " RMS Shared segment id = " << shmid << ", key = " << (key_t)getStatsSegmentId() ; if (enableHugePages > 0) cout << ", created with huge pages support." << endl; else cout << ", created without huge pages support." << endl; createStatsGlobals = TRUE; } else { cout << tmbuf << " Shmget failed, key = " << getStatsSegmentId() <<", Error code: " << errno << " (" << strerror(errno) << ")" << endl; exit(errno); } } // if ENOENT (i.e., attempting creation.) } else { cout << tmbuf << " RMS Shared segment exists, attaching to it, shmid="<< shmid << ", key=" << (key_t)getStatsSegmentId() << "\n"; } if ((statsGlobalsAddr = shmat(shmid, getRmsSharedMemoryAddr(), 0)) == (void *)-1) { cout << tmbuf << "Shmat failed, shmid=" <<shmid << ", key=" << (key_t) getStatsSegmentId() << ", Error code : " << errno << "(" << strerror(errno) << ")\n"; exit(errno); } char *statsGlobalsStartAddr = (char *)statsGlobalsAddr; if (createStatsGlobals) { short envType = StatsGlobals::RTS_GLOBAL_ENV; statsGlobals = new (statsGlobalsStartAddr) StatsGlobals((void *)statsGlobalsAddr, envType, maxSegSize); cliGlobals->setSharedMemId(shmid); // We really should not squirrel the statsGlobals pointer away like // this until the StatsGloblas is initialized, but // statsGlobals->init() needs it ...... cliGlobals->setStatsGlobals(statsGlobals); statsGlobals->init(); } else { statsGlobals = (StatsGlobals *)statsGlobalsAddr; cliGlobals->setSharedMemId(shmid); cliGlobals->setStatsGlobals(statsGlobals); } XPROCESSHANDLE_GETMINE_(statsGlobals->getSscpProcHandle()); NAHeap *sscpHeap = cliGlobals->getExecutorMemory(); cliGlobals->setJmpBufPtr(&sscpJmpBuf); if (setjmp(sscpJmpBuf)) NAExit(1); // Abend IpcEnvironment *sscpIpcEnv = new (sscpHeap) IpcEnvironment(sscpHeap, cliGlobals->getEventConsumed(), FALSE, IPC_SQLSSCP_SERVER, FALSE, TRUE); SscpGlobals *sscpGlobals = NULL; sscpGlobals = new (sscpHeap) SscpGlobals(sscpHeap, statsGlobals); // Currently open $RECEIVE with 256 SscpGuaReceiveControlConnection *cc = new(sscpHeap) SscpGuaReceiveControlConnection(sscpIpcEnv, sscpGlobals, 256); sscpIpcEnv->setControlConnection(cc); while (TRUE) { while (cc->getConnection() == NULL) cc->wait(IpcInfiniteTimeout); #ifdef _DEBUG_RTS cerr << "No. of Requesters-1 " << cc->getNumRequestors() << " \n"; #endif while (cc->getNumRequestors() > 0) { sscpIpcEnv->getAllConnections()->waitOnAll(IpcInfiniteTimeout); } // Inner while } } // runServer