📄 stafperlservice.cpp
字号:
/*****************************************************************************//* Software Testing Automation Framework (STAF) *//* (C) Copyright IBM Corp. 2004 *//* *//* This software is licensed under the Common Public License (CPL) V1.0. *//*****************************************************************************/#include "STAF.h"#include <vector>#include <map>#include "STAFServiceInterface.h"#include "STAFPerlService.h"#include "STAFConnectionProvider.h"#include "STAFUtil.h"#include "STAFThread.h"#include "STAFEventSem.h"#include "STAFMutexSem.h"#include "STAFProcess.h"#include "STAFFileSystem.h"#include "STAFTrace.h"#include "STAF_fstream.h"struct PerlInterpreterData{ STAFString fName; STAFString fExec; STAFString fOptions; STAFConnectionProviderPtr fConnProv; STAFEventSemPtr fPerlInterpreterExitedSem; STAFProcessID_t fPerlInterpreter_PID; unsigned int fNumServices;};typedef STAFRefPtr<PerlInterpreterData> PerlInterpreterDataPtr;typedef std::map<STAFString, PerlInterpreterDataPtr> PerlInterpreterDataMap;struct PerlInterpreterStartThreadData{ PerlInterpreterStartThreadData (STAFString_t startString, STAFEventSemPtr &exitedSem) : fStartString(startString), fPerlInterpreterExitedSem(exitedSem) { /* Do nothing */ } STAFString_t fStartString; STAFEventSemPtr fPerlInterpreterExitedSem;};struct STAFProcPerlServiceData{ STAFString fName; STAFString fExec; PerlInterpreterDataPtr fPerlInterpreter;};static PerlInterpreterDataMap sPerlInterpreterDataMap;static STAFMutexSem sPerlInterpreterDataSem;static STAFString sLocal("local");static STAFString sIPCName("IPCNAME");STAFRC_t STAFServiceGetLevelBounds(unsigned int levelID, unsigned int *minimum, unsigned int *maximum){ switch (levelID) { case kServiceInfo: { *minimum = 30; *maximum = 30; break; } case kServiceInit: { *minimum = 30; *maximum = 30; break; } case kServiceAcceptRequest: { *minimum = 30; *maximum = 30; break; } case kServiceTerm: case kServiceDestruct: { *minimum = 0; *maximum = 0; break; } default: { return kSTAFInvalidAPILevel; } } return kSTAFOk;}unsigned int STAFDoShutdownPerlInterpreter(STAFConnectionProviderPtr &connProv){ try { STAFConnectionPtr connPtr = connProv->connect(sLocal); connPtr->writeUInt(PERL_SERVICE_PERL_INTERPRETER_EXIT); STAFRC_t perlInterpreterRC = connPtr->readUInt(); STAFString perlInterpreterResultString = connPtr->readString(); // Note, this last connect is required depending on the thread timing // in STAFPerlServiceHelper.cpp. In that file, if the request // thread gets started before the creating thread gets control back, // then this call is unnecessary. Otherwise, we need to send this // final request so that the main thread will be able to check the // exit flag. connPtr = connProv->connect(sLocal); connPtr->writeUInt(PERL_SERVICE_PERL_INTERPRETER_FIN); } catch (STAFConnectionProviderException) { // These execptions are anticipated in cases where the PerlInterpreter // has already shutdown before we send the shutdown commands } return 0;}// Note: You should already own sPerlInterpreterDataSem before// calling STAFShutdownJMVunsigned int STAFShutdownPerlInterpreter(STAFString &perlInterpreterName){ try { PerlInterpreterDataPtr perlInterpreter = sPerlInterpreterDataMap[perlInterpreterName]; sPerlInterpreterDataMap.erase(perlInterpreterName); STAFDoShutdownPerlInterpreter(perlInterpreter->fConnProv); } catch (STAFException &e) { e.trace("PLSTAF.STAFShutdownPerlInterpreter()"); } catch (...) { STAFTrace::trace( kSTAFTraceError, "Caught unknown exception in " "PLSTAF.STAFShutdownPerlInterpreter()"); } return 0;}STAFRC_t STAFServiceConstruct(STAFServiceHandle_t *pServiceHandle, void *pServiceInfo, unsigned int infoLevel, STAFString_t *pErrorBuffer){ try { if (infoLevel != 30) return kSTAFInvalidAPILevel; STAFProcPerlServiceData data; STAFServiceInfoLevel30 *pInfo = static_cast<STAFServiceInfoLevel30 *>(pServiceInfo); STAFString perlServiceName = pInfo->name; STAFString perlServiceExec = pInfo->exec; STAFString perlInterpreterExec = "perl "; STAFString perlInterpreterOptions = ""; bool perlInterpreterSpecified = false; unsigned int maxLogs = 5; // Defaults to keeping 5 PerlInterpreter logs long maxLogSize = 1048576; // Default size of each log is 1M data.fName = pInfo->name; data.fExec = pInfo->exec; //XXX: Can't think of a way to make sure the STAFRoot/lib dir is in the // include path, so I'm grabbing it from STAF STAFHandlePtr handlePtr; STAFRC_t retcode = STAFHandle::create("STAF/Service/STAFPerlService", handlePtr); if (retcode != kSTAFOk) { return retcode; } STAFResultPtr stafRootResultPtr = handlePtr->submit("local", "var", "resolve string {STAF/Config/STAFRoot}"); if(stafRootResultPtr->rc != 0) { return stafRootResultPtr->rc; } // XXX: Need to unregister this handle here STAFString libDir = stafRootResultPtr->result; libDir = libDir.replace("\\", "/"); // switch all backslashes to forward perlInterpreterOptions += "-I" + libDir + "/lib "; // Walk through and verify the config options for (unsigned int i = 0; i < pInfo->numOptions; ++i) { STAFString upperOptionName = STAFString(pInfo->pOptionName[i]).upperCase(); STAFString optionValue(pInfo->pOptionValue[i]); if (upperOptionName == "PERLEXEC") { perlInterpreterExec = optionValue; perlInterpreterSpecified = true; } else if (upperOptionName == "MAXLOGS") { // Check to make sure it is an integer value > 0 STAFString maxLogsStr = optionValue; if (maxLogsStr.isDigits() && (maxLogsStr.asUInt() > 0)) { maxLogs = maxLogsStr.asUInt(); } else { STAFString errmsg( "Error constructing the Perl Interpreter using " "Perl Service Name: " + perlServiceName + ", PerlServiceExec " + perlServiceExec + ", Perl Interpreter: " + perlInterpreterExec + ", Perl Interpreter Options: " + perlInterpreterOptions + ", RC: " + STAFString(kSTAFInvalidValue) + ", MAXLOGS must be an positive integer"); *pErrorBuffer = errmsg.adoptImpl(); return kSTAFServiceConfigurationError; } } else if (upperOptionName == "MAXLOGSIZE") { // Check to make sure it is an integer value > 0 STAFString maxLogSizeStr = optionValue; if (maxLogSizeStr.isDigits() && (maxLogSizeStr.asUInt() > 0)) { maxLogSize = (long)maxLogSizeStr.asUInt(); } else { STAFString errmsg( "Error constructing the Perl Interpreter using " "Perl Service Name: " + perlServiceName + ", PerlServiceExec " + perlServiceExec + ", Perl Interpreter: " + perlInterpreterExec + ", Perl Interpreter Options: " + perlInterpreterOptions + ", RC: " + STAFString(kSTAFInvalidValue) + ", MAXLOGSIZE must be an positive integer"); *pErrorBuffer = errmsg.adoptImpl(); return kSTAFServiceConfigurationError; } } else if (upperOptionName == "PERLPARMS") { perlInterpreterOptions = perlInterpreterOptions + " " + optionValue; } else { STAFString optionError(pInfo->pOptionName[i]); *pErrorBuffer = optionError.adoptImpl(); return kSTAFServiceConfigurationError; } } // Check to see if the specified PerlInterpreter already exists STAFMutexSemLock lock(sPerlInterpreterDataSem); if (sPerlInterpreterDataMap.find(perlServiceName) == sPerlInterpreterDataMap.end()) { // The PerlInterpreter doesn't exist so we need to start it PerlInterpreterData perlInterpreterData; perlInterpreterData.fName = perlServiceName; perlInterpreterData.fExec = perlServiceExec; perlInterpreterData.fOptions = perlInterpreterOptions; perlInterpreterData.fPerlInterpreterExitedSem = STAFEventSemPtr(new STAFEventSem, STAFEventSemPtr::INIT); perlInterpreterData.fNumServices = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -