Search in sources :

Example 1 with ModuleEvent

use of org.eclipse.osgi.container.ModuleContainerAdaptor.ModuleEvent in project rt.equinox.framework by eclipse.

the class Module method lockStateChange.

/**
 * Acquires the module lock for state changes by the current thread for the specified
 * transition event.  Certain transition events locks may be nested within other
 * transition event locks.  For example, a resolved transition event lock may be
 * nested within a started transition event lock.  A stopped transition lock
 * may be nested within an updated, unresolved or uninstalled transition lock.
 * @param transitionEvent the transition event to acquire the lock for.
 * @throws BundleException
 */
protected final void lockStateChange(ModuleEvent transitionEvent) throws BundleException {
    boolean previousInterruption = Thread.interrupted();
    boolean invalid = false;
    try {
        boolean acquired = stateChangeLock.tryLock(revisions.getContainer().getModuleLockTimeout(), TimeUnit.SECONDS);
        Set<ModuleEvent> currentTransition = Collections.emptySet();
        if (acquired) {
            boolean isValidTransition = true;
            switch(transitionEvent) {
                case STARTED:
                case UPDATED:
                case UNINSTALLED:
                case UNRESOLVED:
                    // These states must be initiating transition states
                    // no other transition state is allowed when these are kicked off
                    isValidTransition = stateTransitionEvents.isEmpty();
                    break;
                case RESOLVED:
                    isValidTransition = VALID_RESOLVED_TRANSITION.containsAll(stateTransitionEvents);
                    break;
                case STOPPED:
                    isValidTransition = VALID_STOPPED_TRANSITION.containsAll(stateTransitionEvents);
                    break;
                default:
                    isValidTransition = false;
                    break;
            }
            if (!isValidTransition) {
                currentTransition = EnumSet.copyOf(stateTransitionEvents);
                invalid = true;
                stateChangeLock.unlock();
            } else {
                stateTransitionEvents.add(transitionEvent);
                return;
            }
        } else {
            currentTransition = EnumSet.copyOf(stateTransitionEvents);
        }
        Throwable cause;
        if (invalid) {
            cause = new IllegalStateException(NLS.bind(Msg.Module_LockStateError, transitionEvent, currentTransition));
        } else {
            cause = new TimeoutException(NLS.bind(Msg.Module_LockTimeout, revisions.getContainer().getModuleLockTimeout()));
        }
        String exceptonInfo = toString() + ' ' + transitionEvent + ' ' + currentTransition;
        throw new BundleException(Msg.Module_LockError + exceptonInfo, BundleException.STATECHANGE_ERROR, cause);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        // $NON-NLS-1$
        throw new BundleException(Msg.Module_LockError + toString() + " " + transitionEvent, BundleException.STATECHANGE_ERROR, e);
    } finally {
        if (previousInterruption) {
            Thread.currentThread().interrupt();
        }
    }
}
Also used : ModuleEvent(org.eclipse.osgi.container.ModuleContainerAdaptor.ModuleEvent) TimeoutException(java.util.concurrent.TimeoutException)

Example 2 with ModuleEvent

use of org.eclipse.osgi.container.ModuleContainerAdaptor.ModuleEvent in project rt.equinox.framework by eclipse.

the class TestModuleContainer method removeFirstListOfCommonEvents.

private List<DummyModuleEvent> removeFirstListOfCommonEvents(List<DummyModuleEvent> events) {
    List<DummyModuleEvent> result = new ArrayList<DummyModuleDatabase.DummyModuleEvent>();
    if (events.isEmpty()) {
        return result;
    }
    ModuleEvent commonEvent = events.get(0).event;
    for (Iterator<DummyModuleEvent> iEvents = events.iterator(); iEvents.hasNext(); ) {
        DummyModuleEvent current = iEvents.next();
        if (commonEvent.equals(current.event)) {
            iEvents.remove();
            result.add(current);
        } else {
            break;
        }
    }
    return result;
}
Also used : ArrayList(java.util.ArrayList) DummyModuleEvent(org.eclipse.osgi.tests.container.dummys.DummyModuleDatabase.DummyModuleEvent) ModuleEvent(org.eclipse.osgi.container.ModuleContainerAdaptor.ModuleEvent) DummyModuleEvent(org.eclipse.osgi.tests.container.dummys.DummyModuleDatabase.DummyModuleEvent) DummyModuleDatabase(org.eclipse.osgi.tests.container.dummys.DummyModuleDatabase)

Example 3 with ModuleEvent

use of org.eclipse.osgi.container.ModuleContainerAdaptor.ModuleEvent in project rt.equinox.framework by eclipse.

the class Module method start.

/**
 * Starts this module
 * @param options the options for starting
 * @throws BundleException if an errors occurs while starting
 */
public void start(StartOptions... options) throws BundleException {
    revisions.getContainer().checkAdminPermission(getBundle(), AdminPermission.EXECUTE);
    if (options == null) {
        options = new StartOptions[0];
    }
    ModuleEvent event;
    if (StartOptions.LAZY_TRIGGER.isContained(options)) {
        setTrigger();
        if (stateChangeLock.getHoldCount() > 0 && stateTransitionEvents.contains(ModuleEvent.STARTED)) {
            // nothing to do here; the current thread is activating the bundle.
            return;
        }
    }
    BundleException startError = null;
    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;
        checkValid();
        if (StartOptions.TRANSIENT_IF_AUTO_START.isContained(options) && !settings.contains(Settings.AUTO_START)) {
            // Do nothing; this is a request to start only if the module is set for auto start
            return;
        }
        checkFragment();
        persistStartOptions(options);
        if (getStartLevel() > getRevisions().getContainer().getStartLevel()) {
            if (StartOptions.TRANSIENT.isContained(options)) {
                // it is an error to attempt to transient start a bundle without its start level met
                throw new BundleException(Msg.Module_Transient_StartError, BundleException.START_TRANSIENT_ERROR);
            }
            // Do nothing; start level is not met
            return;
        }
        if (State.ACTIVE.equals(getState()))
            return;
        if (getState().equals(State.INSTALLED)) {
            ResolutionReport report;
            // 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;
            try {
                report = getRevisions().getContainer().resolve(Arrays.asList(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 (State.ACTIVE.equals(getState()))
                return;
            if (getState().equals(State.INSTALLED)) {
                String reportMessage = report.getResolutionReportMessage(getCurrentRevision());
                throw new BundleException(Msg.Module_ResolveError + reportMessage, BundleException.RESOLVE_ERROR);
            }
        }
        try {
            event = doStart(options);
        } catch (BundleException e) {
            // must return state to resolved
            setState(State.RESOLVED);
            startError = e;
            // must always publish the STOPPED event on error
            event = ModuleEvent.STOPPED;
        }
    } finally {
        if (lockedStarted) {
            unlockStateChange(ModuleEvent.STARTED);
        }
        inStart.decrementAndGet();
    }
    if (event != null) {
        if (!EnumSet.of(ModuleEvent.STARTED, ModuleEvent.LAZY_ACTIVATION, ModuleEvent.STOPPED).contains(event))
            // $NON-NLS-1$
            throw new IllegalStateException("Wrong event type: " + event);
        publishEvent(event);
    }
    if (startError != null) {
        throw startError;
    }
}
Also used : ResolutionException(org.osgi.service.resolver.ResolutionException) ModuleEvent(org.eclipse.osgi.container.ModuleContainerAdaptor.ModuleEvent) ResolutionReport(org.eclipse.osgi.report.resolution.ResolutionReport)

Example 4 with ModuleEvent

use of org.eclipse.osgi.container.ModuleContainerAdaptor.ModuleEvent in project rt.equinox.framework by eclipse.

the class Module method stop.

/**
 * Stops this module.
 * @param options options for stopping
 * @throws BundleException if an error occurs while stopping
 */
public void stop(StopOptions... options) throws BundleException {
    revisions.getContainer().checkAdminPermission(getBundle(), AdminPermission.EXECUTE);
    if (options == null)
        options = new StopOptions[0];
    ModuleEvent event;
    BundleException stopError = null;
    lockStateChange(ModuleEvent.STOPPED);
    try {
        checkValid();
        checkFragment();
        persistStopOptions(options);
        if (!Module.ACTIVE_SET.contains(getState()))
            return;
        try {
            event = doStop();
        } catch (BundleException e) {
            stopError = e;
            // must always publish the STOPPED event
            event = ModuleEvent.STOPPED;
        }
    } finally {
        unlockStateChange(ModuleEvent.STOPPED);
    }
    if (event != null) {
        if (!ModuleEvent.STOPPED.equals(event))
            // $NON-NLS-1$
            throw new IllegalStateException("Wrong event type: " + event);
        publishEvent(event);
    }
    if (stopError != null)
        throw stopError;
}
Also used : ModuleEvent(org.eclipse.osgi.container.ModuleContainerAdaptor.ModuleEvent)

Aggregations

ModuleEvent (org.eclipse.osgi.container.ModuleContainerAdaptor.ModuleEvent)4 ArrayList (java.util.ArrayList)1 TimeoutException (java.util.concurrent.TimeoutException)1 ResolutionReport (org.eclipse.osgi.report.resolution.ResolutionReport)1 DummyModuleDatabase (org.eclipse.osgi.tests.container.dummys.DummyModuleDatabase)1 DummyModuleEvent (org.eclipse.osgi.tests.container.dummys.DummyModuleDatabase.DummyModuleEvent)1 ResolutionException (org.osgi.service.resolver.ResolutionException)1