Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMengxin Zhu2012-02-27 03:47:36 -0500
committerMengxin Zhu2012-03-01 02:11:36 -0500
commita927f26f8308300acb803be667733da7795c3fe1 (patch)
treebb563d2860ad1692d067315fea9bdaa7dc57e0db /bundles/org.eclipse.equinox.p2.engine/src
parentdac2766583d7f0d27dd1c8692af7c9346cbac92c (diff)
downloadrt.equinox.p2-a927f26f8308300acb803be667733da7795c3fe1.tar.gz
rt.equinox.p2-a927f26f8308300acb803be667733da7795c3fe1.tar.xz
rt.equinox.p2-a927f26f8308300acb803be667733da7795c3fe1.zip
Bug 358842 pausing/resuming a p2 operation.v20120301-1523v20120301-0711
Introduce new test cases that will download artifacts from Internet, so add vm arguments to make downloading more stable. Signed-off-by: Mengxin Zhu <kane.zhu@windriver.com>
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.engine/src')
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/Messages.java2
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/Phase.java15
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/PhaseSet.java28
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/messages.properties1
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/Collect.java42
5 files changed, 84 insertions, 4 deletions
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/Messages.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/Messages.java
index 9c9710c4a..0b8d79429 100644
--- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/Messages.java
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/Messages.java
@@ -70,6 +70,8 @@ public class Messages extends NLS {
public static String Phase_Install_Task;
public static String Phase_Sizing_Error;
public static String Phase_Sizing_Warning;
+
+ public static String phase_thread_interrupted_error;
public static String Phase_Unconfigure_Error;
public static String Phase_Uninstall_Error;
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/Phase.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/Phase.java
index f57a4829a..bcf912978 100644
--- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/Phase.java
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/Phase.java
@@ -44,6 +44,7 @@ public abstract class Phase {
private Map<Touchpoint, Map<String, Object>> touchpointToTouchpointPhaseParameters = new HashMap<Touchpoint, Map<String, Object>>();
private Map<Touchpoint, Map<String, Object>> touchpointToTouchpointOperandParameters = new HashMap<Touchpoint, Map<String, Object>>();
ActionManager actionManager; // injected from phaseset
+ protected boolean isPaused = false;
protected Phase(String phaseId, int weight, boolean forced) {
if (phaseId == null || phaseId.length() == 0)
@@ -121,6 +122,16 @@ public abstract class Phase {
subMonitor.setWorkRemaining(operands.length - i);
if (subMonitor.isCanceled())
throw new OperationCanceledException();
+ while (isPaused) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ mergeStatus(status, new Status(IStatus.ERROR, EngineActivator.ID, NLS.bind(Messages.phase_thread_interrupted_error, phaseId), e));
+ return;
+ }
+ if (subMonitor.isCanceled())
+ throw new OperationCanceledException();
+ }
Operand operand = operands[i];
if (!isApplicable(operand))
continue;
@@ -336,4 +347,8 @@ public abstract class Phase {
protected String getProblemMessage() {
return NLS.bind(Messages.phase_error, getClass().getName());
}
+
+ protected void setPaused(boolean isPaused) {
+ this.isPaused = isPaused;
+ }
}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/PhaseSet.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/PhaseSet.java
index d4d1c6cf3..6e03edabf 100644
--- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/PhaseSet.java
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/PhaseSet.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2010 IBM Corporation and others.
+ * Copyright (c) 2007, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -19,6 +19,8 @@ import org.eclipse.osgi.util.NLS;
public class PhaseSet implements IPhaseSet {
private final Phase[] phases;
+ private boolean isRunning = false;
+ private boolean isPaused = false;
public PhaseSet(Phase[] phases) {
if (phases == null)
@@ -33,6 +35,7 @@ public class PhaseSet implements IPhaseSet {
int totalWork = getTotalWork(weights);
SubMonitor pm = SubMonitor.convert(monitor, totalWork);
try {
+ isRunning = true;
for (int i = 0; i < phases.length; i++) {
if (pm.isCanceled()) {
status.add(Status.CANCEL_STATUS);
@@ -68,10 +71,33 @@ public class PhaseSet implements IPhaseSet {
}
} finally {
pm.done();
+ isRunning = false;
}
return status;
}
+ public synchronized boolean pause() {
+ if (isRunning && !isPaused) {
+ isPaused = true;
+ for (Phase phase : phases) {
+ phase.setPaused(isPaused);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public synchronized boolean resume() {
+ if (isRunning && isPaused) {
+ isPaused = false;
+ for (Phase phase : phases) {
+ phase.setPaused(isPaused);
+ }
+ return true;
+ }
+ return false;
+ }
+
public final IStatus validate(ActionManager actionManager, IProfile profile, Operand[] operands, ProvisioningContext context, IProgressMonitor monitor) {
Set<MissingAction> missingActions = new HashSet<MissingAction>();
for (int i = 0; i < phases.length; i++) {
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/messages.properties b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/messages.properties
index 597ef540d..f5af6f295 100644
--- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/messages.properties
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/messages.properties
@@ -105,5 +105,6 @@ Phase_Install_Error=An error occurred while installing the items
Phase_Install_Task=Installing {0}
Phase_Sizing_Error=Error computing the size. Some of the items to be installed could not be found.
Phase_Sizing_Warning=The size may not be accurate. Some of the items did not report a size.
+phase_thread_interrupted_error=Phase({0}) is interrupted.
Phase_Unconfigure_Error=An error occurred while unconfiguring the items to uninstall
Phase_Uninstall_Error=An error occurred while uninstalling
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/Collect.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/Collect.java
index df2435eda..640bf0807 100644
--- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/Collect.java
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/Collect.java
@@ -12,9 +12,9 @@
package org.eclipse.equinox.internal.p2.engine.phases;
import java.util.*;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.engine.*;
+import org.eclipse.equinox.internal.p2.repository.DownloadPauseResumeEvent;
import org.eclipse.equinox.internal.provisional.p2.core.eventbus.IProvisioningEventBus;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.engine.*;
@@ -22,6 +22,7 @@ import org.eclipse.equinox.p2.engine.spi.ProvisioningAction;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.ITouchpointType;
import org.eclipse.equinox.p2.repository.artifact.IArtifactRequest;
+import org.eclipse.osgi.util.NLS;
/**
* The goal of the collect phase is to ask the touchpoints if the artifacts associated with an IU need to be downloaded.
@@ -29,6 +30,7 @@ import org.eclipse.equinox.p2.repository.artifact.IArtifactRequest;
public class Collect extends InstallableUnitPhase {
public static final String PARM_ARTIFACT_REQUESTS = "artifactRequests"; //$NON-NLS-1$
public static final String NO_ARTIFACT_REPOSITORIES_AVAILABLE = "noArtifactRepositoriesAvailable"; //$NON-NLS-1$
+ private IProvisioningAgent agent = null;
public Collect(int weight) {
super(PhaseSetFactory.PHASE_COLLECT, weight);
@@ -67,8 +69,23 @@ public class Collect extends InstallableUnitPhase {
protected IStatus completePhase(IProgressMonitor monitor, IProfile profile, Map<String, Object> parameters) {
@SuppressWarnings("unchecked")
List<IArtifactRequest[]> artifactRequests = (List<IArtifactRequest[]>) parameters.get(PARM_ARTIFACT_REQUESTS);
+ // it happens when rollbacking
+ if (artifactRequests.size() == 0)
+ return Status.OK_STATUS;
ProvisioningContext context = (ProvisioningContext) parameters.get(PARM_CONTEXT);
- IProvisioningAgent agent = (IProvisioningAgent) parameters.get(PARM_AGENT);
+ synchronized (this) {
+ agent = (IProvisioningAgent) parameters.get(PARM_AGENT);
+ }
+
+ if (isPaused) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ return new Status(IStatus.ERROR, EngineActivator.ID, NLS.bind(Messages.phase_thread_interrupted_error, phaseId), e);
+ }
+ if (monitor.isCanceled())
+ return Status.CANCEL_STATUS;
+ }
List<IArtifactRequest> totalArtifactRequests = new ArrayList<IArtifactRequest>(artifactRequests.size());
DownloadManager dm = new DownloadManager(context, agent);
@@ -87,6 +104,9 @@ public class Collect extends InstallableUnitPhase {
} finally {
if (downloadStatus.isOK() && bus != null)
bus.publishEvent(new CollectEvent(CollectEvent.TYPE_OVERALL_END, null, context, totalArtifactRequests.toArray(new IArtifactRequest[totalArtifactRequests.size()])));
+ synchronized (this) {
+ agent = null;
+ }
}
}
@@ -95,6 +115,22 @@ public class Collect extends InstallableUnitPhase {
return null;
}
+ @Override
+ protected void setPaused(boolean isPaused) {
+ super.setPaused(isPaused);
+ firePauseEventToDownloadJobs();
+ }
+
+ private void firePauseEventToDownloadJobs() {
+ synchronized (this) {
+ if (agent != null) {
+ IProvisioningEventBus bus = (IProvisioningEventBus) agent.getService(IProvisioningEventBus.SERVICE_NAME);
+ if (bus != null)
+ bus.publishEvent(new DownloadPauseResumeEvent(isPaused ? DownloadPauseResumeEvent.TYPE_PAUSE : DownloadPauseResumeEvent.TYPE_RESUME));
+ }
+ }
+ }
+
protected IStatus initializeOperand(IProfile profile, InstallableUnitOperand operand, Map<String, Object> parameters, IProgressMonitor monitor) {
IStatus status = super.initializeOperand(profile, operand, parameters, monitor);
// defer setting the IU until after the super method to avoid triggering touchpoint initialization

Back to the top