Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUwe Stieber2011-11-14 17:19:22 +0000
committerUwe Stieber2011-11-14 17:58:49 +0000
commit7648a108647fefb71f48aff164076c60205eedf1 (patch)
tree28d30fd78868f0776a4b90d01ef88d62970f70cc /target_explorer/plugins
parent89aa93ebb281f229ac45bfc5fe1ee93dece9cce2 (diff)
downloadorg.eclipse.tcf-7648a108647fefb71f48aff164076c60205eedf1.tar.gz
org.eclipse.tcf-7648a108647fefb71f48aff164076c60205eedf1.tar.xz
org.eclipse.tcf-7648a108647fefb71f48aff164076c60205eedf1.zip
Target Explorer: Enable the asynchronous callback collector and handler to customize the callback invocation thread
Diffstat (limited to 'target_explorer/plugins')
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core/META-INF/MANIFEST.MF2
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/async/AbstractAsyncExecutableJob.java14
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/async/AbstractAsyncExecutableStepperJob.java (renamed from target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/async/AsyncExecutableStepperJob.java)6
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/async/AsyncCallbackCollector.java29
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/async/AsyncCallbackHandler.java30
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/model/ThreadSafeContainerModelNode.java28
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/model/ThreadSafeModelNode.java28
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.processes.core/src/org/eclipse/tm/te/tcf/processes/core/launcher/ProcessLauncher.java23
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.processes.core/src/org/eclipse/tm/te/tcf/processes/core/launcher/ProcessStreamsListener.java13
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.terminals.core/src/org/eclipse/tm/te/tcf/terminals/core/launcher/TerminalsLauncher.java23
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.terminals.core/src/org/eclipse/tm/te/tcf/terminals/core/launcher/TerminalsStreamsListener.java13
11 files changed, 99 insertions, 110 deletions
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core/META-INF/MANIFEST.MF b/target_explorer/plugins/org.eclipse.tm.te.core/META-INF/MANIFEST.MF
index 015f2121f..a9dd00f75 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.core/META-INF/MANIFEST.MF
+++ b/target_explorer/plugins/org.eclipse.tm.te.core/META-INF/MANIFEST.MF
@@ -7,7 +7,6 @@ Bundle-Activator: org.eclipse.tm.te.core.activator.CoreBundleActivator
Bundle-Vendor: %providerName
Require-Bundle: org.eclipse.core.runtime;bundle-version="3.7.0",
org.eclipse.tm.te.runtime;bundle-version="1.0.0",
- org.eclipse.tm.te.runtime.concurrent;bundle-version="1.0.0",
org.eclipse.tm.te.runtime.stepper;bundle-version="1.0.0",
org.eclipse.tm.te.runtime.services;bundle-version="1.0.0",
org.eclipse.tm.te.runtime.persistence;bundle-version="1.0.0",
@@ -23,7 +22,6 @@ Export-Package: org.eclipse.tm.te.core.activator;x-internal:=true,
org.eclipse.tm.te.core.connection.interfaces,
org.eclipse.tm.te.core.connection.managers,
org.eclipse.tm.te.core.connection.strategy,
- org.eclipse.tm.te.core.model,
org.eclipse.tm.te.core.model.interfaces,
org.eclipse.tm.te.core.nls;x-internal:=true,
org.eclipse.tm.te.core.utils.text
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/async/AbstractAsyncExecutableJob.java b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/async/AbstractAsyncExecutableJob.java
index c6b2536aa..4abd2a781 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/async/AbstractAsyncExecutableJob.java
+++ b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/async/AbstractAsyncExecutableJob.java
@@ -17,7 +17,7 @@ import org.eclipse.core.runtime.jobs.IJobManager;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.tm.te.core.async.interfaces.IAsyncExecutable;
import org.eclipse.tm.te.runtime.callback.Callback;
-import org.eclipse.tm.te.runtime.concurrent.util.ExecutorsUtil;
+import org.eclipse.tm.te.runtime.interfaces.IConditionTester;
import org.eclipse.tm.te.runtime.interfaces.callback.ICallback;
import org.eclipse.tm.te.runtime.utils.ProgressHelper;
@@ -186,6 +186,16 @@ public abstract class AbstractAsyncExecutableJob extends Job implements IAsyncEx
*/
protected abstract void internalExecute(final IProgressMonitor monitor, final ICallback callback);
+ /**
+ * Hold the execution of {@link #run(IProgressMonitor)} until the asynchronous executable
+ * has completed the execution and invoked the callback.
+ *
+ * @param timeout The timeout in milliseconds. <code>0</code> means wait forever.
+ * @param conditionTester The condition tester which condition must be fulfilled until
+ * the execution hold of {@link #run(IProgressMonitor)} can be released.
+ */
+ protected abstract void waitAndExecute(long timeout, IConditionTester conditionTester);
+
/* (non-Javadoc)
* @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
*/
@@ -196,7 +206,7 @@ public abstract class AbstractAsyncExecutableJob extends Job implements IAsyncEx
ProgressHelper.beginTask(monitor, "", jobTicks); //$NON-NLS-1$
final Callback callback = new Callback(monitor, ProgressHelper.PROGRESS_DONE, getJobCallback());
internalExecute(monitor, callback);
- ExecutorsUtil.waitAndExecute(0, callback.getDoneConditionTester(isCancelable() ? monitor : null));
+ waitAndExecute(0, callback.getDoneConditionTester(isCancelable() ? monitor : null));
finished = true;
if (getRescheduleDelay() >= 0 && Platform.isRunning() && (!isCancelable() || !monitor.isCanceled())) {
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/async/AsyncExecutableStepperJob.java b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/async/AbstractAsyncExecutableStepperJob.java
index 073fd5cd4..0c12489cf 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/async/AsyncExecutableStepperJob.java
+++ b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/async/AbstractAsyncExecutableStepperJob.java
@@ -19,12 +19,12 @@ import org.eclipse.tm.te.runtime.interfaces.callback.ICallback;
import org.eclipse.tm.te.runtime.utils.ProgressHelper;
/**
- * Asynchronous executable stepper job.
+ * Abstract asynchronous executable stepper job.
* <p>
* The job executes a list of actions. If any action returns with an error, the whole job will be
* aborted.
*/
-public class AsyncExecutableStepperJob extends AbstractAsyncExecutableJob {
+public abstract class AbstractAsyncExecutableStepperJob extends AbstractAsyncExecutableJob {
private final IAsyncExecutable[] actions;
/**
@@ -33,7 +33,7 @@ public class AsyncExecutableStepperJob extends AbstractAsyncExecutableJob {
* @param name The job name. Must not be <code>null</code>
* @param actions The actions to execute. Must not be <code>null</code>.
*/
- public AsyncExecutableStepperJob(String name, IAsyncExecutable[] actions) {
+ public AbstractAsyncExecutableStepperJob(String name, IAsyncExecutable[] actions) {
super(name);
Assert.isNotNull(actions);
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/async/AsyncCallbackCollector.java b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/async/AsyncCallbackCollector.java
index 92d171073..f0fb15908 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/async/AsyncCallbackCollector.java
+++ b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/async/AsyncCallbackCollector.java
@@ -17,7 +17,6 @@ import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.tm.te.core.activator.CoreBundleActivator;
import org.eclipse.tm.te.runtime.callback.Callback;
-import org.eclipse.tm.te.runtime.concurrent.util.ExecutorsUtil;
import org.eclipse.tm.te.runtime.interfaces.callback.ICallback;
/**
@@ -40,6 +39,23 @@ public class AsyncCallbackCollector extends AsyncCallbackHandler {
private boolean isFinished;
private boolean initDone;
+ // The reference to the callback invocation delegate
+ private ICallbackInvocationDelegate delegate = null;
+
+ /**
+ * Delegation interfaces used by the asynchronous callback collector to
+ * invoke the final callback.
+ */
+ public static interface ICallbackInvocationDelegate {
+
+ /**
+ * Invokes the given runnable.
+ *
+ * @param runnable The runnable. Must not be <code>null</code>.
+ */
+ public void invoke(Runnable runnable);
+ }
+
/**
* Simple target callback handling an asynchronous callback collector parent itself and remove
* themselves from the collector after callback has done.
@@ -90,21 +106,25 @@ public class AsyncCallbackCollector extends AsyncCallbackHandler {
* Constructor.
*/
public AsyncCallbackCollector() {
- this(null);
+ this(null, null);
}
/**
* Constructor.
*
* @param callback The final callback to invoke if the collector enters the finished state.
+ * @param delegate The callback invocation delegate. Must not be <code>null</code> if the callback is not <code>null</code>.
*/
- public AsyncCallbackCollector(ICallback callback) {
+ public AsyncCallbackCollector(ICallback callback, ICallbackInvocationDelegate delegate) {
super();
+ if (callback != null) Assert.isNotNull(delegate);
+
// We have to add our master callback to the list of callback to avoid that
// the collector is running empty to early!
addCallback(callback);
this.callback = callback;
+ this.delegate = delegate;
// We are not finished yet.
isFinished = false;
@@ -141,7 +161,8 @@ public class AsyncCallbackCollector extends AsyncCallbackHandler {
*/
protected void onCollectorFinished() {
if (callback != null) {
- ExecutorsUtil.execute(new Runnable() {
+ Assert.isNotNull(delegate);
+ delegate.invoke(new Runnable() {
@Override
public void run() {
Throwable error = getError();
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/async/AsyncCallbackHandler.java b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/async/AsyncCallbackHandler.java
index f854ec591..8ea299ebc 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/async/AsyncCallbackHandler.java
+++ b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/async/AsyncCallbackHandler.java
@@ -16,7 +16,6 @@ import java.util.Map;
import java.util.Vector;
import org.eclipse.core.runtime.Platform;
-import org.eclipse.tm.te.runtime.concurrent.util.ExecutorsUtil;
import org.eclipse.tm.te.runtime.interfaces.IConditionTester;
import org.eclipse.tm.te.runtime.interfaces.callback.ICallback;
@@ -26,7 +25,6 @@ import org.eclipse.tm.te.runtime.interfaces.callback.ICallback;
public class AsyncCallbackHandler {
private final List<ICallback> callbacks = new Vector<ICallback>();
private final IConditionTester conditionTester;
- private boolean timeoutOccurred;
private Throwable error;
private final static boolean TRACING_ENABLED = Boolean.parseBoolean(Platform.getDebugOption("org.eclipse.tm.te.runtime/trace/callbacks")); //$NON-NLS-1$
@@ -47,7 +45,6 @@ public class AsyncCallbackHandler {
*/
public AsyncCallbackHandler(IConditionTester tester) {
super();
- timeoutOccurred = false;
error = null;
conditionTester = new AsyncCallbackConditionTester(tester);
}
@@ -147,11 +144,14 @@ public class AsyncCallbackHandler {
}
/**
- * Returns <code>true</code> if the <code>wait</code> methods have been left because of timeout
- * and not because the waiting condition has been fulfilled.
+ * Returns the condition tester to use for waiting for the callback handler
+ * until all callbacks have been invoked and the external condition tester
+ * is fulfilled too.
+ *
+ * @return The condition tester instance.
*/
- public boolean isTimeoutOccurred() {
- return timeoutOccurred;
+ public IConditionTester getConditionTester() {
+ return conditionTester;
}
final class AsyncCallbackConditionTester implements IConditionTester {
@@ -170,8 +170,7 @@ public class AsyncCallbackHandler {
externalTester = tester;
}
- /*
- * (non-Javadoc)
+ /* (non-Javadoc)
* @see org.eclipse.tm.te.runtime.interfaces.IConditionTester#cleanup()
*/
@Override
@@ -181,8 +180,7 @@ public class AsyncCallbackHandler {
}
}
- /*
- * (non-Javadoc)
+ /* (non-Javadoc)
* @see org.eclipse.tm.te.runtime.interfaces.IConditionTester#isConditionFulfilled()
*/
@Override
@@ -191,14 +189,4 @@ public class AsyncCallbackHandler {
return isEmpty() || (externalTester != null && externalTester.isConditionFulfilled());
}
}
-
- /**
- * Wait for all associated callback's to finish or the specified timeout has been occurred.
- *
- * @param timeout The timeout in milliseconds. If <code>0</code>, the method waits forever till
- * all callback's have been returned.
- */
- public final void waitForFinishOrTimeout(long timeout) {
- timeoutOccurred = ExecutorsUtil.waitAndExecute(timeout, conditionTester);
- }
}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/model/ThreadSafeContainerModelNode.java b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/model/ThreadSafeContainerModelNode.java
deleted file mode 100644
index 73fe10a67..000000000
--- a/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/model/ThreadSafeContainerModelNode.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2011 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
- *
- * Contributors:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-package org.eclipse.tm.te.core.model;
-
-import org.eclipse.tm.te.runtime.concurrent.util.ExecutorsUtil;
-import org.eclipse.tm.te.runtime.model.ContainerModelNode;
-
-/**
- * Container model node implementation assuring thread safety by enforcing model operations to
- * happen in the executor thread.
- */
-public class ThreadSafeContainerModelNode extends ContainerModelNode {
-
- /* (non-Javadoc)
- * @see org.eclipse.tm.te.runtime.nodes.PropertiesContainer#checkThreadAccess()
- */
- @Override
- protected boolean checkThreadAccess() {
- return ExecutorsUtil.isExecutorThread();
- }
-}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/model/ThreadSafeModelNode.java b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/model/ThreadSafeModelNode.java
deleted file mode 100644
index 357405372..000000000
--- a/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/model/ThreadSafeModelNode.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2011 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
- *
- * Contributors:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-package org.eclipse.tm.te.core.model;
-
-import org.eclipse.tm.te.runtime.concurrent.util.ExecutorsUtil;
-import org.eclipse.tm.te.runtime.model.ModelNode;
-
-/**
- * Model node implementation assuring thread safety by enforcing model operations to happen in the
- * executor thread.
- */
-public class ThreadSafeModelNode extends ModelNode {
-
- /* (non-Javadoc)
- * @see org.eclipse.tm.te.runtime.nodes.PropertiesContainer#checkThreadAccess()
- */
- @Override
- protected boolean checkThreadAccess() {
- return ExecutorsUtil.isExecutorThread();
- }
-}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.processes.core/src/org/eclipse/tm/te/tcf/processes/core/launcher/ProcessLauncher.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.processes.core/src/org/eclipse/tm/te/tcf/processes/core/launcher/ProcessLauncher.java
index 650691f2e..91d0d1596 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.tcf.processes.core/src/org/eclipse/tm/te/tcf/processes/core/launcher/ProcessLauncher.java
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.processes.core/src/org/eclipse/tm/te/tcf/processes/core/launcher/ProcessLauncher.java
@@ -128,22 +128,25 @@ public class ProcessLauncher extends PlatformObject implements IProcessLauncher
eventListener = null;
}
+ // Create the callback invocation delegate
+ AsyncCallbackCollector.ICallbackInvocationDelegate delegate = new AsyncCallbackCollector.ICallbackInvocationDelegate() {
+ @Override
+ public void invoke(Runnable runnable) {
+ Assert.isNotNull(runnable);
+ if (Protocol.isDispatchThread()) runnable.run();
+ else Protocol.invokeLater(runnable);
+ }
+ };
+
// Create the callback collector
final AsyncCallbackCollector collector = new AsyncCallbackCollector(new Callback() {
@Override
protected void internalDone(Object caller, IStatus status) {
+ Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$
// Close the channel as all disposal is done
- if (finChannel != null) {
- if (Protocol.isDispatchThread()) finChannel.close();
- else Protocol.invokeAndWait(new Runnable() {
- @Override
- public void run() {
- finChannel.close();
- }
- });
- }
+ if (finChannel != null) finChannel.close();
}
- });
+ }, delegate);
if (streamsListener != null) {
// Dispose the streams listener
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.processes.core/src/org/eclipse/tm/te/tcf/processes/core/launcher/ProcessStreamsListener.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.processes.core/src/org/eclipse/tm/te/tcf/processes/core/launcher/ProcessStreamsListener.java
index beb0663ff..fc99fad84 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.tcf.processes.core/src/org/eclipse/tm/te/tcf/processes/core/launcher/ProcessStreamsListener.java
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.processes.core/src/org/eclipse/tm/te/tcf/processes/core/launcher/ProcessStreamsListener.java
@@ -646,6 +646,16 @@ public class ProcessStreamsListener implements IStreams.StreamsListener, IProces
dataReceiver.clear();
}
+ // Create the callback invocation delegate
+ AsyncCallbackCollector.ICallbackInvocationDelegate delegate = new AsyncCallbackCollector.ICallbackInvocationDelegate() {
+ @Override
+ public void invoke(Runnable runnable) {
+ Assert.isNotNull(runnable);
+ if (Protocol.isDispatchThread()) runnable.run();
+ else Protocol.invokeLater(runnable);
+ }
+ };
+
// Create a new collector to catch all runnable stop callback's
AsyncCallbackCollector collector = new AsyncCallbackCollector(new Callback() {
/* (non-Javadoc)
@@ -653,6 +663,7 @@ public class ProcessStreamsListener implements IStreams.StreamsListener, IProces
*/
@Override
protected void internalDone(final Object caller, final IStatus status) {
+ Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$
// Get the service instance from the parent
IStreams svcStreams = getParent().getSvcStreams();
// Unsubscribe the streams listener from the service
@@ -666,7 +677,7 @@ public class ProcessStreamsListener implements IStreams.StreamsListener, IProces
}
});
}
- });
+ }, delegate);
// Loop all runnable's and force them to stop
synchronized (runnables) {
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.terminals.core/src/org/eclipse/tm/te/tcf/terminals/core/launcher/TerminalsLauncher.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.terminals.core/src/org/eclipse/tm/te/tcf/terminals/core/launcher/TerminalsLauncher.java
index b3b426b18..057adcf31 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.tcf.terminals.core/src/org/eclipse/tm/te/tcf/terminals/core/launcher/TerminalsLauncher.java
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.terminals.core/src/org/eclipse/tm/te/tcf/terminals/core/launcher/TerminalsLauncher.java
@@ -112,22 +112,25 @@ public class TerminalsLauncher extends PlatformObject implements ITerminalsLaunc
eventListener = null;
}
+ // Create the callback invocation delegate
+ AsyncCallbackCollector.ICallbackInvocationDelegate delegate = new AsyncCallbackCollector.ICallbackInvocationDelegate() {
+ @Override
+ public void invoke(Runnable runnable) {
+ Assert.isNotNull(runnable);
+ if (Protocol.isDispatchThread()) runnable.run();
+ else Protocol.invokeLater(runnable);
+ }
+ };
+
// Create the callback collector
final AsyncCallbackCollector collector = new AsyncCallbackCollector(new Callback() {
@Override
protected void internalDone(Object caller, IStatus status) {
+ Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$
// Close the channel as all disposal is done
- if (finChannel != null) {
- if (Protocol.isDispatchThread()) finChannel.close();
- else Protocol.invokeAndWait(new Runnable() {
- @Override
- public void run() {
- finChannel.close();
- }
- });
- }
+ if (finChannel != null) finChannel.close();
}
- });
+ }, delegate);
if (streamsListener != null) {
// Dispose the streams listener
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.terminals.core/src/org/eclipse/tm/te/tcf/terminals/core/launcher/TerminalsStreamsListener.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.terminals.core/src/org/eclipse/tm/te/tcf/terminals/core/launcher/TerminalsStreamsListener.java
index 48fbf400a..4d12ab394 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.tcf.terminals.core/src/org/eclipse/tm/te/tcf/terminals/core/launcher/TerminalsStreamsListener.java
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.terminals.core/src/org/eclipse/tm/te/tcf/terminals/core/launcher/TerminalsStreamsListener.java
@@ -656,6 +656,16 @@ public class TerminalsStreamsListener implements IStreams.StreamsListener, ITerm
dataReceiver.clear();
}
+ // Create the callback invocation delegate
+ AsyncCallbackCollector.ICallbackInvocationDelegate delegate = new AsyncCallbackCollector.ICallbackInvocationDelegate() {
+ @Override
+ public void invoke(Runnable runnable) {
+ Assert.isNotNull(runnable);
+ if (Protocol.isDispatchThread()) runnable.run();
+ else Protocol.invokeLater(runnable);
+ }
+ };
+
// Create a new collector to catch all runnable stop callback's
AsyncCallbackCollector collector = new AsyncCallbackCollector(new Callback() {
/* (non-Javadoc)
@@ -663,6 +673,7 @@ public class TerminalsStreamsListener implements IStreams.StreamsListener, ITerm
*/
@Override
protected void internalDone(final Object caller, final IStatus status) {
+ Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$
// Get the service instance from the parent
IStreams svcStreams = getParent().getSvcStreams();
// Unsubscribe the streams listener from the service
@@ -676,7 +687,7 @@ public class TerminalsStreamsListener implements IStreams.StreamsListener, ITerm
}
});
}
- });
+ }, delegate);
// Loop all runnable's and force them to stop
synchronized (runnables) {

Back to the top