public Object run()

in subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StartAction.java [198:353]


	public Object run() {
		// Protect against re-entry now that cycles are supported.
		if (!Activator.getInstance().getLockingStrategy().set(State.STARTING, target)) {
			return null;
		}
		try {
			AffectedResources affectedResources;
			// We are now protected against re-entry.
			// If necessary, install the dependencies.
	    	if (State.INSTALLING.equals(target.getState()) && !Utils.isProvisionDependenciesInstall(target)) {
	    		// Acquire the global write lock while installing dependencies.
				Activator.getInstance().getLockingStrategy().writeLock();
				try {
					// We are now protected against installs, starts, stops, and uninstalls.
		    		// We need a separate coordination when installing 
					// dependencies because cleaning up the temporary export 
					// sharing policies must be done while holding the write lock.
		    		Coordination c = Utils.createCoordination(target);
		    		try {
		    			installDependencies(target, c);
		    			// Associated subsystems must be computed after all dependencies 
						// are installed because some of the dependencies may be 
						// subsystems. This is safe to do while only holding the read
						// lock since we know that nothing can be added or removed.
		    			affectedResources = computeAffectedResources(target);
						for (BasicSubsystem subsystem : affectedResources.subsystems()) {
							if (State.INSTALLING.equals(subsystem.getState())
									&& !Utils.isProvisionDependenciesInstall(subsystem)) {
								installDependencies(subsystem, c);
							}
						}
						// Downgrade to the read lock in order to prevent 
		    			// installs and uninstalls but allow starts and stops.
						Activator.getInstance().getLockingStrategy().readLock();
		    		}
		    		catch (Throwable t) {
		    			c.fail(t);
		    		}
		    		finally {
		    			// This will clean up the temporary export sharing
		    			// policies. Must be done while holding the write lock.
		    			c.end();
		    		}
				}
				finally {
					// Release the global write lock as soon as possible.
					Activator.getInstance().getLockingStrategy().writeUnlock();
				}
	    	}
	    	else {
	    		// Acquire the read lock in order to prevent installs and
	    		// uninstalls but allow starts and stops.
	    		Activator.getInstance().getLockingStrategy().readLock();
	    	}
	    	try {
	    		// We now hold the read lock and are protected against installs
	    		// and uninstalls.
	    		if (Restriction.INSTALL_ONLY.equals(restriction)) {
					return null;
				}
	    		// Compute associated subsystems here in case (1) they weren't
	    		// computed previously while holding the write lock or (2) they
	    		// were computed previously and more were subsequently added. 
				// This is safe to do while only holding the read lock since we
				// know that nothing can be added or removed.
	    		affectedResources = computeAffectedResources(target);
				// 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(affectedResources.subsystems());
				}
				finally {
					// Release the global mutual exclusion lock as soon as possible.
					Activator.getInstance().getLockingStrategy().unlock();
				}
				Coordination coordination = this.coordination;
				try {
					coordination = createCoordination();
					// We are now protected against other starts and stops of the affected subsystems.
					if (!isTargetStartable(instigator, requestor, target)) {
						return null;
					}
					
					// Resolve if necessary.
					if (State.INSTALLED.equals(target.getState()))
						resolve(instigator, target, target, coordination, affectedResources.subsystems());
					if (Restriction.RESOLVE_ONLY.equals(restriction))
						return null;
					target.setState(State.STARTING);
					// Be sure to set the state back to RESOLVED if starting fails.
					coordination.addParticipant(new Participant() {
						@Override
						public void ended(Coordination coordination) throws Exception {
							// Nothing.
						}

						@Override
						public void failed(Coordination coordination) throws Exception {
							target.setState(State.RESOLVED);
						}
					});
					SubsystemContentHeader header = target.getSubsystemManifest().getSubsystemContentHeader();
					if (header != null)
						Collections.sort(affectedResources.resources(), new StartResourceComparator(header));
					for (Resource resource : affectedResources.resources())
						startResource(resource, coordination);
					target.setState(State.ACTIVE);
					
				}
				catch (Throwable t) {
					// We catch exceptions and fail the coordination here to
					// ensure we are still holding the state change locks when
					// the participant sets the state to RESOLVED.
					coordination.fail(t);
				}
				finally {
					try {
						// Don't end a coordination that was not begun as part
						// of this start action.
						if (coordination.getName().equals(Utils.computeCoordinationName(target))) {
							coordination.end();
						}
					}
					finally {
						// Release the state change locks of affected subsystems.
						Activator.getInstance().getLockingStrategy().unlock(affectedResources.subsystems());
					}
				}
	    	}
	    	finally {
				// Release the read lock.
				Activator.getInstance().getLockingStrategy().readUnlock();
			}
		}
		catch (CoordinationException e) {
			Throwable t = e.getCause();
			if (t == null) {
				throw new SubsystemException(e);
			}
			if (t instanceof SecurityException) {
				throw (SecurityException)t;
			}
			if (t instanceof SubsystemException) {
				throw (SubsystemException)t;
			}
			throw new SubsystemException(t);
		}
		finally {
			// Protection against re-entry no longer required.
			Activator.getInstance().getLockingStrategy().unset(State.STARTING, target);
		}
		return null;
	}