if (previousException != null) {
throw previousException;
}
if (hardCancelledDescriptors.contains(activeDescriptor)) {
throw new MultiException(new WasCancelledException(activeDescriptor));
}
while (creatingDescriptors.containsKey(activeDescriptor)) {
long holdingLock = creatingDescriptors.get(activeDescriptor);
if (holdingLock == Thread.currentThread().getId()) {
throw new MultiException(new IllegalStateException(
"Circular dependency involving " + activeDescriptor.getImplementation() +
" was found. Full descriptor is " + activeDescriptor));
}
if (throwWouldBlock) {
throw new MultiException(new WouldBlockException(activeDescriptor));
}
try {
this.wait();
}
catch (InterruptedException ie) {
throw new MultiException(ie);
}
}
retVal = (U) backingMap.get(activeDescriptor);
if (retVal != null) return retVal;
previousException = levelErrorMap.get(activeDescriptor);
if (previousException != null) {
throw previousException;
}
if (hardCancelledDescriptors.contains(activeDescriptor)) {
throw new MultiException(new WasCancelledException(activeDescriptor));
}
creatingDescriptors.put(activeDescriptor, Thread.currentThread().getId());
localCurrentLevel = currentLevel;
if (currentTask != null && currentTask.isUp()) {
localCurrentLevel++;
if (localCurrentLevel > currentTask.getProposedLevel()) {
localCurrentLevel = currentTask.getProposedLevel();
}
}
}
RuntimeException error = null;
try {
int mode = Utilities.getRunLevelMode(activeDescriptor);
if (mode == RunLevel.RUNLEVEL_MODE_VALIDATING) {
validate(activeDescriptor, localCurrentLevel);
}
retVal = activeDescriptor.create(root);
return retVal;
}
catch (RuntimeException th) {
if (th instanceof MultiException) {
if (!CurrentTaskFuture.isWouldBlock((MultiException) th)) {
error = th;
}
// We want WouldBlock rethrown
}
else {
error = th;
}
throw th;
}
finally {
synchronized (this) {
boolean hardCancelled = hardCancelledDescriptors.remove(activeDescriptor);
if (retVal != null) {
if (!hardCancelled) {
backingMap.put(activeDescriptor, retVal);
orderedCreationList.addFirst(activeDescriptor);
}
if (wasCancelled || hardCancelled) {
// Even though this service actually ran to completion, we
// are going to pretend it failed. Putting it in the lists
// above will ensure it gets properly shutdown
MultiException cancelledException = new MultiException(new WasCancelledException(activeDescriptor));
if (!hardCancelled) {
levelErrorMap.put(activeDescriptor, cancelledException);
}