📄 stafrespoolservice.cpp
字号:
STAFResultPtr handleRequest(STAFServiceRequestLevel30 *pInfo, ResPoolServiceData *pData){ STAFString result; STAFRC_t rc = kSTAFOk; // Verify the requester has at least trust level 3 VALIDATE_TRUST(3, pData->fShortName, "REQUEST", pData->fLocalMachineName); // Parse the request STAFCommandParseResultPtr parsedResult = pData->fRequestParser->parse( pInfo->request); if (parsedResult->rc != kSTAFOk) { return STAFResultPtr(new STAFResult(kSTAFInvalidRequestString, parsedResult->errorBuffer), STAFResultPtr::INIT); } // Set the poolName variable (resolve the pool name) STAFResultPtr resultPtr = resolveOp(pInfo, pData, parsedResult, sPool); if (resultPtr->rc != 0) return resultPtr; STAFString poolName = resultPtr->result; // Set the FIRST variable (if first = 0, a random request is performed) unsigned int first = parsedResult->optionTimes(sFirst); // Set the timeout variable (resolve the timeout value and check if numeric) unsigned int timeout = STAF_EVENT_SEM_INDEFINITE_WAIT; if (parsedResult->optionTimes(sTimeout) > 0) { resultPtr = resolveOp(pInfo, pData, parsedResult, sTimeout); if (resultPtr->rc != 0) return resultPtr; if (!resultPtr->result.isDigits()) { return STAFResultPtr(new STAFResult(kSTAFInvalidValue, resultPtr->result), STAFResultPtr::INIT); } timeout = (resultPtr->result).asUInt(); } RequestDataPtr requestDataPtr; PoolMap::iterator poolIterator; PoolDataPtr poolPtr; // Get a read lock on the Pool Map for the duration of this block { STAFRWSemRLock rLock(*pData->fPoolMapRWSem); // Make sure the specified resource pool is in the PoolMap poolIterator = pData->fPoolMap.find(poolName.toUpperCase()); if (poolIterator == pData->fPoolMap.end()) { return STAFResultPtr(new STAFResult(kSTAFDoesNotExist, poolName), STAFResultPtr::INIT); } poolPtr = (*poolIterator).second; // Lock the poolData semaphore for the duration of this block { STAFMutexSemLock lock(*poolPtr->accessSem); if (poolPtr->resourceList.size() == 0) { return STAFResultPtr(new STAFResult( kSTAFResPoolNoEntriesAvailable, poolName), STAFResultPtr::INIT); } if (debug) // XXX cout << "Got a respool request for " << poolName << "\n"; // Register for notification when the handle ends STAFString request = "STAF_NOTIFY REGISTER ONENDOFHANDLE "; request += pInfo->handle; request += " MACHINE "; request += pInfo->machine; request += " UUID "; request += pInfo->stafInstanceUUID; request += " SERVICE "; request += pData->fShortName; request += " KEY "; request += "ResPoolEntry"; STAFResultPtr notifyResult = pData->fHandlePtr->submit("LOCAL", "HANDLE", request); // Check if there are any available resources int availResources = poolPtr->numResources - poolPtr->usedResources; if (availResources > 0) { // Get the index of a random resource int rIndex = rand() % availResources; // Find the first or Nth available resource in the resource list unsigned int i; // Index of the available resource for (i = 0; i < poolPtr->resourceList.size(); i++) { if ((!poolPtr->resourceList[i].owned) && (first || !rIndex--)) break; } // Mark the resource as OWNED and return the entry info poolPtr->usedResources++; poolPtr->resourceList[i].owned = 1; poolPtr->resourceList[i].orgUUID = pInfo->stafInstanceUUID; poolPtr->resourceList[i].orgMachine = pInfo->machine; poolPtr->resourceList[i].orgName = pInfo->handleName; poolPtr->resourceList[i].orgHandle = pInfo->handle; poolPtr->resourceList[i].orgUser = pInfo->user; poolPtr->resourceList[i].orgEndpoint = pInfo->endpoint; STAFString currentTime = STAFTimestamp::now().asString(); poolPtr->resourceList[i].requestedTime = currentTime; poolPtr->resourceList[i].acquiredTime = currentTime; // Return the entry assigned to the request return STAFResultPtr(new STAFResult(kSTAFOk, poolPtr->resourceList[i].entry), STAFResultPtr::INIT); } // Else no resources currently available; put me on the pending list RequestData requestData(pInfo->stafInstanceUUID, pInfo->machine, pInfo->handleName, pInfo->handle, pInfo->user, pInfo->endpoint); requestDataPtr = RequestDataPtr(new RequestData(requestData), RequestDataPtr::INIT); poolPtr->requestList.push_back(requestDataPtr); } // End block for locking the PoolData access semaphore } // End block for putting a read lock on the PoolMap // Wait for the specified time for a resource to become available requestDataPtr->wakeup->wait(timeout); // Check if the handle that submitted this request was garbage // collected while we were waiting for a resource to become // available, and if so, return an error. // Save the cost of getting a semaphore lock by first checking if // the request was garbage collected if (*requestDataPtr->garbageCollectedPtr) { // Lock the poolData semaphore for the duration of this block STAFMutexSemLock lock(*poolPtr->accessSem); if (*requestDataPtr->garbageCollectedPtr) { return STAFResultPtr( new STAFResult( kSTAFRequestCancelled, "The handle that submitted this request no longer exists"), STAFResultPtr::INIT); } } // If request timed out, remove the request from the list. Save the // cost of getting a semaphore lock by first checking if the request // timed out. if (requestDataPtr->retCode == kSTAFTimeout) { // Lock the poolData semaphore for the duration of this block STAFMutexSemLock lock(*poolPtr->accessSem); if (requestDataPtr->retCode == kSTAFTimeout) { poolPtr->requestList.remove(requestDataPtr); } } // Return the return code and result assigned to the request return STAFResultPtr(new STAFResult(requestDataPtr->retCode, requestDataPtr->resultBuffer), STAFResultPtr::INIT);} // Handles resource pool release entry requestsSTAFResultPtr handleRelease(STAFServiceRequestLevel30 *pInfo, ResPoolServiceData *pData){ STAFString result; STAFRC_t rc = kSTAFOk; // Verify the requester has at least trust level 3 VALIDATE_TRUST(3, pData->fShortName, "RELEASE", pData->fLocalMachineName); // Parse the request STAFCommandParseResultPtr parsedResult = pData->fReleaseParser->parse(pInfo->request); if (parsedResult->rc != kSTAFOk) { return STAFResultPtr(new STAFResult(kSTAFInvalidRequestString, parsedResult->errorBuffer), STAFResultPtr::INIT); } // Set the poolName variable (resolve the pool name) STAFResultPtr resultPtr = resolveOp(pInfo, pData, parsedResult, sPool); if (resultPtr->rc != 0) return resultPtr; STAFString poolName = resultPtr->result; // Set the releaseEntry variable (resolve the entry value) resultPtr = resolveOp(pInfo, pData, parsedResult, sEntry); if (resultPtr->rc != 0) return resultPtr; STAFString releaseEntry = resultPtr->result; // Get a read lock on the Pool Map for the duration of this block STAFRWSemRLock rLock(*pData->fPoolMapRWSem); // Make sure that the resource pool is in pData->poolMap PoolMap::iterator poolIterator; PoolDataPtr poolPtr; poolIterator = pData->fPoolMap.find(poolName.toUpperCase()); if (poolIterator == pData->fPoolMap.end()) { return STAFResultPtr(new STAFResult(kSTAFDoesNotExist, poolName), STAFResultPtr::INIT); } poolPtr = (*poolIterator).second; // Lock the poolData semaphore for the duration of this block STAFMutexSemLock lock(*poolPtr->accessSem); // Find the entry in the resource pool int resid = -1; for (unsigned int i = 0; i < poolPtr->resourceList.size(); i++) { if (releaseEntry == poolPtr->resourceList[i].entry) { resid = i; break; } } // If the entry is not in the resource pool, return an error if (resid == -1) { return STAFResultPtr(new STAFResult(kSTAFDoesNotExist, releaseEntry), STAFResultPtr::INIT); } // Check if the entry requested to be released is owned if (poolPtr->resourceList[resid].owned) { // Check if you are the owner unsigned int owner = 0; // 0 means not the owner if ((poolPtr->resourceList[resid].orgUUID == pInfo->stafInstanceUUID) && (poolPtr->resourceList[resid].orgHandle == pInfo->handle)) { owner = 1; // 1 means you are the owner } // If you are not the owner and FORCE is specified, need trust level 4 unsigned int force = parsedResult->optionTimes(sForce); if (!owner && force) { // Verify the requester has at least trust level 4 VALIDATE_TRUST2(4, pData->fShortName, "RELEASE FORCE", pData->fLocalMachineName); } // To release, you must be the owner or FORCE must be specified if (owner || force) { // Mark the resource as available poolPtr->usedResources--; poolPtr->resourceList[resid].owned = 0; // If there are any pending requests for this pool, wake up the // first requester and tell him the resource he can have. if (poolPtr->requestList.size() > 0) { RequestDataPtr requestDataPtr = poolPtr->requestList.front(); // Assign the resource to the request requestDataPtr->retCode = kSTAFOk; requestDataPtr->resultBuffer = poolPtr->resourceList[resid].entry; // Update the resource entry's ownership information poolPtr->resourceList[resid].owned = 1; poolPtr->usedResources++; poolPtr->resourceList[resid].orgUUID = requestDataPtr->orgUUID; poolPtr->resourceList[resid].orgMachine = requestDataPtr->orgMachine; poolPtr->resourceList[resid].orgName = requestDataPtr->orgName; poolPtr->resourceList[resid].orgHandle = requestDataPtr->orgHandle; poolPtr->resourceList[resid].orgUser = requestDataPtr->orgUser; poolPtr->resourceList[resid].orgEndpoint = requestDataPtr->orgEndpoint; poolPtr->resourceList[resid].requestedTime = requestDataPtr->requestedTime; poolPtr->resourceList[resid].acquiredTime = STAFTimestamp::now().asSt
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -