in subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StopAction.java [45:144]
public Object run() {
// Protect against re-entry now that cycles are supported.
if (!Activator.getInstance().getLockingStrategy().set(State.STOPPING, target)) {
return null;
}
try {
// We are now protected against re-entry.
// Acquire the global read lock to prevent installs and uninstalls
// but allow starts and stops.
Activator.getInstance().getLockingStrategy().readLock();
try {
// We are now protected against installs and uninstalls.
checkRoot();
// Compute affected subsystems. This is safe to do while only
// holding the read lock since we know that nothing can be added
// or removed.
LinkedHashSet<BasicSubsystem> subsystems = new LinkedHashSet<BasicSubsystem>();
subsystems.add(target);
List<Resource> resources = new ArrayList<Resource>(Activator.getInstance().getSubsystems().getResourcesReferencedBy(target));
for (Resource resource : resources) {
if (resource instanceof BasicSubsystem) {
subsystems.add((BasicSubsystem)resource);
}
}
// Acquire the global mutual exclusion lock while acquiring the
// state change locks of affected subsystems.
Activator.getInstance().getLockingStrategy().lock();
try {
// We are now protected against cycles.
// Acquire the state change locks of affected subsystems.
Activator.getInstance().getLockingStrategy().lock(subsystems);
}
finally {
// Release the global mutual exclusion lock as soon as possible.
Activator.getInstance().getLockingStrategy().unlock();
}
try {
// We are now protected against other starts and stops of the affected subsystems.
State state = target.getState();
if (EnumSet.of(State.INSTALLED, State.INSTALLING, State.RESOLVED).contains(state)) {
// INSTALLING is included because a subsystem may
// persist in this state without being locked when
// apache-aries-provision-dependencies:=resolve.
return null;
}
else if (EnumSet.of(State.INSTALL_FAILED, State.UNINSTALLED).contains(state)) {
throw new IllegalStateException("Cannot stop from state " + state);
}
target.setState(State.STOPPING);
SubsystemContentHeader header = target.getSubsystemManifest().getSubsystemContentHeader();
if (header != null) {
Collections.sort(resources, new StartResourceComparator(target.getSubsystemManifest().getSubsystemContentHeader()));
Collections.reverse(resources);
}
for (Resource resource : resources) {
// Don't stop the region context bundle.
if (Utils.isRegionContextBundle(resource))
continue;
try {
stopResource(resource);
}
catch (Exception e) {
logger.error("An error occurred while stopping resource " + resource + " of subsystem " + target, e);
}
}
// TODO Can we automatically assume it actually is resolved?
target.setState(State.RESOLVED);
try {
synchronized (target) {
target.setDeploymentManifest(new DeploymentManifest(
target.getDeploymentManifest(),
null,
target.isAutostart(),
target.getSubsystemId(),
SubsystemIdentifier.getLastId(),
target.getLocation(),
false,
false));
}
}
catch (Exception e) {
throw new SubsystemException(e);
}
}
finally {
// Release the state change locks of affected subsystems.
Activator.getInstance().getLockingStrategy().unlock(subsystems);
}
}
finally {
// Release the read lock.
Activator.getInstance().getLockingStrategy().readUnlock();
}
}
finally {
// Protection against re-entry no longer required.
Activator.getInstance().getLockingStrategy().unset(State.STOPPING, target);
}
return null;
}