📄 staflocalipcconnprovider.cpp
字号:
/*****************************************************************************//* Software Testing Automation Framework (STAF) *//* (C) Copyright IBM Corp. 2001, 2004 *//* *//* This software is licensed under the Common Public License (CPL) V1.0. *//*****************************************************************************/#include "STAF.h"#include <fcntl.h>#include <sys/un.h>#include "STAFConnectionProvider.h"#include "STAFSocket.h"#include "STAFUtil.h"#include "STAFString.h"#include "STAFEventSem.h"#include "STAFTrace.h"#include "STAFInternalUtil.h"#include "STAFThreadManager.h"#include <set>#include <stdlib.h>// XXX: Might want to look at adding someing like kSTAFConnectionError, instead// of using kSTAFBaseOSError in this code. Same goes for Local IPC.#define CATCH_STANDARD(functionString) \catch (STAFException &e)\{\ if (errorBuffer)\ {\ *errorBuffer = getExceptionString(e, "STAFLocalIPCConnProvider.cpp: "\ functionString)\ .adoptImpl();\ }\}\catch (...)\{\ if (errorBuffer)\ {\ STAFString error("STAFLocalIPCConnProvider.cpp: Caught unknown "\ "exception in " functionString "()");\ *errorBuffer = error.adoptImpl();\ }\}#define CATCH_STANDARD_TRACE(functionString) \catch (STAFException &e)\{\ STAFTrace::trace(kSTAFTraceError,\ getExceptionString(e, "STAFLocalIPCConnProvider.cpp: "\ functionString));\}\catch (...)\{\ STAFTrace::trace(kSTAFTraceError,\ "STAFLocalIPCConnProvider.cpp: Caught unknown exception "\ "in " functionString "()");\}#ifdef STAF_OS_NAME_HPUXextern "C"{ void _main();}#endif// PrototypesSTAFRC_t STAFConnectionProviderConstruct(STAFConnectionProvider_t *provider, void *constructInfo, unsigned int constructInfoLevel, STAFString_t *errorBuffer);STAFRC_t STAFConnectionProviderStart(STAFConnectionProvider_t provider, void *startInfo, unsigned int startInfoLevel, STAFString_t *errorBuffer);STAFRC_t STAFConnectionProviderStop(STAFConnectionProvider_t provider, void *stopInfo, unsigned int stopInfoLevel, STAFString_t *errorBuffer);STAFRC_t STAFConnectionProviderDestruct(STAFConnectionProvider_t *provider, void *destructInfo, unsigned int destructInfoLevel, STAFString_t *errorBuffer);STAFRC_t STAFConnectionProviderConnect(STAFConnectionProvider_t provider, STAFConnection_t *connection, void *connectInfo, unsigned int connectInfoLevel, STAFString_t *errorBuffer);STAFRC_t STAFConnectionProviderGetMyNetworkIDs(STAFConnectionProvider_t provider, STAFStringConst_t *logicalID, STAFStringConst_t *physicalD, STAFString_t *errorBuffer);STAFRC_t STAFConnectionProviderGetOptions( STAFConnectionProvider_t provider, STAFObject_t *options, STAFString_t *errorBuffer);STAFRC_t STAFConnectionProviderGetProperty( STAFConnectionProvider_t provider, STAFConnectionProviderProperty_t property, STAFStringConst_t *value, STAFString_t *errorBuffer);STAFRC_t STAFConnectionRead(STAFConnection_t connection, void *buffer, unsigned int readLength, STAFString_t *errorBuffer);STAFRC_t STAFConnectionReadUInt(STAFConnection_t connection, unsigned int *uint, STAFString_t *errorBuffer);STAFRC_t STAFConnectionReadSTAFString(STAFConnection_t connection, STAFString_t *stafString, STAFString_t *errorBuffer);STAFRC_t STAFConnectionWrite(STAFConnection_t connection, void *buffer, unsigned int writeLength, STAFString_t *errorBuffer);STAFRC_t STAFConnectionWriteUInt(STAFConnection_t connection, unsigned int uint, STAFString_t *errorBuffer);STAFRC_t STAFConnectionWriteSTAFString(STAFConnection_t connection, STAFStringConst_t stafString, STAFString_t *errorBuffer);STAFRC_t STAFConnectionGetPeerNetworkIDs(STAFConnection_t connection, STAFStringConst_t *logicalID, STAFStringConst_t *physicalD, STAFString_t *errorBuffer);STAFRC_t STAFConnectionDestruct(STAFConnection_t *connection, STAFString_t *errorBuffer);static STAFConnectionProviderFunctionTable gFuncTable ={ STAFConnectionProviderConstruct, STAFConnectionProviderStart, STAFConnectionProviderStop, STAFConnectionProviderDestruct, STAFConnectionProviderConnect, STAFConnectionProviderGetMyNetworkIDs, STAFConnectionProviderGetOptions, STAFConnectionProviderGetProperty, STAFConnectionRead, STAFConnectionReadUInt, STAFConnectionReadSTAFString, STAFConnectionWrite, STAFConnectionWriteUInt, STAFConnectionWriteSTAFString, STAFConnectionGetPeerNetworkIDs, STAFConnectionDestruct};struct STAFLocalConnectionProviderImpl : STAFConnectionProviderImpl{ STAFConnectionProviderMode_t mode; void *data; STAFString_t ipcName; STAFSocket_t serverSocket; STAFString logicalNetworkID; STAFString physicalNetworkID; STAFObjectPtr options; STAFString portProperty; STAFString isSecureProperty; STAFConnectionProviderNewConnectionFunc_t connFunc; STAFEventSemPtr syncSem; STAFConnectionProviderState_t state; STAFThreadManagerPtr threadManager;};struct STAFLocalConnectionImpl : STAFConnectionImpl{ STAFSocket_t clientSocket; // XXX: HACK HACK // Due to an unknown bug on Linux, these strings need to be here // to prevent corruption of the corresponding tcp/ip connection // provider. It appears that some form of copy // assignment/construction operator from this structure replaces // one for the tcp/ip version and the buffer below zeros out the // strings in the corresponding spot in the tcp/ip provider. STAFString dummyLogicalNetworkID; STAFString dummyPhysicalNetworkID; // ???: Look at moving this buffer into the read/write functions. It will // make the read/write functions thread safe. Just need to make sure // it doesn't hurt performance. char buffer[4096];};struct LocalConnectionData{ STAFConnectionProviderNewConnectionFunc_t connFunc; STAFLocalConnectionProviderImpl *provider; STAFLocalConnectionImpl *connection;};typedef std::set<STAFConnectionProvider_t> ProviderSet;static STAFMutexSem sActiveProvidersSem;static ProviderSet sActiveProviders;void atExit(){ ProviderSet activeProvidersCopy; { STAFMutexSemLock lock(sActiveProvidersSem); activeProvidersCopy = sActiveProviders; } for (ProviderSet::iterator iter = activeProvidersCopy.begin(); iter != activeProvidersCopy.end(); ++iter) { STAFConnectionProvider_t thisProvider = *iter; // XXX: Clean up. I.e., kill threads, etc. }}unsigned int STAFLocalIPCConnectionThread(void *data){ try { LocalConnectionData *connData = reinterpret_cast<LocalConnectionData *>(data); connData->connFunc(connData->provider, connData->connection, &gFuncTable, connData->provider->data); delete connData; } CATCH_STANDARD_TRACE("STAFLocalIPCConnectionThread"); return 0;}unsigned int STAFTCPRunThread(void *providerImpl){ STAFLocalConnectionProviderImpl *provider = reinterpret_cast<STAFLocalConnectionProviderImpl *>(providerImpl); try { provider->syncSem->post(); while (provider->state == kSTAFConnectionProviderActive) { STAFLocalConnectionImpl connImpl; struct sockaddr_in clientAddress = { 0 }; STAFSocketLen_t clientAddressLength = sizeof(clientAddress); do { connImpl.clientSocket = accept( provider->serverSocket, reinterpret_cast<struct sockaddr *>(&clientAddress), &clientAddressLength); } while (!STAFUtilIsValidSocket(connImpl.clientSocket) && (STAFSocketGetLastError() == SOCEINTR) && (provider->state != kSTAFConnectionProviderStopped)); if (provider->state == kSTAFConnectionProviderStopped) break; if (!STAFUtilIsValidSocket(connImpl.clientSocket)) { STAFTrace::trace(kSTAFTraceError, STAFString("Error accepting on server socket" ", socket RC: ") + STAFString(STAFSocketGetLastError())); continue; } // Set the socket to be non-inheritable unsigned int osRC = 0; STAFSocket_t newSocket; if (STAFUtilGetNonInheritableSocket(connImpl.clientSocket, &newSocket, &osRC)) { STAFTrace::trace( kSTAFTraceError, STAFString("Error getting non-inheritable socket, " "STAFUtilGetNonInheritableSocket(), OS RC: ") + STAFString(osRC)); continue; } connImpl.clientSocket = newSocket; // Ok, let's perform the callback now LocalConnectionData connData; connData.connFunc = provider->connFunc; connData.provider = provider; connData.connection = new STAFLocalConnectionImpl(connImpl); provider->threadManager->dispatch( STAFLocalIPCConnectionThread, new LocalConnectionData(connData)); } } CATCH_STANDARD_TRACE("STAFTCPRunThread"); try { provider->syncSem->post(); } CATCH_STANDARD_TRACE("STAFTCPRunThread"); return 0;}STAFRC_t STAFConnectionProviderConstruct(STAFConnectionProvider_t *provider, void *constructInfo, unsigned int constructInfoLevel, STAFString_t *errorBuffer){ if (provider == 0) return kSTAFInvalidParm; if (constructInfoLevel != 1) return kSTAFInvalidAPILevel; STAFConnectionProviderConstructInfoLevel1 *cpInfo = reinterpret_cast<STAFConnectionProviderConstructInfoLevel1 *>( constructInfo); try { static bool initedAtExit = false; if (!initedAtExit) { STAFMutexSemLock lock(sActiveProvidersSem); if (!initedAtExit) atexit(atExit); } STAFLocalConnectionProviderImpl lipcData; lipcData.mode = cpInfo->mode; lipcData.syncSem = STAFEventSemPtr(new STAFEventSem, STAFEventSemPtr::INIT); lipcData.state = kSTAFConnectionProviderStopped; lipcData.ipcName = STAFString("STAF").adoptImpl(); lipcData.serverSocket = 0; lipcData.threadManager = STAFThreadManagerPtr(new STAFThreadManager, STAFThreadManagerPtr::INIT); // Get instance name if (getenv("STAF_INSTANCE_NAME") != NULL) { lipcData.ipcName = STAFString( getenv("STAF_INSTANCE_NAME")).adoptImpl(); } for (unsigned int i = 0; i < cpInfo->numOptions; ++i) { STAFString thisOption = STAFString(cpInfo->optionNames[i]).upperCase();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -