📄 stafhandlemanager.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 "STAFProc.h"#include "STAFHandleManager.h"#include "STAFProcess.h"#include "STAFTrace.h"#include "STAFServiceManager.h"#include "STAFProcUtil.h"#include "STAFHandleService.h"#include "STAFDiagManager.h"#include "STAFConnectionManager.h"#include "STAFThreadManager.h"unsigned int HandleMonitorThread(void *);static STAFHandleManager *pHandleManager = 0;static STAFThreadManager &getHandleThreadManager(){ static STAFThreadManager theThreadManager(1); return theThreadManager;}STAFHandleManager::STAFHandleManager() : fNextHandle(1){ pHandleManager = this; getHandleThreadManager().dispatch(HandleMonitorThread, 0);}void STAFHandleManager::processTerminated(STAFProcessID_t pid, STAFProcessHandle_t procHandle, unsigned int rc, void *){ pHandleManager->handleProcessTerminated(pid, procHandle);}unsigned int callHandleRemovedCallback(void *handleAsVoid){ STAFHandle_t *handlePtr = reinterpret_cast<STAFHandle_t *>(handleAsVoid); STAFHandleService::getInstance()->handleRemoved(*handlePtr); delete handlePtr; return 0;}void STAFHandleManager::handleProcessTerminated(STAFProcessID_t pid, STAFProcessHandle_t procHandle){ HandleList::iterator handleIter; // Basically, we loop through the list finding a registered handle with // the specified pid and procHandle. We only have to worry about registered // handles here. Pending handles are removed by the Process service, and we // never have static or in-process handles monitored by the ProcessManager. STAFMutexSemLock handleLock(fHandleListSem); for(handleIter = fHandleList.begin(); (handleIter != fHandleList.end()) && ((handleIter->second.pid != pid) || (handleIter->second.procHandle != procHandle) || (handleIter->second.state != kRegistered)); ++handleIter) { /* Do Nothing */ } if (handleIter != fHandleList.end()) { // Must dispatch calling the handleRemoved(handle) method so that it // runs on another thread and doesn't keep the lock on fHandleListSem. getHandleThreadManager().dispatch( callHandleRemovedCallback, new STAFHandle_t(handleIter->second.handle)); fHandleList.erase(handleIter); }}STAFString STAFHandleManager::name(STAFHandle_t handle){ STAFMutexSemLock handleLock(fHandleListSem); if (fHandleList.find(handle) != fHandleList.end()) return fHandleList[handle].name; return STAFString();}STAFRC_t STAFHandleManager::variablePool(STAFHandle_t handle, STAFVariablePoolPtr &pool){ STAFRC_t rc = kSTAFOk; STAFMutexSemLock handleLock(fHandleListSem); if (fHandleList.find(handle) != fHandleList.end()) pool = fHandleList[handle].variablePoolPtr; else rc = kSTAFHandleDoesNotExist; return rc;}STAFRC_t STAFHandleManager::handleQueue(STAFHandle_t handle, STAFHandleQueuePtr &queue){ STAFRC_t rc = kSTAFOk; STAFMutexSemLock handleLock(fHandleListSem); if (fHandleList.find(handle) != fHandleList.end()) queue = fHandleList[handle].handleQueuePtr; else rc = kSTAFHandleDoesNotExist; return rc;}std::vector<STAFHandle_t> STAFHandleManager::handlesWithName(STAFString name){ name.lowerCase(); std::vector<STAFHandle_t> handles; STAFMutexSemLock handleLock(fHandleListSem); HandleList::iterator handleIter; // XXX: This should be able to be done with some form of copy_if for(handleIter = fHandleList.begin(); handleIter != fHandleList.end(); ++handleIter) { if (name == handleIter->second.name.toLowerCase()) handles.push_back(handleIter->second.handle); } return handles;}STAFRC_t STAFHandleManager::updateTimestamp(STAFHandle_t handle, STAFProcessID_t pid){ STAFMutexSemLock handleLock(fHandleListSem); if (fHandleList.find(handle) == fHandleList.end()) return kSTAFHandleDoesNotExist; HandleData &theHandle = fHandleList[handle]; if ((theHandle.state != kStatic) && (theHandle.pid != pid)) return kSTAFInvalidHandle; theHandle.lastUsedTimestamp = STAFTimestamp::now(); return kSTAFOk;}STAFRC_t STAFHandleManager::addAndGetPendingHandle(STAFHandle_t &handle, STAFProcessID_t pid, STAFProcessHandle_t procHandle, STAFVariablePoolPtr pool){ // Note: This method should only be used by STAFProcessService. It will // obtain a lock on our fHandleListSem before calling this method. // Should anyone else need to call this method, they must also lock // our fHandleListSem before calling this method. HandleData theHandle(fNextHandle++, pid, procHandle, kPending, STAFTimestamp::now(), STAFString(), pool); fHandleList[theHandle.handle] = theHandle; handle = theHandle.handle; return kSTAFOk;}STAFRC_t STAFHandleManager::addAndGetStaticHandle(STAFHandle_t &handle, const STAFString &name){ STAFMutexSemLock handleLock(fHandleListSem); HandleData theHandle(fNextHandle++, 0, 0, kStatic, STAFTimestamp::now(), name); fHandleList[theHandle.handle] = theHandle; handle = theHandle.handle; return kSTAFOk;}STAFRC_t STAFHandleManager::addAndGetStaticHandle(STAFHandle_t &handle, const STAFString &name, STAFVariablePoolPtr pool){ STAFMutexSemLock handleLock(fHandleListSem); HandleData theHandle(fNextHandle++, 0, 0, kStatic, STAFTimestamp::now(), name, pool); fHandleList[theHandle.handle] = theHandle; handle = theHandle.handle; return kSTAFOk;}STAFServiceResult STAFHandleManager::addNotification( STAFHandle_t handle, const STAFString machine, const STAFString uuid, const STAFString service, const STAFString key){ STAFServiceResult serviceResult(kSTAFOk); if (isLocalMachine(machine, 1)) { addNotificationEntry(handle, machine, uuid, service, key); return serviceResult; } else { // Remote machine STAFRC_t rc = kSTAFOk; STAFConnectionPtr connection; STAFString result; rc = gConnectionManagerPtr->makeConnection( machine, connection, result); if (rc) { serviceResult.fRC = rc; serviceResult.fResult = result; return serviceResult; } connection->writeUInt(kSTAFHandleTerminationRegistrationAPI); connection->writeUInt(0); // Dummy level STAFRC_t ack = connection->readUInt(); if (ack != kSTAFOk) { serviceResult.fRC = ack; serviceResult.fResult = "Error connecting " "kSTAFHandleTerminationRegistrationAPI"; return serviceResult; } // min and max levels connection->writeUInt(1); connection->writeUInt(1); connection->writeUInt(handle); connection->writeString(gMachinePtr->toLowerCase()); connection->writeString(uuid); connection->writeString(service); connection->writeString(key); addPollingEntry(handle, machine, uuid, service, key); return serviceResult; }}STAFRC_t STAFHandleManager::addNotificationEntry(STAFHandle_t &handle, const STAFString &machine, const STAFString &uuid, const STAFString &service, const STAFString &key){ STAFMutexSemLock notificationLock(fNotificationListSem); // Make sure the handle/machine/service combination // is not already registered STAFHandleManager::NotificationList::iterator iter; for (iter = fNotificationList.begin(); iter != fNotificationList.end(); iter++) { STAFHandleManager::NotificationData notifiee(*iter); if ((notifiee.handle == handle) && (notifiee.machine == machine) && (notifiee.uuid == uuid) && (notifiee.notifyService == service)) { return kSTAFOk; } } NotificationData theNotification(handle, machine, uuid, key, service); fNotificationList.push_back(theNotification); return kSTAFOk;}STAFRC_t STAFHandleManager::deleteNotification(STAFHandle_t handle, const STAFString machine, const STAFString uuid, const STAFString service){ if (debug) // XXX cout << "Deleting notification for handle " << handle << "\n"; STAFMutexSemLock notificationLock(fNotificationListSem); NotificationList::iterator notificationIter; for(notificationIter = fNotificationList.begin(); (notificationIter != fNotificationList.end()) && (notificationIter->handle != handle) && (notificationIter->machine != machine) && (notificationIter->uuid != uuid); ++notificationIter) { /* Do Nothing */} if (notificationIter != fNotificationList.end() && (notificationIter->handle == handle) && (notificationIter->machine == machine) && (notificationIter->uuid == uuid)) { fNotificationList.erase(notificationIter); } return kSTAFOk;}STAFRC_t STAFHandleManager::addPollingEntry(STAFHandle_t &handle, const STAFString &machine, const STAFString &uuid, const STAFString &service, const STAFString &key){ STAFMutexSemLock pollingLock(fPollingDataListSem); // Make sure the handle/machine/service combination // is not already registered STAFHandleManager::PollingDataList::iterator iter; for (iter = fPollingDataList.begin(); iter != fPollingDataList.end(); iter++) { STAFHandleManager::PollingData notifiee(*iter); if ((notifiee.handle == handle) && (notifiee.machine == machine) && (notifiee.uuid == uuid) && (notifiee.notifyService == service)) { return kSTAFOk; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -