void TeamDebugger::ValueNodeValueRequested(CpuState* cpuState, ValueNodeContainer* container, ValueNode* valueNode) { AutoLocker<ValueNodeContainer> containerLocker(container); if (valueNode->Container() != container) return; // check whether a job is already in progress AutoLocker<Worker> workerLocker(fWorker); SimpleJobKey jobKey(valueNode, JOB_TYPE_RESOLVE_VALUE_NODE_VALUE); if (fWorker->GetJob(jobKey) != NULL) return; workerLocker.Unlock(); // schedule the job status_t error = fWorker->ScheduleJob( new(std::nothrow) ResolveValueNodeValueJob(fDebuggerInterface, fDebuggerInterface->GetArchitecture(), cpuState, fTeam->GetTeamTypeInformation(), container, valueNode), this); if (error != B_OK) { // scheduling failed -- set the value to invalid valueNode->SetLocationAndValue(NULL, NULL, error); } }
status_t ResolveValueNodeValueJob::_ResolveParentNodeValue(ValueNode* parentNode) { AutoLocker<ValueNodeContainer> containerLocker(fContainer); if (parentNode->Container() != fContainer) return B_BAD_VALUE; // if the parent node already has a value, we're done status_t nodeResolutionState = parentNode->LocationAndValueResolutionState(); if (nodeResolutionState != VALUE_NODE_UNRESOLVED) return nodeResolutionState; // check whether a job is already in progress AutoLocker<Worker> workerLocker(GetWorker()); SimpleJobKey jobKey(parentNode, JOB_TYPE_RESOLVE_VALUE_NODE_VALUE); if (GetWorker()->GetJob(jobKey) == NULL) { workerLocker.Unlock(); // schedule the job status_t error = GetWorker()->ScheduleJob( new(std::nothrow) ResolveValueNodeValueJob(fDebuggerInterface, fArchitecture, fCpuState, fTypeInformation, fContainer, parentNode)); if (error != B_OK) { // scheduling failed -- set the value to invalid parentNode->SetLocationAndValue(NULL, NULL, error); return error; } } // wait for the job to finish workerLocker.Unlock(); containerLocker.Unlock(); switch (WaitFor(jobKey)) { case JOB_DEPENDENCY_SUCCEEDED: case JOB_DEPENDENCY_NOT_FOUND: // "Not found" can happen due to a race condition between // unlocking the worker and starting to wait. break; case JOB_DEPENDENCY_ACTIVE: return B_OK; case JOB_DEPENDENCY_FAILED: case JOB_DEPENDENCY_ABORTED: default: return B_ERROR; } containerLocker.Lock(); // now there should be a value for the node nodeResolutionState = parentNode->LocationAndValueResolutionState(); return nodeResolutionState != VALUE_NODE_UNRESOLVED ? nodeResolutionState : B_ERROR; }