use of org.osgi.service.coordinator.Participant in project felix by apache.
the class CoordinationImpl method fail.
/**
* @see org.osgi.service.coordinator.Coordination#fail(java.lang.Throwable)
*/
public boolean fail(final Throwable reason) {
this.owner.checkPermission(name, CoordinationPermission.PARTICIPATE);
if (reason == null) {
throw new IllegalArgumentException("Reason must not be null");
}
if (startTermination()) {
this.failReason = reason;
final List<Participant> releaseList = new ArrayList<Participant>();
synchronized (this.participants) {
releaseList.addAll(this.participants);
this.participants.clear();
}
// consider failure reason (if not null)
for (int i = releaseList.size() - 1; i >= 0; i--) {
final Participant part = releaseList.get(i);
try {
part.failed(this);
} catch (final Exception e) {
LogWrapper.getLogger().log(LogWrapper.LOG_ERROR, "Participant threw exception during call to fail()", e);
}
// release the participant for other coordinations
owner.releaseParticipant(part);
}
this.owner.unregister(this, false);
state = State.FAILED;
synchronized (this.waitLock) {
this.waitLock.notifyAll();
}
return true;
}
return false;
}
use of org.osgi.service.coordinator.Participant in project aries by apache.
the class StartAction method run.
@Override
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;
// 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 {
// 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 {
// 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;
}
use of org.osgi.service.coordinator.Participant in project felix by apache.
the class CoordinationImpl method end.
/**
* @see org.osgi.service.coordinator.Coordination#end()
*/
public void end() {
this.owner.checkPermission(name, CoordinationPermission.INITIATE);
if (!this.isTerminated() && this.associatedThread != null && Thread.currentThread() != this.associatedThread) {
throw new CoordinationException("Coordination is associated with different thread", this, CoordinationException.WRONG_THREAD);
}
if (startTermination()) {
final CoordinationException nestedFailed = this.owner.endNestedCoordinations(this);
if (nestedFailed != null) {
this.failReason = nestedFailed;
}
boolean partialFailure = false;
this.owner.unregister(this, true);
final List<Participant> releaseList = new ArrayList<Participant>();
synchronized (this.participants) {
releaseList.addAll(this.participants);
this.participants.clear();
}
// consider failure reason (if not null)
for (int i = releaseList.size() - 1; i >= 0; i--) {
final Participant part = releaseList.get(i);
try {
if (this.failReason != null) {
part.failed(this);
} else {
part.ended(this);
}
} catch (final Exception e) {
LogWrapper.getLogger().log(LogWrapper.LOG_ERROR, "Participant threw exception during call to fail()", e);
partialFailure = true;
}
// release the participant for other coordinations
owner.releaseParticipant(part);
}
state = State.TERMINATED;
synchronized (this.waitLock) {
this.waitLock.notifyAll();
}
this.associatedThread = null;
if (this.failReason != null) {
throw new CoordinationException("Nested coordination failed", this, CoordinationException.FAILED, this.failReason);
}
if (partialFailure) {
throw new CoordinationException("One or more participants threw while ending the coordination", this, CoordinationException.PARTIALLY_ENDED);
}
} else if (state == State.FAILED) {
this.owner.unregister(this, true);
state = State.TERMINATED;
throw new CoordinationException("Coordination failed", this, CoordinationException.FAILED, failReason);
} else {
// already terminated
throw new CoordinationException("Coordination " + id + "/" + name + " has already terminated", this, CoordinationException.ALREADY_ENDED);
}
}
use of org.osgi.service.coordinator.Participant in project felix by apache.
the class CoordinatorUtil method addToCoordination.
public static boolean addToCoordination(final Object srv, final UpdateThread thread, final Runnable task) {
final Coordinator coordinator = (Coordinator) srv;
Coordination c = coordinator.peek();
if (c != null) {
Notifier n = null;
for (final Participant p : c.getParticipants()) {
if (p instanceof Notifier) {
n = (Notifier) p;
break;
}
}
if (n == null) {
n = new Notifier(thread);
c.addParticipant(n);
}
n.add(task);
return true;
}
return false;
}
use of org.osgi.service.coordinator.Participant in project aries by apache.
the class StartAction method startSubsystemResource.
private void startSubsystemResource(Resource resource, final Coordination coordination) throws IOException {
final BasicSubsystem subsystem = (BasicSubsystem) resource;
if (!isTargetStartable(instigator, target, subsystem)) {
return;
}
// their autostart setting set to started.
if (Utils.isContent(this.target, subsystem))
subsystem.setAutostart(true);
new StartAction(instigator, target, subsystem, coordination).run();
if (coordination == null)
return;
coordination.addParticipant(new Participant() {
public void ended(Coordination coordination) throws Exception {
// noop
}
public void failed(Coordination coordination) throws Exception {
new StopAction(target, subsystem, !subsystem.isRoot()).run();
}
});
}
Aggregations