use of org.eclipse.osgi.container.ModuleContainerAdaptor.ContainerEvent in project rt.equinox.framework by eclipse.
the class SystemModule method waitForStop.
/**
* Waits until the module container has stopped.
* @param timeout The amount of time to wait.
* @return The container event indicated why the framework stopped
* or if there was a time out waiting for stop.
* @see Framework#waitForStop(long)
* @throws InterruptedException if the thread was interrupted while waiting
*/
public ContainerEvent waitForStop(long timeout) throws InterruptedException {
final boolean waitForever = timeout == 0;
final long start = System.currentTimeMillis();
long timeLeft = timeout;
AtomicReference<ContainerEvent> stopEvent = null;
State currentState = null;
boolean stateLocked = false;
try {
if (timeout == 0) {
stateChangeLock.lockInterruptibly();
stateLocked = true;
} else {
stateLocked = stateChangeLock.tryLock(timeLeft, TimeUnit.MILLISECONDS);
}
if (stateLocked) {
stopEvent = forStop;
currentState = getState();
}
} finally {
if (stateLocked) {
stateChangeLock.unlock();
}
}
if (stopEvent == null || currentState == null) {
// Could not lock system module stateChangeLock; timeout
return ContainerEvent.STOPPED_TIMEOUT;
}
if (!ACTIVE_SET.contains(currentState)) {
// check if a past event is waiting for us
ContainerEvent result = stopEvent.get();
if (result != null) {
return result;
}
// framework must not have even been started yet
return ContainerEvent.STOPPED;
}
synchronized (stopEvent) {
do {
ContainerEvent result = stopEvent.get();
if (result != null) {
return result;
}
timeLeft = waitForever ? 0 : start + timeout - System.currentTimeMillis();
if (waitForever || timeLeft > 0) {
stopEvent.wait(timeLeft);
} else {
return ContainerEvent.STOPPED_TIMEOUT;
}
} while (true);
}
}
use of org.eclipse.osgi.container.ModuleContainerAdaptor.ContainerEvent in project rt.equinox.framework by eclipse.
the class SystemModule method stop.
@Override
public void stop(StopOptions... options) throws BundleException {
ContainerEvent containerEvent = ContainerEvent.STOPPED_TIMEOUT;
// other threads from starting the framework while we are shutting down
try {
if (stateChangeLock.tryLock(10, TimeUnit.SECONDS)) {
try {
try {
// Always transient
super.stop(StopOptions.TRANSIENT);
} catch (BundleException e) {
getRevisions().getContainer().adaptor.publishContainerEvent(ContainerEvent.ERROR, this, e);
// must continue on
}
if (holdsTransitionEventLock(ModuleEvent.UPDATED)) {
containerEvent = ContainerEvent.STOPPED_UPDATE;
} else if (holdsTransitionEventLock(ModuleEvent.UNRESOLVED)) {
containerEvent = ContainerEvent.STOPPED_REFRESH;
} else {
containerEvent = ContainerEvent.STOPPED;
}
getRevisions().getContainer().adaptor.publishContainerEvent(containerEvent, this, null);
getRevisions().getContainer().close();
} finally {
AtomicReference<ContainerEvent> eventReference = forStop;
eventReference.compareAndSet(null, containerEvent);
stateChangeLock.unlock();
synchronized (eventReference) {
eventReference.notifyAll();
}
}
} else {
throw new BundleException(Msg.SystemModule_LockError);
}
} catch (InterruptedException e) {
getRevisions().getContainer().adaptor.publishContainerEvent(ContainerEvent.ERROR, this, e);
throw new BundleException(Msg.Module_LockError + toString(), BundleException.STATECHANGE_ERROR, e);
}
}
use of org.eclipse.osgi.container.ModuleContainerAdaptor.ContainerEvent in project rt.equinox.framework by eclipse.
the class SystemModule method init.
/**
* Initializes the module container
* @throws BundleException if an exeption occurred while initializing
*/
public final void init() throws BundleException {
getRevisions().getContainer().checkAdminPermission(getBundle(), AdminPermission.EXECUTE);
boolean lockedStarted = false;
// Indicate we are in the middle of a start.
// This must be incremented before we acquire the STARTED lock the first time.
inStart.incrementAndGet();
try {
lockStateChange(ModuleEvent.STARTED);
lockedStarted = true;
getContainer().getAdaptor().initBegin();
checkValid();
if (ACTIVE_SET.contains(getState()))
return;
getRevisions().getContainer().open();
if (getState().equals(State.INSTALLED)) {
// must unlock to avoid out of order locks when multiple unresolved
// bundles are started at the same time from different threads
unlockStateChange(ModuleEvent.STARTED);
lockedStarted = false;
ResolutionReport report;
try {
report = getRevisions().getContainer().resolve(Arrays.asList((Module) this), true);
} finally {
lockStateChange(ModuleEvent.STARTED);
lockedStarted = true;
}
// need to check valid again in case someone uninstalled the bundle
checkValid();
ResolutionException e = report.getResolutionException();
if (e != null) {
if (e.getCause() instanceof BundleException) {
throw (BundleException) e.getCause();
}
}
if (ACTIVE_SET.contains(getState()))
return;
if (getState().equals(State.INSTALLED)) {
String reportMessage = report.getResolutionReportMessage(getCurrentRevision());
throw new BundleException(Msg.Module_ResolveError + reportMessage, BundleException.RESOLVE_ERROR);
}
}
setState(State.STARTING);
AtomicReference<ContainerEvent> existingForStop = forStop;
if (existingForStop.get() != null) {
// There was a previous launch, reset the reference forStop
forStop = new AtomicReference<>();
}
publishEvent(ModuleEvent.STARTING);
try {
initWorker();
} catch (Throwable t) {
setState(State.STOPPING);
publishEvent(ModuleEvent.STOPPING);
setState(State.RESOLVED);
publishEvent(ModuleEvent.STOPPED);
getRevisions().getContainer().close();
if (t instanceof BundleException) {
throw (BundleException) t;
}
// $NON-NLS-1$
throw new BundleException("Error initializing container.", BundleException.ACTIVATOR_ERROR, t);
}
} finally {
getContainer().getAdaptor().initEnd();
if (lockedStarted) {
unlockStateChange(ModuleEvent.STARTED);
}
inStart.decrementAndGet();
}
}
Aggregations