Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core.concurrent/build.properties3
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core.concurrent/plugin.properties3
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core.concurrent/plugin.xml24
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core.concurrent/schema/executorServices.exsd200
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core.concurrent/schema/executorUtilDelegates.exsd200
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/Executors.java147
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/event/ExecutorThreadNotificationListener.java34
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/executors/AbstractDelegatingExecutorService.java206
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/executors/SingleThreadedExecutorService.java182
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/factories/SingleThreadThreadFactory.java71
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/interfaces/IExecutor.java21
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/interfaces/IExecutorUtilDelegate.java38
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/interfaces/INestableExecutor.java37
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/interfaces/ISingleThreadedExecutor.java38
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/nls/Messages.java1
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/nls/Messages.properties2
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/util/ExecutorsUtil.java302
17 files changed, 1508 insertions, 1 deletions
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/build.properties b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/build.properties
index f4ae97015..73a5119ed 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/build.properties
+++ b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/build.properties
@@ -2,4 +2,5 @@ source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
- plugin.properties
+ plugin.properties,\
+ plugin.xml
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/plugin.properties b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/plugin.properties
index 708f53360..d3682ad53 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/plugin.properties
+++ b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/plugin.properties
@@ -10,3 +10,6 @@
pluginName = Target Explorer, Concurrent Core plug-in
providerName = Eclipse.org
+
+ExtensionPoint.executorServices.name=Executor Services
+ExtensionPoint.executorUtilDelegates.name=Executor Utility Wait and Dispatch Delegates
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/plugin.xml b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/plugin.xml
new file mode 100644
index 000000000..eb9707c1b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/plugin.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+<!-- Extension point contributions -->
+ <extension-point id="executorServices" name="%ExtensionPoint.executorServices.name" schema="schema/executorServices.exsd"/>
+ <extension-point id="executorUtilDelegates" name="%ExtensionPoint.executorUtilDelegates.name" schema="schema/executorUtilDelegates.exsd"/>
+
+<!-- Executor service contributions -->
+ <extension point="org.eclipse.tm.te.core.concurrent.executorServices">
+ <executorService
+ id="org.eclipse.tm.te.core.concurrent.executors.singleThreaded"
+ label="Single Threaded Executor">
+ <class
+ class="org.eclipse.tm.te.core.concurrent.executors.SingleThreadedExecutorService">
+ <parameter
+ name="threadPoolNamePrefix"
+ value="Target Explorer Single Thread Executor">
+ </parameter>
+ </class>
+ </executorService>
+ </extension>
+
+</plugin>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/schema/executorServices.exsd b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/schema/executorServices.exsd
new file mode 100644
index 000000000..2bb2977c4
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/schema/executorServices.exsd
@@ -0,0 +1,200 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.tm.te.core.concurrent" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.tm.te.core.concurrent" id="executorServices" name="Executor Services"/>
+ </appinfo>
+ <documentation>
+ This extension point is used to contribute executor services.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="executorService" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="executorService">
+ <annotation>
+ <documentation>
+ Declares a Wind River executor service contribution.
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="class" minOccurs="0" maxOccurs="1"/>
+ <element ref="description" minOccurs="0" maxOccurs="1"/>
+ </sequence>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ The unique id of the executor service contribution.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="label" type="string" use="required">
+ <annotation>
+ <documentation>
+ The label representing the executor service within the UI.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string">
+ <annotation>
+ <documentation>
+ The class that implements &lt;code&gt;com.windriver.core.runtime.concurrent.interfaces.IWRExecutor&lt;/code&gt; or extends &lt;code&gt;com.windriver.core.runtime.concurrent.executors.AbstractDelegatingExecutorService&lt;/code&gt;.
+&lt;p&gt;
+The executor service implementation class must be specified either by the class attribute or the class child element!
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":com.windriver.core.runtime.concurrent.interfaces.IWRExecutor"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="description" type="string">
+ <annotation>
+ <documentation>
+ A short description of the executor service to be presented in the UI.
+ </documentation>
+ </annotation>
+ </element>
+
+ <element name="class">
+ <annotation>
+ <documentation>
+ &lt;p&gt;Used when creating an &lt;code&gt;IExecutableExtension&lt;/code&gt; with a named parameter, or more than one.&lt;/p&gt;
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="parameter" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="class" type="string">
+ <annotation>
+ <documentation>
+ The class that implements &lt;code&gt;com.windriver.core.runtime.concurrent.interfaces.IWRExecutor&lt;/code&gt; or extends &lt;code&gt;com.windriver.core.runtime.concurrent.executors.AbstractDelegatingExecutorService&lt;/code&gt;.
+&lt;p&gt;
+The executor service implementation class must be specified either by the class attribute or the class child element!
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":com.windriver.core.runtime.concurrent.interfaces.IWRExecutor"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="parameter">
+ <annotation>
+ <documentation>
+ &lt;p&gt;A parameter for an &lt;code&gt;IExecutableExtension&lt;/code&gt;.&lt;/p&gt;
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="name" type="string" use="required">
+ <annotation>
+ <documentation>
+ &lt;p&gt;The parameter name.&lt;/p&gt;
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="value" type="string" use="required">
+ <annotation>
+ <documentation>
+ &lt;p&gt;The parameter value.&lt;/p&gt;
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ Target Explorer 1.0.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ This is an example of the extension point usage:
+&lt;p&gt;
+&lt;pre&gt;&lt;code&gt;
+ &lt;extension point=&quot;org.eclipse.tm.te.core.concurrent.executorServices&quot;&gt;
+ &lt;executorService
+ id=&quot;org.eclipse.tm.te.core.concurrent.executors.singleThreaded&quot;
+ class=&quot;org.eclipse.tm.te.core.concurrent.executors.SingleThreadedExecutorService&quot;
+ label=&quot;Single Threaded Executor Service&quot;&gt;
+ &lt;/exectorService&gt;
+ &lt;/extension&gt;
+&lt;/code&gt;&lt;/pre&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="apiinfo"/>
+ </appinfo>
+ <documentation>
+ The provider of a executor service must implement &lt;samp&gt;org.eclipse.tm.te.core.concurrent.interfaces.IExecutor&lt;/samp&gt;.
+ </documentation>
+ </annotation>
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="copyright"/>
+ </appinfo>
+ <documentation>
+ 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.
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/schema/executorUtilDelegates.exsd b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/schema/executorUtilDelegates.exsd
new file mode 100644
index 000000000..29cab0c64
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/schema/executorUtilDelegates.exsd
@@ -0,0 +1,200 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.tm.te.core.concurrent" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.tm.te.core.concurrent" id="executorUtilDelegates" name="Executor Utility Delegates"/>
+ </appinfo>
+ <documentation>
+ This extension point is used to contribute executor utility delegates.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="executorUtilDelegate" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="executorUtilDelegate">
+ <annotation>
+ <documentation>
+ Declares a Wind River executor utility delegate contribution.
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="class" minOccurs="0" maxOccurs="1"/>
+ <element ref="description" minOccurs="0" maxOccurs="1"/>
+ </sequence>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ The unique id of the executor utility delegate contribution.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="label" type="string" use="required">
+ <annotation>
+ <documentation>
+ The label representing the executor utility delegate within the UI.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string">
+ <annotation>
+ <documentation>
+ The class that implements &lt;code&gt;com.windriver.core.runtime.concurrent.interfaces.IWRExecutorUtilDelegate&lt;/code&gt;.
+&lt;p&gt;
+The executor utility delegate implementation class must be specified either by the class attribute or the class child element!
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":com.windriver.core.runtime.concurrent.interfaces.IWRExecutorUtilDelegate"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="description" type="string">
+ <annotation>
+ <documentation>
+ A short description of the executor utility delegate to be presented in the UI.
+ </documentation>
+ </annotation>
+ </element>
+
+ <element name="class">
+ <annotation>
+ <documentation>
+ &lt;p&gt;Used when creating an &lt;code&gt;IExecutableExtension&lt;/code&gt; with a named parameter, or more than one.&lt;/p&gt;
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="parameter" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="class" type="string">
+ <annotation>
+ <documentation>
+ The class that implements &lt;code&gt;com.windriver.core.runtime.concurrent.interfaces.IWRExecutorUtilDelegate&lt;/code&gt;.
+&lt;p&gt;
+The executor utility delegate implementation class must be specified either by the class attribute or the class child element!
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":com.windriver.core.runtime.concurrent.interfaces.IWRExecutorUtilDelegate"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="parameter">
+ <annotation>
+ <documentation>
+ &lt;p&gt;A parameter for an &lt;code&gt;IExecutableExtension&lt;/code&gt;.&lt;/p&gt;
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="name" type="string" use="required">
+ <annotation>
+ <documentation>
+ &lt;p&gt;The parameter name.&lt;/p&gt;
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="value" type="string" use="required">
+ <annotation>
+ <documentation>
+ &lt;p&gt;The parameter value.&lt;/p&gt;
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ Target Explorer 1.0.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ This is an example of the extension point usage:
+&lt;p&gt;
+&lt;pre&gt;&lt;code&gt;
+ &lt;extension point=&quot;org.eclipse.tm.te.core.concurrent.executorUtilDelegates&quot;&gt;
+ &lt;executorUtilDelegate
+ id=&quot;org.eclipse.tm.te.core.concurrent.executor.delegates.swt&quot;
+ class=&quot;org.eclipse.tm.te.ui.swt.executor.delegates.SWTExecutorUtilDelegate&quot;
+ label=&quot;SWT Executor Utility Delegate&quot;&gt;
+ &lt;/exectorUtilDelegate&gt;
+ &lt;/extension&gt;
+&lt;/code&gt;&lt;/pre&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="apiinfo"/>
+ </appinfo>
+ <documentation>
+ The provider of a executor utility delegates must implement &lt;samp&gt;org.eclipse.tm.te.core.concurrent.interfaces.IExecutorUtilDelegate&lt;/samp&gt;.
+ </documentation>
+ </annotation>
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="copyright"/>
+ </appinfo>
+ <documentation>
+ 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.
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/Executors.java b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/Executors.java
new file mode 100644
index 000000000..b298a28cd
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/Executors.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * 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.concurrent;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.tm.te.core.concurrent.interfaces.IExecutor;
+import org.eclipse.tm.te.core.extensions.AbstractExtensionPointManager;
+import org.eclipse.tm.te.core.extensions.ExecutableExtensionProxy;
+
+
+/**
+ * Class is providing the entry points to create or query the executor service
+ * instances.
+ */
+public final class Executors {
+
+ /**
+ * Execution service extension point manager.
+ */
+ protected static class ExecutorServiceExtensionPointManager extends AbstractExtensionPointManager<IExecutor> {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.tm.te.core.extensions.AbstractExtensionPointManager#
+ * getExtensionPointId()
+ */
+ @Override
+ protected String getExtensionPointId() {
+ return "org.eclipse.tm.te.core.concurrent.executorServices"; //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.tm.te.core.extensions.AbstractExtensionPointManager#
+ * getConfigurationElementName()
+ */
+ @Override
+ protected String getConfigurationElementName() {
+ return "executorService"; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the list of all contributed executors.
+ *
+ * @return The list of contributed executors, or an empty array.
+ */
+ public IExecutor[] getExecutors() {
+ List<IExecutor> contributions = new ArrayList<IExecutor>();
+ Collection<ExecutableExtensionProxy<IExecutor>> proxies = getExtensions().values();
+ for (ExecutableExtensionProxy<IExecutor> proxy : proxies)
+ if (proxy.getInstance() != null
+ && !contributions.contains(proxy.getInstance()))
+ contributions.add(proxy.getInstance());
+
+ return contributions.toArray(new IExecutor[contributions.size()]);
+ }
+
+ /**
+ * Returns the executor identified by its unique id. If no executor with
+ * the specified id is registered, <code>null</code> is returned.
+ *
+ * @param id
+ * The unique id of the executor. Must not be
+ * <code>null</code>
+ * @param newInstance
+ * Specify <code>true</code> to get a new executor service
+ * instance, <code>false</code> otherwise.
+ *
+ * @return The executor instance or <code>null</code>.
+ */
+ public IExecutor getExecutor(String id, boolean newInstance) {
+ Assert.isNotNull(id);
+
+ IExecutor executorService = null;
+ if (getExtensions().containsKey(id)) {
+ ExecutableExtensionProxy<IExecutor> proxy = getExtensions().get(id);
+ // Get the extension instance
+ executorService = newInstance ? proxy.newInstance() : proxy.getInstance();
+ }
+
+ return executorService;
+ }
+ }
+
+ // Reference to the executor service extension point manager
+ private final static ExecutorServiceExtensionPointManager EXTENSION_POINT_MANAGER = new ExecutorServiceExtensionPointManager();
+
+ /**
+ * Constructor.
+ * <p>
+ * <b>Note:</b> The class cannot be instantiated.
+ */
+ private Executors() {
+ }
+
+ /**
+ * Creates an instance of the executor registered with the specified id. If
+ * no executor is registered under the given id, the method will return
+ * <code>null</code>.
+ *
+ * @param id
+ * The id of the executor. Must not be <code>null</code>.
+ * @return The new executor instance or <code>null</code>.
+ */
+ public static IExecutor newExecutor(String id) {
+ Assert.isNotNull(id);
+ return EXTENSION_POINT_MANAGER.getExecutor(id, true);
+ }
+
+ /**
+ * Returns the shared instance of the executor registered with the specified
+ * id. If the shared instance hasn't been created yet, the instance will be
+ * created and saved. Subsequent calls to this method with the same id will
+ * return always the same executor instance. If no executor is registered
+ * under the given id, the method will return <code>null</code>.
+ *
+ * @param id
+ * The id of the executor. Must not be <code>null</code>.
+ * @return The new executor instance or <code>null</code>.
+ */
+ public static IExecutor getSharedExecutor(String id) {
+ Assert.isNotNull(id);
+ return EXTENSION_POINT_MANAGER.getExecutor(id, false);
+ }
+
+ /**
+ * Returns the shared instances of all registered executors.
+ *
+ * @return All executor instances or an empty array.
+ */
+ public static IExecutor[] getAllSharedExecutors() {
+ return EXTENSION_POINT_MANAGER.getExecutors();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/event/ExecutorThreadNotificationListener.java b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/event/ExecutorThreadNotificationListener.java
new file mode 100644
index 000000000..18720ee4b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/event/ExecutorThreadNotificationListener.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * 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.concurrent.event;
+
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.tm.te.core.concurrent.util.ExecutorsUtil;
+import org.eclipse.tm.te.core.interfaces.events.IEventFireDelegate;
+import org.eclipse.tm.te.core.interfaces.events.IEventListener;
+
+/**
+ * Abstract notification listener implementation executing the
+ * notifications within the shared executor thread.
+ */
+public abstract class ExecutorThreadNotificationListener extends PlatformObject implements IEventListener, IEventFireDelegate {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.core.interfaces.events.IEventFireDelegate#fire(java.lang.Runnable)
+ */
+ public final void fire(Runnable runnable) {
+ // Force notification into the executor thread.
+ //
+ // Note: The executor thread is not identical with the display thread!
+ // Use ExecutorsUtil.executeInUI(runnable) to execute the runnable
+ // within the display thread.
+ ExecutorsUtil.execute(runnable);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/executors/AbstractDelegatingExecutorService.java b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/executors/AbstractDelegatingExecutorService.java
new file mode 100644
index 000000000..72b3e8c39
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/executors/AbstractDelegatingExecutorService.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * 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.concurrent.executors;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tm.te.core.concurrent.activator.CoreBundleActivator;
+import org.eclipse.tm.te.core.concurrent.interfaces.IExecutor;
+import org.eclipse.tm.te.core.concurrent.nls.Messages;
+import org.eclipse.tm.te.core.extensions.ExecutableExtension;
+
+/**
+ * Abstract delegating execution service implementation.
+ */
+public abstract class AbstractDelegatingExecutorService extends
+ ExecutableExtension implements IExecutor, ExecutorService {
+ // The executor service to delegate the API calls to
+ private ExecutorService delegate;
+
+ // The thread pool name prefix
+ private String threadPoolNamePrefix;
+
+ /**
+ * Constructor.
+ */
+ public AbstractDelegatingExecutorService() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.core.extensions.ExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)
+ */
+ @Override
+ public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {
+ super.setInitializationData(config, propertyName, data);
+
+ if (config != null && data instanceof Map<?, ?>) {
+ Map<?, ?> params = (Map<?, ?>) data;
+ // Initialize the thread pool name prefix field by reading the
+ // "threadPoolNamePrefix" extension attribute if present.
+ threadPoolNamePrefix = (String) params.get("threadPoolNamePrefix"); //$NON-NLS-1$
+ if (threadPoolNamePrefix == null || threadPoolNamePrefix.trim().length() == 0) {
+ threadPoolNamePrefix = ""; //$NON-NLS-1$
+ }
+ }
+
+ // Create the executor service delegate
+ this.delegate = createExecutorServiceDelegate();
+ Assert.isNotNull(delegate);
+ }
+
+ /**
+ * Returns the thread pool name prefix if specified by the extension.
+ *
+ * @return The thread pool name prefix or an empty string.
+ */
+ public String getThreadPoolNamePrefix() {
+ return threadPoolNamePrefix != null ? threadPoolNamePrefix : ""; //$NON-NLS-1$
+ }
+
+ /**
+ * Invoked by the constructor exactly once to create the executor service
+ * delegate instance.
+ *
+ * @return The executor service instance and never <code>null</code>.
+ */
+ protected abstract ExecutorService createExecutorServiceDelegate();
+
+ /**
+ * Returns the executor service delegate instance.
+ *
+ * @return The executor service delegate instance.
+ */
+ protected final ExecutorService getExecutorServiceDelegate() {
+ return delegate;
+ }
+
+ /**
+ * Log the given exception as error to the error log.
+ *
+ * @param e
+ * The exception or <code>null</code>.
+ */
+ protected void logException(Throwable e) {
+ if (e != null) {
+ IStatus status = new Status(
+ IStatus.ERROR,
+ CoreBundleActivator.getUniqueIdentifier(),
+ NLS.bind(Messages.AbstractDelegatingExecutorService_unhandledException,
+ e.getLocalizedMessage()), e);
+ Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(status);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.concurrent.Executor#execute(java.lang.Runnable)
+ */
+ public void execute(Runnable command) {
+ delegate.execute(command);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.concurrent.ExecutorService#shutdown()
+ */
+ public void shutdown() {
+ delegate.shutdown();
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.concurrent.ExecutorService#shutdownNow()
+ */
+ public List<Runnable> shutdownNow() {
+ return delegate.shutdownNow();
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.concurrent.ExecutorService#isShutdown()
+ */
+ public boolean isShutdown() {
+ return delegate.isShutdown();
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.concurrent.ExecutorService#isTerminated()
+ */
+ public boolean isTerminated() {
+ return delegate.isTerminated();
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.concurrent.ExecutorService#awaitTermination(long, java.util.concurrent.TimeUnit)
+ */
+ public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
+ return delegate.awaitTermination(timeout, unit);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.concurrent.ExecutorService#submit(java.util.concurrent.Callable)
+ */
+ public <T> Future<T> submit(Callable<T> task) {
+ return delegate.submit(task);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.concurrent.ExecutorService#submit(java.lang.Runnable, java.lang.Object)
+ */
+ public <T> Future<T> submit(Runnable task, T result) {
+ return delegate.submit(task, result);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.concurrent.ExecutorService#submit(java.lang.Runnable)
+ */
+ public Future<?> submit(Runnable task) {
+ return delegate.submit(task);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.concurrent.ExecutorService#invokeAll(java.util.Collection)
+ */
+ public <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks) throws InterruptedException {
+ return delegate.invokeAll(tasks);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.concurrent.ExecutorService#invokeAll(java.util.Collection, long, java.util.concurrent.TimeUnit)
+ */
+ public <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException {
+ return delegate.invokeAll(tasks, timeout, unit);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.concurrent.ExecutorService#invokeAny(java.util.Collection)
+ */
+ public <T> T invokeAny(Collection<Callable<T>> tasks) throws InterruptedException, ExecutionException {
+ return delegate.invokeAny(tasks);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.concurrent.ExecutorService#invokeAny(java.util.Collection, long, java.util.concurrent.TimeUnit)
+ */
+ public <T> T invokeAny(Collection<Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
+ return delegate.invokeAny(tasks, timeout, unit);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/executors/SingleThreadedExecutorService.java b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/executors/SingleThreadedExecutorService.java
new file mode 100644
index 000000000..095817642
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/executors/SingleThreadedExecutorService.java
@@ -0,0 +1,182 @@
+/*******************************************************************************
+ * 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.concurrent.executors;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.eclipse.tm.te.core.concurrent.factories.SingleThreadThreadFactory;
+import org.eclipse.tm.te.core.concurrent.interfaces.INestableExecutor;
+import org.eclipse.tm.te.core.concurrent.interfaces.ISingleThreadedExecutor;
+
+/**
+ * A single threaded executor service implementation.
+ */
+public class SingleThreadedExecutorService extends AbstractDelegatingExecutorService implements ISingleThreadedExecutor, INestableExecutor {
+
+ /**
+ * A single threaded executor implementation.
+ */
+ protected class SingleThreadedExecutor extends ThreadPoolExecutor implements INestableExecutor {
+ // The current nesting depth
+ private final AtomicInteger currentNestingDepth = new AtomicInteger(0);
+
+ /**
+ * Constructor.
+ *
+ * @param threadFactory
+ * The thread factory instance. Must not be <code>null</code>.
+ *
+ * @throws NullPointerException
+ * if threadFactory is <code>null</code>.
+ */
+ public SingleThreadedExecutor(ThreadFactory threadFactory) {
+ this(threadFactory, new LinkedBlockingQueue<Runnable>());
+ }
+
+ /**
+ * Constructor.
+ * <p>
+ * Private constructor to catch the work queue instance passed into the
+ * {@link ThreadPoolExecutor} constructor.
+ *
+ * @param threadFactory
+ * The thread factory instance. Must not be <code>null</code>.
+ * @param workQueue
+ * The work queue instance. Must not be <code>null</code>.
+ */
+ private SingleThreadedExecutor(ThreadFactory threadFactory, BlockingQueue<Runnable> workQueue) {
+ super(1, 1, 0L, TimeUnit.NANOSECONDS, workQueue, threadFactory);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.core.concurrent.interfaces.INestableExecutor#getMaxDepth()
+ */
+ public int getMaxDepth() {
+ return 1;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.core.concurrent.interfaces.INestableExecutor#readAndExecute()
+ */
+ public boolean readAndExecute() {
+ // Method is callable from the executor thread only
+ if (!isExecutorThread()) {
+ throw new IllegalStateException("Must be called from within the executor thread!"); //$NON-NLS-1$
+ }
+
+ BlockingQueue<Runnable> queue = getQueue();
+
+ // If the work queue is empty, there is nothing to do
+ if (!queue.isEmpty()) {
+ // Work queue not empty, check if we reached the maximum nesting
+ // depth
+ if (currentNestingDepth.get() >= getMaxDepth()) {
+ throw new IllegalStateException("Maximum nesting depth exceeded!"); //$NON-NLS-1$
+ }
+
+ // Get the next work item to do
+ Runnable runnable = null;
+ try {
+ // Double check that the queue is not empty, we desire to
+ // avoid
+ // blocking here!
+ if (!queue.isEmpty()) {
+ runnable = queue.take();
+ }
+ } catch (InterruptedException e) { /* ignored on purpose */ }
+
+ if (runnable != null) {
+ // Increase the nesting depth
+ currentNestingDepth.incrementAndGet();
+ try {
+ // Execute the runnable
+ runnable.run();
+ } finally {
+ // Decrease nesting depth
+ currentNestingDepth.decrementAndGet();
+ }
+ }
+ }
+
+ return !queue.isEmpty();
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.concurrent.ThreadPoolExecutor#afterExecute(java.lang.Runnable, java.lang.Throwable)
+ */
+ @Override
+ protected void afterExecute(Runnable r, Throwable t) {
+ super.afterExecute(r, t);
+ if (t != null)
+ logException(t);
+ }
+ }
+
+ // Internal reference to the one shot thread factory instance
+ private SingleThreadThreadFactory threadFactory;
+
+ /**
+ * Constructor.
+ */
+ public SingleThreadedExecutorService() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.core.concurrent.executors.AbstractDelegatingExecutorService#createExecutorServiceDelegate()
+ */
+ @Override
+ protected ExecutorService createExecutorServiceDelegate() {
+ threadFactory = new SingleThreadThreadFactory(getThreadPoolNamePrefix());
+ return new SingleThreadedExecutor(threadFactory);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.core.concurrent.interfaces.ISingleThreadedExecutor#isExecutorThread()
+ */
+ public final boolean isExecutorThread() {
+ return isExecutorThread(Thread.currentThread());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.core.concurrent.interfaces.ISingleThreadedExecutor#isExecutorThread(java.lang.Thread)
+ */
+ public final boolean isExecutorThread(Thread thread) {
+ if (thread != null && threadFactory != null) {
+ return thread.equals(threadFactory.getThread());
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.core.concurrent.interfaces.INestableExecutor#getMaxDepth()
+ */
+ public int getMaxDepth() {
+ if (!(getExecutorServiceDelegate() instanceof INestableExecutor)) {
+ throw new UnsupportedOperationException("Executor service delegate must implement INestableExecutor"); //$NON-NLS-1$
+ }
+ return ((INestableExecutor) getExecutorServiceDelegate()).getMaxDepth();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.core.concurrent.interfaces.INestableExecutor#readAndExecute()
+ */
+ public boolean readAndExecute() {
+ if (!(getExecutorServiceDelegate() instanceof INestableExecutor)) {
+ throw new UnsupportedOperationException("Executor service delegate must implement INestableExecutor"); //$NON-NLS-1$
+ }
+ return ((INestableExecutor) getExecutorServiceDelegate()).readAndExecute();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/factories/SingleThreadThreadFactory.java b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/factories/SingleThreadThreadFactory.java
new file mode 100644
index 000000000..a80ac0a36
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/factories/SingleThreadThreadFactory.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * 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.concurrent.factories;
+
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.eclipse.core.runtime.Assert;
+
+/**
+ * A thread factory implementation creating a single thread only.
+ */
+public class SingleThreadThreadFactory implements ThreadFactory {
+ private final ThreadGroup threadGroup;
+ private final String threadName;
+ private Thread thread;
+
+ private final AtomicInteger threadNumber = new AtomicInteger(1);
+
+ /**
+ * Constructor.
+ *
+ * @param namePrefix
+ * The name prefix to name the created threads. Must not be
+ * <code>null</code>.
+ */
+ public SingleThreadThreadFactory(String namePrefix) {
+ Assert.isNotNull(namePrefix);
+
+ // Determine the thread group. Use the security manager if available.
+ this.threadGroup = (System.getSecurityManager() != null) ? System.getSecurityManager().getThreadGroup() : Thread.currentThread().getThreadGroup();
+ // Set the thread name prefix
+ this.threadName = ("".equals(namePrefix.trim()) ? "Executor" : namePrefix) + " - " + threadNumber.getAndIncrement(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.concurrent.ThreadFactory#newThread(java.lang.Runnable)
+ */
+ public Thread newThread(Runnable r) {
+ // The thread can be created on once. If called a second time,
+ // this factory cannot create any additional threads.
+ if (thread != null) return null;
+
+ // Create the thread with the desired name and the current thread number
+ thread = new Thread(threadGroup, r, threadName);
+ thread.setDaemon(false);
+ thread.setPriority(Thread.NORM_PRIORITY);
+
+ // Return the thread
+ return thread;
+ }
+
+ /**
+ * Returns the single created thread instance or <code>null</code> if
+ * {@link #newThread(Runnable)} have not been called yet.
+ *
+ * @return The single created thread instance or <code>null</code>.
+ */
+ public Thread getThread() {
+ return thread;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/interfaces/IExecutor.java b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/interfaces/IExecutor.java
new file mode 100644
index 000000000..eb48fd30d
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/interfaces/IExecutor.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * 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.concurrent.interfaces;
+
+import java.util.concurrent.Executor;
+
+import org.eclipse.tm.te.core.interfaces.IExecutableExtension;
+
+/**
+ * Execution interface declaration.
+ */
+public interface IExecutor extends Executor, IExecutableExtension {
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/interfaces/IExecutorUtilDelegate.java b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/interfaces/IExecutorUtilDelegate.java
new file mode 100644
index 000000000..2969a382f
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/interfaces/IExecutorUtilDelegate.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * 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.concurrent.interfaces;
+
+import org.eclipse.tm.te.core.interfaces.IExecutableExtension;
+
+/**
+ * Executor utility delegate interface declaration.
+ */
+public interface IExecutorUtilDelegate extends IExecutableExtension {
+
+ /**
+ * Returns if or if not the current thread is an executor thread handled by
+ * this executor utility wait and dispatch delegate.
+ *
+ * @return <code>True</code> if the current thread is handled,
+ * <code>false</code> otherwise.
+ */
+ public boolean isHandledExecutorThread();
+
+ /**
+ * Reads an event from the handled executors event queue, dispatches it
+ * appropriately, and returns <code>true</code> if there is potentially more
+ * work to do, or <code>false</code> if the caller can sleep until another
+ * event is placed on the event queue.
+ *
+ * @return <code>True</code> if there is potentially more work to do,
+ * <code>false</code> otherwise.
+ */
+ public boolean readAndDispatch();
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/interfaces/INestableExecutor.java b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/interfaces/INestableExecutor.java
new file mode 100644
index 000000000..55eb0c1ae
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/interfaces/INestableExecutor.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * 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.concurrent.interfaces;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Nestable execution interface declaration.
+ */
+public interface INestableExecutor extends Executor {
+
+ /**
+ * Returns the maximum allowed nesting depth. If this methods returns an
+ * integer value <= 0, nesting is disabled.
+ *
+ * @return The maximum allowed nesting depth or 0 to disable nesting.
+ */
+ public int getMaxDepth();
+
+ /**
+ * Reads the next command from the task queue and execute it if the maximum
+ * allowed nesting depth has not been exceeded. If the maximum nesting depth
+ * has been reached, the method will throw an {@link IllegalStateException}.
+ *
+ * @return <code>True</code> if there is potentially more work to do, or
+ * <code>false</code> if the caller can sleep until another event is
+ * placed on the task queue.
+ */
+ public boolean readAndExecute();
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/interfaces/ISingleThreadedExecutor.java b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/interfaces/ISingleThreadedExecutor.java
new file mode 100644
index 000000000..1d9269c9e
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/interfaces/ISingleThreadedExecutor.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * 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.concurrent.interfaces;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Single threaded execution service interface declaration.
+ */
+public interface ISingleThreadedExecutor extends Executor {
+
+ /**
+ * Returns if or if not the current thread is identical to the executor
+ * thread.
+ *
+ * @return <code>True</code> if the current thread is the executor thread,
+ * <code>false</code> otherwise.
+ */
+ public boolean isExecutorThread();
+
+ /**
+ * Returns if or if not the given thread is identical to the executor
+ * thread.
+ *
+ * @param thread
+ * The thread or <code>null</code>.
+ * @return <code>True</code> if the current thread is the executor thread,
+ * <code>false</code> otherwise.
+ */
+ public boolean isExecutorThread(Thread thread);
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/nls/Messages.java b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/nls/Messages.java
index 53ce81a5d..a43ba20e5 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/nls/Messages.java
+++ b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/nls/Messages.java
@@ -29,4 +29,5 @@ public class Messages extends NLS {
// **** Declare externalized string id's down here *****
+ public static String AbstractDelegatingExecutorService_unhandledException;
}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/nls/Messages.properties
index 3017309b8..58d39fc78 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/nls/Messages.properties
+++ b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/nls/Messages.properties
@@ -4,3 +4,5 @@
#
PendingOperationModelNode_label=Pending...
+
+AbstractDelegatingExecutorService_unhandledException=Unhandled exception caught in executor: {0}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/util/ExecutorsUtil.java b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/util/ExecutorsUtil.java
new file mode 100644
index 000000000..fc2011b12
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core.concurrent/src/org/eclipse/tm/te/core/concurrent/util/ExecutorsUtil.java
@@ -0,0 +1,302 @@
+/*******************************************************************************
+ * 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.concurrent.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.tm.te.core.concurrent.Executors;
+import org.eclipse.tm.te.core.concurrent.interfaces.IExecutorUtilDelegate;
+import org.eclipse.tm.te.core.concurrent.interfaces.INestableExecutor;
+import org.eclipse.tm.te.core.concurrent.interfaces.ISingleThreadedExecutor;
+import org.eclipse.tm.te.core.extensions.AbstractExtensionPointManager;
+import org.eclipse.tm.te.core.extensions.ExecutableExtensionProxy;
+import org.eclipse.tm.te.core.interfaces.IConditionTester;
+
+
+/**
+ * Utility class to provide helper methods to execute tasks at
+ * a executor service asynchronous and synchronous.
+ */
+public final class ExecutorsUtil {
+
+ /**
+ * Execution utility wait and dispatch utility extension point manager.
+ */
+ protected static class ExecutorUtilDelegateExtensionPointManager extends AbstractExtensionPointManager<IExecutorUtilDelegate> {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.core.extensions.AbstractExtensionPointManager#getExtensionPointId()
+ */
+ @Override
+ protected String getExtensionPointId() {
+ return "org.eclipse.tm.te.core.concurrent.executorUtilDelegates"; //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.core.extensions.AbstractExtensionPointManager#getConfigurationElementName()
+ */
+ @Override
+ protected String getConfigurationElementName() {
+ return "executorUtilDelegate"; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the list of all contributed executor utility delegates.
+ *
+ * @return The list of contributed executor utility delegates, or an
+ * empty array.
+ */
+ public IExecutorUtilDelegate[] getExecutorUtilDelegates() {
+ List<IExecutorUtilDelegate> contributions = new ArrayList<IExecutorUtilDelegate>();
+ Collection<ExecutableExtensionProxy<IExecutorUtilDelegate>> proxies = getExtensions().values();
+ for (ExecutableExtensionProxy<IExecutorUtilDelegate> proxy : proxies) {
+ if (proxy.getInstance() != null&& !contributions.contains(proxy.getInstance())) {
+ contributions.add(proxy.getInstance());
+ }
+ }
+
+ return contributions.toArray(new IExecutorUtilDelegate[contributions.size()]);
+ }
+
+ /**
+ * Returns the executor utility delegate identified by its unique id. If
+ * no executor utility delegate with the specified id is registered,
+ * <code>null</code> is returned.
+ *
+ * @param id
+ * The unique id of the executor utility delegate. Must not
+ * be <code>null</code>
+ * @param newInstance
+ * Specify <code>true</code> to get a new executor utility
+ * delegate instance, <code>false</code> otherwise.
+ *
+ * @return The executor instance or <code>null</code>.
+ */
+ public IExecutorUtilDelegate getExecutorUtilDelegate(String id, boolean newInstance) {
+ Assert.isNotNull(id);
+
+ IExecutorUtilDelegate executorUtilDelegate = null;
+ if (getExtensions().containsKey(id)) {
+ ExecutableExtensionProxy<IExecutorUtilDelegate> proxy = getExtensions().get(id);
+ // Get the extension instance
+ executorUtilDelegate = newInstance ? proxy.newInstance() : proxy.getInstance();
+ }
+
+ return executorUtilDelegate;
+ }
+ }
+
+ // Reference to the executor service extension point manager
+ private final static ExecutorUtilDelegateExtensionPointManager EXTENSION_POINT_MANAGER = new ExecutorUtilDelegateExtensionPointManager();
+
+ // Reference to the used executor service.
+ private final static ISingleThreadedExecutor EXECUTOR;
+ // Reference to the used UI executor service (might be null if not available)
+ private final static ISingleThreadedExecutor UI_EXECUTOR;
+
+ /**
+ * Static constructor.
+ */
+ static {
+ EXECUTOR = (ISingleThreadedExecutor) Executors.getSharedExecutor("org.eclipse.tm.te.core.concurrent.executors.singleThreaded"); //$NON-NLS-1$
+ Assert.isNotNull(EXECUTOR);
+ UI_EXECUTOR = (ISingleThreadedExecutor) Executors.getSharedExecutor("org.eclipse.tm.ui.swt.executors.display"); //$NON-NLS-1$
+ }
+
+ /**
+ * Shutdown the executor service used.
+ */
+ public static void shutdown() {
+ if (EXECUTOR instanceof ExecutorService) {
+ ((ExecutorService) EXECUTOR).shutdown();
+ }
+ if (UI_EXECUTOR instanceof ExecutorService) {
+ ((ExecutorService) UI_EXECUTOR).shutdown();
+ }
+ }
+
+ /**
+ * Checks if the current thread is identical with the executor thread.
+ *
+ * @return <code>True</code> if the current thread is the executor thread,
+ * <code>false</code> otherwise.
+ */
+ public static boolean isExecutorThread() {
+ return EXECUTOR != null ? EXECUTOR.isExecutorThread() : false;
+ }
+
+ /**
+ * Checks if the current thread is identical with the UI executor thread.
+ *
+ * @return <code>True</code> if the current thread is the UI executor
+ * thread, <code>false</code> otherwise.
+ */
+ public static boolean isUIExecutorThread() {
+ return UI_EXECUTOR != null ? UI_EXECUTOR.isExecutorThread() : false;
+ }
+
+ /**
+ * Schedule the given {@link Runnable} for invocation within the used
+ * executor thread.
+ *
+ * @param runnable
+ * The <code>java.lang.Runnable</code> to execute within the
+ * executor thread.
+ */
+ public static void execute(Runnable runnable) {
+ if (runnable != null) {
+ if (EXECUTOR instanceof ExecutorService) {
+ if (!((ExecutorService) EXECUTOR).isShutdown()
+ && !((ExecutorService) EXECUTOR).isTerminated()) {
+ EXECUTOR.execute(runnable);
+ }
+ } else {
+ if (EXECUTOR != null) {
+ EXECUTOR.execute(runnable);
+ }
+ }
+ }
+ }
+
+ /**
+ * Schedule the given {@link Runnable} to run the current workbench display
+ * thread.
+ *
+ * @param runnable
+ * The runnable to execute.
+ */
+ public static void executeInUI(Runnable runnable) {
+ if (runnable != null) {
+ if (UI_EXECUTOR instanceof ExecutorService) {
+ if (!((ExecutorService) UI_EXECUTOR).isShutdown()
+ && !((ExecutorService) UI_EXECUTOR).isTerminated()) {
+ UI_EXECUTOR.execute(runnable);
+ }
+ } else {
+ if (UI_EXECUTOR != null) {
+ UI_EXECUTOR.execute(runnable);
+ }
+ }
+ }
+ }
+
+ /**
+ * Waits either for the given condition tester to signal that the condition,
+ * the caller want's to wait for, has been completely fulfilled or till the
+ * timeout runs out. If the specified condition tester is <code>null</code>,
+ * the method will always wait till the timeout occurs. In case
+ * <code>timeout == 0</code> and <code>conditionTester == null</code>, the
+ * method returns immediately with the return value <code>true</code>!
+ *
+ * @param timeout
+ * The timeout to wait in milliseconds. <code>0</code> means
+ * infinite wait time!
+ * @param conditionTester
+ * The condition tester to use for checking the interrupt
+ * condition.
+ *
+ * @return <code>false</code> if the exit reason if that the waiting
+ * condition has been fulfilled, <code>true</code> if the exit
+ * reason is the timeout!
+ */
+ public static boolean waitAndExecute(final long timeout,
+ final IConditionTester conditionTester) {
+ // both parameter are null, return immediately!
+ if (conditionTester == null && timeout == 0)
+ return true;
+
+ // we assume that the exit reason will be the timeout
+ boolean exitReason = true;
+
+ // Remember the executors utility delegate down the road. As long
+ // we don't leave the waitAndExecute method, the thread cannot change.
+ IExecutorUtilDelegate lastDelegate = null;
+
+ // Remember the start time to calculate the timeout
+ final long startTime = System.currentTimeMillis();
+ // keep going till either the condition tester or the timeout will
+ // break the loop!
+ while (true) {
+ if (conditionTester != null && conditionTester.isConditionFulfilled()) {
+ // the exit reason is the condition tester!
+ exitReason = false;
+ break;
+ }
+ if (timeout != 0 && ((System.currentTimeMillis() - startTime) >= timeout)) {
+ // timeout occurred, just break the loop
+ break;
+ }
+ // none of the break conditions are fulfilled, so wait a little bit
+ // before testing again.
+ if (isExecutorThread()) {
+ // We are in the executor thread. Keep the command dispatching running.
+ if (EXECUTOR instanceof INestableExecutor) {
+ ((INestableExecutor) EXECUTOR).readAndExecute();
+ Thread.yield();
+ } else {
+ throw new IllegalStateException("waitAndExecute called from within a non-nestable executor service!"); //$NON-NLS-1$
+ }
+ }
+ // Check if we are in the UI executor thread
+ else if (isUIExecutorThread()) {
+ // We are in the executor thread. Keep the command dispatching
+ // running.
+ if (UI_EXECUTOR instanceof INestableExecutor) {
+ ((INestableExecutor) UI_EXECUTOR).readAndExecute();
+ Thread.yield();
+ } else {
+ throw new IllegalStateException("waitAndExecute called from within a non-nestable UI executor service!"); //$NON-NLS-1$
+ }
+ }
+ // Check if we have a delegate contribution which is handling
+ // the current thread.
+ else {
+ boolean foundHandlingDelegate = false;
+
+ if (lastDelegate == null) {
+ // Get all registered delegates
+ IExecutorUtilDelegate[] delegates = EXTENSION_POINT_MANAGER.getExecutorUtilDelegates();
+ for (IExecutorUtilDelegate delegate : delegates) {
+ // Does the delegate handles the current thread?
+ if (delegate.isHandledExecutorThread()) {
+ foundHandlingDelegate = true;
+ lastDelegate = delegate;
+ // Read and dispatch one event
+ delegate.readAndDispatch();
+ break;
+ }
+ }
+ } else {
+ foundHandlingDelegate = true;
+ // Read and dispatch one event
+ lastDelegate.readAndDispatch();
+ }
+
+ if (!foundHandlingDelegate) {
+ // Not in any executor thread, put the current thread to sleep
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) { /* ignored on purpose */ }
+ }
+ }
+ }
+
+ // give the condition tester the chance to cleanup
+ if (conditionTester != null) {
+ conditionTester.cleanup();
+ }
+
+ return exitReason;
+ }
+}

Back to the top