Ejemplo n.º 1
0
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;
}