diff options
author | Thomas Watson | 2016-06-02 19:29:32 +0000 |
---|---|---|
committer | Thomas Watson | 2017-06-16 12:38:08 +0000 |
commit | 0965ee422528b80cd11bb690f7d94559c54c0d16 (patch) | |
tree | 19240cb97a60192fb768f3254e418f52a98963ac /bundles/org.eclipse.osgi/container/src/org/eclipse | |
parent | 943977005bfc2a3c04daca26822418310029133f (diff) | |
download | rt.equinox.framework-0965ee422528b80cd11bb690f7d94559c54c0d16.tar.gz rt.equinox.framework-0965ee422528b80cd11bb690f7d94559c54c0d16.tar.xz rt.equinox.framework-0965ee422528b80cd11bb690f7d94559c54c0d16.zip |
Bug 492825 - [osgi R7] Resolver specification updates for version 1.1
Add onCancel support
Change-Id: I0e46d80bb47a044fa9d1087515b550fc2cf0773b
Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
Diffstat (limited to 'bundles/org.eclipse.osgi/container/src/org/eclipse')
3 files changed, 45 insertions, 22 deletions
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainerAdaptor.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainerAdaptor.java index 31cce058c..117473a79 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainerAdaptor.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainerAdaptor.java @@ -13,6 +13,7 @@ package org.eclipse.osgi.container; import java.io.DataInputStream; import java.util.EnumSet; import java.util.concurrent.Executor; +import java.util.concurrent.ScheduledExecutorService; import org.eclipse.osgi.container.Module.Settings; import org.eclipse.osgi.service.debug.DebugOptions; import org.osgi.framework.Constants; @@ -317,4 +318,14 @@ public abstract class ModuleContainerAdaptor { // do nothing by default return null; } + + /** + * Returns the scheduled executor that may be used by the + * container to schedule background tasks. + * @return the scheduled executor, or null if background tasks are not supported + * @since 3.13 + */ + public ScheduledExecutorService getScheduledExecutor() { + return null; + } } diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java index d58c142e6..9d0b7872f 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java @@ -12,8 +12,8 @@ package org.eclipse.osgi.container; import java.security.Permission; import java.util.*; -import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicBoolean; import org.apache.felix.resolver.*; import org.eclipse.osgi.container.ModuleRequirement.DynamicModuleRequirement; import org.eclipse.osgi.container.namespaces.EquinoxFragmentNamespace; @@ -472,11 +472,6 @@ final class ModuleResolver { return version instanceof Version ? (Version) version : Version.emptyVersion; } - static class ResolutionTimeout extends RuntimeException { - private static final long serialVersionUID = 1L; - // Just a marker exception to break out of extra long resolution - } - class ResolveProcess extends ResolveContext implements Comparator<Capability>, FelixResolveContext, Executor { class ResolveLogger extends Logger { @@ -512,7 +507,6 @@ final class ModuleResolver { @Override public boolean isDebugEnabled() { - checkTimeout(); return DEBUG_USES; } @@ -553,8 +547,7 @@ final class ModuleResolver { private volatile boolean currentlyResolvingMandatory = false; private final Set<Resource> transitivelyResolveFailures = new LinkedHashSet<>(); private final Set<Resource> failedToResolve = new HashSet<>(); - private final long resolveTimeout = System.currentTimeMillis() + resolverBatchTimeout; - private volatile boolean checkTimeout = true; + private AtomicBoolean scheduleTimeout = new AtomicBoolean(true); /* * Used to generate the UNRESOLVED_PROVIDER resolution report entries. * @@ -849,12 +842,13 @@ final class ModuleResolver { @Override public Collection<Resource> findRelatedResources(Resource host) { + // for the container we only care about fragments for related resources List<ModuleCapability> hostCaps = ((ModuleRevision) host).getModuleCapabilities(HostNamespace.HOST_NAMESPACE); if (hostCaps.isEmpty()) { return Collections.emptyList(); } - Collection<Resource> ondemandFragments = new ArrayList<>(); + Collection<Resource> relatedFragments = new ArrayList<>(); for (String hostBSN : getHostBSNs(hostCaps)) { String matchFilter = "(" + EquinoxFragmentNamespace.FRAGMENT_NAMESPACE + "=" + hostBSN + ")"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ Requirement fragmentRequirement = ModuleContainer.createRequirement(EquinoxFragmentNamespace.FRAGMENT_NAMESPACE, Collections.<String, String> singletonMap(Namespace.REQUIREMENT_FILTER_DIRECTIVE, matchFilter), Collections.<String, Object> emptyMap()); @@ -866,14 +860,14 @@ final class ModuleResolver { ModuleRequirement hostReq = candidate.getRevision().getModuleRequirements(HostNamespace.HOST_NAMESPACE).get(0); for (ModuleCapability hostCap : hostCaps) { if (hostReq.matches(hostCap)) { - ondemandFragments.add(candidate.getResource()); + relatedFragments.add(candidate.getResource()); break; } } } } - return ondemandFragments; + return relatedFragments; } private Collection<String> getHostBSNs(List<ModuleCapability> hostCaps) { @@ -1037,9 +1031,13 @@ final class ModuleResolver { } maxUsedMemory = Math.max(maxUsedMemory, Runtime.getRuntime().freeMemory() - initialFreeMemory); } - } catch (ResolutionTimeout timeoutException) { + } catch (ResolutionException resolutionException) { + if (resolutionException.getCause() instanceof CancellationException) { // revert back to single bundle resolves resolveRevisionsIndividually(isMandatory, logger, result, toResolve, revisions); + } else { + throw resolutionException; + } } catch (OutOfMemoryError memoryError) { // revert back to single bundle resolves resolveRevisionsIndividually(isMandatory, logger, result, toResolve, revisions); @@ -1053,7 +1051,7 @@ final class ModuleResolver { } private void resolveRevisionsIndividually(boolean isMandatory, ResolveLogger logger, Map<Resource, List<Wire>> result, Collection<Resource> toResolve, Collection<ModuleRevision> revisions) throws ResolutionException { - checkTimeout = false; + scheduleTimeout.set(false); for (Resource resource : toResolve) { if (!wirings.containsKey(resource) && !failedToResolve.contains(resource)) { resolveRevisions(Collections.singletonList(resource), isMandatory, logger, result); @@ -1091,9 +1089,11 @@ final class ModuleResolver { result.put(interimResultEntry.getKey(), interimResultEntry.getValue()); } } - } catch (ResolutionTimeout timeoutException) { + } catch (ResolutionException resolutionException) { + if (resolutionException.getCause() instanceof CancellationException) { applyTransitiveFailures = false; - throw timeoutException; + } + throw resolutionException; } catch (OutOfMemoryError memoryError) { applyTransitiveFailures = false; throw memoryError; @@ -1588,14 +1588,21 @@ final class ModuleResolver { @Override public void execute(Runnable command) { - checkTimeout(); adaptor.getResolverExecutor().execute(command); } - void checkTimeout() { - if (checkTimeout && resolveTimeout < System.currentTimeMillis()) { - checkTimeout = false; - throw new ResolutionTimeout(); + @Override + public void onCancel(Runnable callback) { + // Note that for each resolve Process we only want timeout the initial batch resolve + if (scheduleTimeout.compareAndSet(true, false)) { + ScheduledExecutorService scheduledExecutor = adaptor.getScheduledExecutor(); + if (scheduledExecutor != null) { + try { + scheduledExecutor.schedule(callback, resolverBatchTimeout, TimeUnit.MILLISECONDS); + } catch (RejectedExecutionException e) { + // ignore may have been shutdown, it is ok we will not be able to timeout + } + } } } diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainerAdaptor.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainerAdaptor.java index f02e02d30..4c3e6539a 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainerAdaptor.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainerAdaptor.java @@ -339,6 +339,11 @@ public class EquinoxContainerAdaptor extends ModuleContainerAdaptor { return executor.getInitialized(lazyExecutorCreator); } + @Override + public ScheduledExecutorService getScheduledExecutor() { + return container.getScheduledExecutor(); + } + public void shutdownResolverExecutor() { Executor current = executor.getAndClear(); if (current instanceof ExecutorService) { |