📄 stafproc.cpp
字号:
try { // XXX: Cannot stop the local connection provider because this // hangs the shutdown of STAFProc when exiting the outer try // block. It's hanging in the local connection provider's // STAFConnectionProviderConnect method when it calls // ConnectToPipe() (on the WaitForMutipleObjects() call within // the ConnectToPipe method). It actually should not have // gotten that far as it should have failed in GetPipeData() // issued before ConnectToPipe() in the local connection // provider's STAFConnectionProviderConnect method. // Probably, it's due to a file mapping (that we aren't saving // a reference to) not getting closed. if ((*cpIter)->getName() != "local") (*cpIter)->stop(); } catch (STAFException &se) { STAFString message = STAFString("Error stopping ") + (*cpIter)->getName() + " interface. Error code: " + se.getErrorCode() + " Reason: " + se.getText(); STAFTrace::trace(kSTAFTraceError, message); } } // Get rid of connection provider references connProvList = STAFConnectionManager::ConnectionProviderList(); // XXX: Without this sleep, the system doesn't get time to cleanup // everything before the main thread ends, resulting in an extra // message stating that terminate() was called. I should probably // try to debug this further, but this masks the problem sufficiently // at the moment. gThreadManagerPtr->sleepCurrentThread(1000); // Clean up any OS specific stuff. int stafOSTermRC = STAFProcOSTerm(errorBuffer, osRC); if (stafOSTermRC != 0) { STAFString message("Error during platform-specific termination: "); message += errorBuffer + ", RC: " + STAFString(osRC); STAFTrace::trace(kSTAFTraceError, message); return 1; } } catch (STAFException &se) { se.write("main()"); } catch (...) { cout << "Caught unknown exception in main()" << endl; } return 0;}STAFRC_t HandleRequest(const STAFConnectionProvider *provider, STAFConnectionPtr &connection){ unsigned int doShutdown = 0; try { unsigned int readBuffer[2]; connection->read(readBuffer, sizeof(readBuffer)); unsigned int apiNum = STAFUtilConvertLEUIntToNative(readBuffer[0]); unsigned int apiLevel = STAFUtilConvertLEUIntToNative(readBuffer[1]); unsigned int minLevel = apiLevel; unsigned int maxLevel = apiLevel; if ((apiNum <= gMaxAPINumber) && (apiLevel == 0) && (gAPITable[apiNum].apiType == kNewAPI)) { // Need to send the ok and then read the min and max levels connection->writeUInt(kSTAFOk); minLevel = connection->readUInt(); maxLevel = connection->readUInt(); } if (apiNum > gMaxAPINumber) { if (STAFTrace::doTrace(kSTAFTraceDebug)) { STAFString message("Invalid API number ("); message += STAFString(apiNum) + ") received"; STAFTrace::trace(kSTAFTraceDebug, message); } connection->writeUInt(kSTAFInvalidAPI); } else if ((maxLevel < gAPITable[apiNum].minLevel) || (minLevel > gAPITable[apiNum].maxLevel)) { if (STAFTrace::doTrace(kSTAFTraceDebug)) { STAFString message("Invalid API level ("); message += STAFString(apiLevel) + ") received for API number " + apiNum; STAFTrace::trace(kSTAFTraceDebug, message); } connection->writeUInt(kSTAFInvalidAPILevel); } else if ((provider->getName() == sLowerLocal) ? !gAPITable[apiNum].availLocal : !gAPITable[apiNum].availRemote) { if (STAFTrace::doTrace(kSTAFTraceDebug)) { STAFString message("Invalid connection provider ("); message += provider->getName() + ") used for API number " + apiNum; STAFTrace::trace(kSTAFTraceDebug, message); } connection->writeUInt(kSTAFInvalidAPI); } else { if (gAPITable[apiNum].apiType == kOldAPI) { connection->writeUInt(kSTAFOk); } else { apiLevel = STAF_MIN(maxLevel, gAPITable[apiNum].maxLevel); connection->writeUInt(apiLevel); } gAPITable[apiNum].handler(apiLevel, provider, connection, doShutdown); } } catch (STAFConnectionIOException) { // A client has unexpectedly terminated the connection // Do nothing, cleanup is automatic STAFTrace::trace( kSTAFTraceDebug, "HandleRequest(): Connection terminated unexpectedly"); } catch (STAFException &se) { se.trace("HandleRequest()"); } catch (...) { STAFTrace::trace( kSTAFTraceError, "Caught unknown exception in HandleRequest()"); } if (doShutdown) gShutdownSemaphore->post(); return kSTAFOk;}void handleLocalServiceRequestAPI(unsigned int level, const STAFConnectionProvider *provider, STAFConnectionPtr &connection, unsigned int &doShutdown){ unsigned int readBuffer[6]; connection->read(readBuffer, sizeof(readBuffer)); STAFProcessID_t pid = STAFUtilConvertLEUIntToNative(readBuffer[1]); unsigned int whereLength = STAFUtilConvertLEUIntToNative(readBuffer[3]); unsigned int serviceLength = STAFUtilConvertLEUIntToNative(readBuffer[4]); unsigned int requestLength = STAFUtilConvertLEUIntToNative(readBuffer[5]); unsigned int buffSize = whereLength + serviceLength + requestLength; STAFBuffer<char> buffer(new char[buffSize], STAFBuffer<char>::INIT); connection->read(buffer, buffSize); STAFServiceRequestPtr serviceRequestPtr = gRequestManager.getNewServiceRequest(); STAFServiceRequest &serviceRequest = *serviceRequestPtr; serviceRequest.fSyncMode = STAFUtilConvertLEUIntToNative(readBuffer[0]); serviceRequest.fMachineNickname = gMachineNickname; serviceRequest.fHandle = STAFUtilConvertLEUIntToNative(readBuffer[2]); serviceRequest.fRequest = STAFString(buffer + whereLength + serviceLength, requestLength, STAFString::kUTF8); serviceRequest.fDiagEnabled = gDiagManager.getEnabled(); serviceRequest.fInterface = provider->getName(); connection->getPeerNetworkIDs(serviceRequest.fLogicalInterfaceID, serviceRequest.fPhysicalInterfaceID); serviceRequest.fMachine = serviceRequest.fLogicalInterfaceID; serviceRequest.fEndpoint = serviceRequest.fInterface + gSpecSeparator + serviceRequest.fLogicalInterfaceID + provider->getProperty(kSTAFConnectionProviderPortProperty); serviceRequest.fSTAFInstanceUUID = gSTAFInstanceUUID; serviceRequest.fIsLocalRequest = true; STAFRC_t rc = gHandleManager.updateTimestamp(serviceRequest.fHandle, pid); if (rc != kSTAFOk) { STAFString errorMsg = STAFString( "HandleManager::updateTimestamp() failed to update handle ") + serviceRequest.fHandle; connection->writeUInt(rc); connection->writeString(errorMsg); return; } serviceRequest.fHandleName = gHandleManager.name(serviceRequest.fHandle); rc = gHandleManager.variablePool(serviceRequest.fHandle, serviceRequest.fRequestVarPool); if (rc != kSTAFOk) { STAFString errorMsg = STAFString( "HandleManager::variablePool() failed to get the variable pool " "for handle ") + serviceRequest.fHandle; connection->writeUInt(rc); connection->writeString(errorMsg); return; } serviceRequest.fSourceSharedVarPool = STAFVariablePoolPtr(new STAFVariablePool, STAFVariablePoolPtr::INIT); serviceRequest.fLocalSharedVarPool = *gSharedVariablePoolPtr; serviceRequest.fLocalSystemVarPool = *gGlobalVariablePoolPtr; gHandleManager.getAuthenticationInfo(serviceRequest.fHandle, serviceRequest.fAuthenticator, serviceRequest.fUserIdentifier, serviceRequest.fAuthenticationData); serviceRequest.fUser = serviceRequest.fAuthenticator + gSpecSeparator + serviceRequest.fUserIdentifier; DEFINE_VAR_POOL_LIST(varPoolList, varPoolListSize, serviceRequest); STAFString unresWhere(buffer, whereLength, STAFString::kUTF8); STAFString errorBuffer; rc = RESOLVE_STRING(unresWhere, serviceRequest.fTargetMachine); if (rc != kSTAFOk) { connection->writeUInt(rc); connection->writeString(errorBuffer); return; } serviceRequest.fTargetService = STAFString(buffer + whereLength, serviceLength, STAFString::kUTF8); // Resolved string, where, is stripped to allow begining and/or trailing // white spaces serviceRequest.fTargetMachine = serviceRequest.fTargetMachine.strip(STAFString::kBoth); rc = gRequestManager.add(serviceRequestPtr); try { if ((serviceRequest.fTargetMachine.isEqualTo( sLocal, kSTAFStringCaseInsensitive)) || (serviceRequest.fTargetMachine.isEqualTo( sLocalLong, kSTAFStringCaseInsensitive))) { // Local service request serviceRequest.fTargetMachine = gMachine; serviceRequest.fMachine = gMachine; STAFString serviceName; rc = RESOLVE_STRING(serviceRequest.fTargetService, serviceName); if (rc != kSTAFOk) { serviceRequest.fResult.fRC = rc; serviceRequest.fResult.fResult = errorBuffer; } else { // Resolved string, serviceName, is stripped to allow // begining and/or trailing white spaces serviceRequest.fTargetService = serviceName.strip(STAFString::kBoth); // Strip any whitespace from the beginning of a request serviceRequest.fRequest = serviceRequest.fRequest.strip(STAFString::kFront); serviceRequest.fResult = submitLocalRequest(connection, serviceRequest); } } else { // Service request to a remote system serviceRequest.fResult = submitRemoteRequest(connection, serviceRequest); } if (serviceRequest.fSyncMode == kSTAFReqSync) { connection->writeUInt(serviceRequest.fResult.fRC); connection->writeString(serviceRequest.fResult.fResult); } doShutdown = serviceRequest.fResult.fDoShutdown; } catch (STAFException &e) { if ((serviceRequest.fSyncMode == kSTAFReqRetain) || (serviceRequest.fSyncMode == kSTAFReqQueueRetain)) { serviceRequest.fResult.fRC = e.getErrorCode(); serviceRequest.fResult.fResult = e.getText(); gRequestManager.requestCompleted(serviceRequest.fRequestNumber, serviceRequest.fResult); } else { if (gRequestManager.requestExists(serviceRequest.fRequestNumber)) gRequestManager.deleteRequest(serviceRequest.fRequestNumber); } throw; } catch (...) { if (gRequestManager.requestExists(serviceRequest.fRequestNumber)) gRequestManager.deleteRequest(serviceRequest.fRequestNumber); throw; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -