Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Leherbauer2015-11-27 15:15:57 +0000
committerAnton Leherbauer2015-11-27 15:16:09 +0000
commitdabedd5fad7a418027b532c64a984b96f9efd4b5 (patch)
tree751e863d18f6f7257411cac97dcf6af95cc206d3
parenta0ac2a8323dfcc06cea1733d0a2bf23b55b9cdb7 (diff)
downloadorg.eclipse.tcf-dabedd5fad7a418027b532c64a984b96f9efd4b5.tar.gz
org.eclipse.tcf-dabedd5fad7a418027b532c64a984b96f9efd4b5.tar.xz
org.eclipse.tcf-dabedd5fad7a418027b532c64a984b96f9efd4b5.zip
Target Explorer: Fix race conditions starting multiple processes in a row
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/channelmanager/ChannelManager.java16
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessLauncher.java50
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessProcessesListener.java10
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessStreamsListener.java3
4 files changed, 46 insertions, 33 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/channelmanager/ChannelManager.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/channelmanager/ChannelManager.java
index 93254084d..75ca2e63c 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/channelmanager/ChannelManager.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/channelmanager/ChannelManager.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014 Wind River Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2014, 2015 Wind River Systems, Inc. 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 http://www.eclipse.org/legal/epl-v10.html
@@ -780,8 +780,6 @@ public class ChannelManager extends PlatformObject implements IChannelManager {
finProxy.removeListener(listener);
if (finProxy.isEmpty()) finProxies.remove(finProxy);
if (finProxies.isEmpty()) streamProxies.remove(channel);
- } else {
- finProxy.addListener(listener);
}
done.doneSubscribeStream(error);
}
@@ -829,25 +827,27 @@ public class ChannelManager extends PlatformObject implements IChannelManager {
proxy.removeListener(listener);
// Are there remaining proxied listeners for this stream type?
if (proxy.isEmpty()) {
+ // Remove from proxy list
+ proxies.remove(proxy);
+ if (proxies.isEmpty()) streamProxies.remove(channel);
// Unregister the stream type
IStreams service = channel.getRemoteService(IStreams.class);
if (service != null) {
- final StreamListenerProxy finProxy = proxy;
- final List<StreamListenerProxy> finProxies = proxies;
-
// Unsubscribe
service.unsubscribe(streamType, proxy, new IStreams.DoneUnsubscribe() {
@Override
public void doneUnsubscribe(IToken token, Exception error) {
- finProxies.remove(finProxy);
- if (finProxies.isEmpty()) streamProxies.remove(channel);
done.doneUnsubscribeStream(error);
}
});
} else {
done.doneUnsubscribeStream(new Exception(Messages.ChannelManager_stream_missing_service_message));
}
+ } else {
+ done.doneUnsubscribeStream(null);
}
+ } else {
+ done.doneUnsubscribeStream(null);
}
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessLauncher.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessLauncher.java
index 71f0d2b5a..6ce812511 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessLauncher.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessLauncher.java
@@ -95,7 +95,7 @@ public class ProcessLauncher extends PlatformObject implements IProcessLauncher
/* default */ boolean sigTermSent;
// The callback instance
- private ICallback callback;
+ ICallback callback;
// The streams listener instance
private IChannelManager.IStreamsListener streamsListener = null;
@@ -112,6 +112,7 @@ public class ProcessLauncher extends PlatformObject implements IProcessLauncher
// The active token.
IToken activeToken = null;
+ private boolean processExited;
/**
* Message ID for error message in case the process launch failed.
@@ -138,6 +139,8 @@ public class ProcessLauncher extends PlatformObject implements IProcessLauncher
*/
@Override
public void dispose() {
+ Assert.isTrue(callback == null || callback.isDone(), "Must not dispose during launch"); //$NON-NLS-1$
+
// Unlink the process context
processContext = null;
@@ -300,19 +303,14 @@ public class ProcessLauncher extends PlatformObject implements IProcessLauncher
Assert.isNotNull(properties);
// Normalize the callback
- if (callback == null) {
- this.callback = new Callback() {
- /* (non-Javadoc)
- * @see org.eclipse.tcf.te.runtime.callback.Callback#internalDone(java.lang.Object, org.eclipse.core.runtime.IStatus)
- */
- @Override
- public void internalDone(Object caller, IStatus status) {
- }
- };
- }
- else {
- this.callback = callback;
- }
+ this.callback = new Callback() {
+ @Override
+ public void internalDone(Object caller, IStatus status) {
+ if (callback != null)
+ callback.setResult(getResult());
+ doneLaunch(callback, status);
+ }
+ };
// Remember the process properties
this.properties = properties;
@@ -372,6 +370,14 @@ public class ProcessLauncher extends PlatformObject implements IProcessLauncher
}
}
+ protected void doneLaunch(ICallback callback, IStatus status) {
+ if (callback != null)
+ callback.done(this, status);
+ // process exited during launch - dispose now
+ if (processExited)
+ dispose();
+ }
+
protected void onChannelOpenDone(final IPeer peer) {
Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$
@@ -1017,17 +1023,16 @@ public class ProcessLauncher extends PlatformObject implements IProcessLauncher
* @param result The result object or <code>null</code>.
*/
protected void invokeCallback(IStatus status, Object result) {
- // Dispose the process launcher if we report an error
- if (status.getSeverity() == IStatus.ERROR) {
- dispose();
- }
-
// Invoke the callback
ICallback callback = getCallback();
if (callback != null) {
callback.setResult(result);
callback.done(this, status);
}
+ // Dispose the process launcher if we report an error
+ if (status.getSeverity() == IStatus.ERROR) {
+ dispose();
+ }
}
/**
@@ -1173,4 +1178,11 @@ public class ProcessLauncher extends PlatformObject implements IProcessLauncher
}
return result.toString();
}
+
+ void processExited() {
+ processExited = true;
+ // dispose unless process launch is still in progress
+ if (callback.isDone())
+ dispose();
+ }
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessProcessesListener.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessProcessesListener.java
index 6251db486..b3160be27 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessProcessesListener.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessProcessesListener.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2011, 2015 Wind River Systems, Inc. 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 http://www.eclipse.org/legal/epl-v10.html
@@ -14,11 +14,11 @@ import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.tcf.services.IProcesses;
import org.eclipse.tcf.services.IProcesses.ProcessesListener;
+import org.eclipse.tcf.te.runtime.events.EventManager;
+import org.eclipse.tcf.te.runtime.interfaces.callback.ICallback;
import org.eclipse.tcf.te.tcf.processes.core.activator.CoreBundleActivator;
import org.eclipse.tcf.te.tcf.processes.core.interfaces.launcher.IProcessContextAwareListener;
import org.eclipse.tcf.te.tcf.processes.core.interfaces.tracing.ITraceIds;
-import org.eclipse.tcf.te.runtime.events.EventManager;
-import org.eclipse.tcf.te.runtime.interfaces.callback.ICallback;
/**
* Remote process processes listener implementation.
@@ -111,8 +111,8 @@ public class ProcessProcessesListener implements ProcessesListener, IProcessCont
// Send a notification
ProcessStateChangeEvent event = createRemoteProcessStateChangeEvent(context, exitCode);
EventManager.getInstance().fireEvent(event);
- // Dispose the parent remote process launcher
- getParent().dispose();
+ // Notify the parent remote process launcher
+ getParent().processExited();
}
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessStreamsListener.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessStreamsListener.java
index bf2d8631e..717e56693 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessStreamsListener.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessStreamsListener.java
@@ -435,7 +435,8 @@ public class ProcessStreamsListener implements IChannelManager.IStreamsListener,
}
// Store the callback instance
- this.callback = callback;
+ if (callback != null)
+ this.callback = callback;
}
/**

Back to the top