mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-16 13:35:22 +02:00
[213635] Added name to DSF executor.
This commit is contained in:
parent
2b3d31bb31
commit
0ce3cca4da
4 changed files with 267 additions and 142 deletions
|
@ -0,0 +1,232 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 Wind River Systems 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.dd.dsf.ui.concurrent;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.SWTException;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
|
||||
public class DisplayDsfExecutor extends DefaultDsfExecutor
|
||||
{
|
||||
/**
|
||||
* Internal mapping of display objects to executors.
|
||||
*/
|
||||
private static Map<Display, DisplayDsfExecutor> fExecutors = Collections.synchronizedMap( new HashMap<Display, DisplayDsfExecutor>() );
|
||||
|
||||
/**
|
||||
* Factory method for display executors.
|
||||
* @param display Display to create an executor for.
|
||||
* @return The new (or re-used) executor.
|
||||
*/
|
||||
public static DsfExecutor getDisplayDsfExecutor(Display display) {
|
||||
synchronized (fExecutors) {
|
||||
DisplayDsfExecutor executor = fExecutors.get(display);
|
||||
if (executor == null) {
|
||||
executor = new DisplayDsfExecutor(display);
|
||||
fExecutors.put(display, executor);
|
||||
}
|
||||
return executor;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The display class used by this executor to execute the submitted runnables.
|
||||
*/
|
||||
private final Display fDisplay;
|
||||
|
||||
|
||||
private DisplayDsfExecutor(Display display) {
|
||||
super("Display DSF Executor"); //$NON-NLS-1$
|
||||
fDisplay = display;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a callable wrapper, which delegates to the display to perform the
|
||||
* operation. The callable blocks the executor thread while each call
|
||||
* is executed in the display thred.
|
||||
* @param <V> Type used in the callable.
|
||||
* @param callable Callable to wrap.
|
||||
* @return Wrapper callable.
|
||||
*/
|
||||
private <V> Callable<V> createSWTDispatchCallable(final Callable<V> callable) {
|
||||
return new Callable<V>() {
|
||||
@SuppressWarnings("unchecked")
|
||||
public V call() throws Exception {
|
||||
final Object[] v = new Object[1];
|
||||
final Throwable[] e = new Throwable[1];
|
||||
|
||||
try {
|
||||
fDisplay.syncExec(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
v[0] = callable.call();
|
||||
} catch(Throwable exception) {
|
||||
e[0] = exception;
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (SWTException swtException) {
|
||||
if (swtException.code == SWT.ERROR_DEVICE_DISPOSED) {
|
||||
DisplayDsfExecutor.super.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
if(e[0] instanceof RuntimeException)
|
||||
throw (RuntimeException) e[0];
|
||||
else if(e[0] instanceof Exception)
|
||||
throw (Exception) e[0];
|
||||
|
||||
return (V) v[0];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a runnable wrapper, which delegates to the display to perform the
|
||||
* operation. The runnable blocks the executor thread while each call
|
||||
* is executed in the display thred.
|
||||
* @param runnable Runnable to wrap.
|
||||
* @return Wrapper runnable.
|
||||
*/
|
||||
private Runnable createSWTDispatchRunnable(final Runnable runnable) {
|
||||
return new Runnable() {
|
||||
public void run() {
|
||||
final Throwable[] e = new Throwable[1];
|
||||
try {
|
||||
fDisplay.syncExec(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
runnable.run();
|
||||
} catch(Throwable exception) {
|
||||
e[0] = exception;
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (SWTException swtException) {
|
||||
if (swtException.code == SWT.ERROR_DEVICE_DISPOSED) {
|
||||
DisplayDsfExecutor.super.shutdown();
|
||||
}
|
||||
}
|
||||
if(e[0] instanceof RuntimeException)
|
||||
throw (RuntimeException) e[0];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> ScheduledFuture<V> schedule(final Callable<V> callable, long delay, TimeUnit unit) {
|
||||
if (fDisplay.isDisposed()) {
|
||||
if (!super.isShutdown()) super.shutdown();
|
||||
throw new RejectedExecutionException("Display " + fDisplay + " is disposed."); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
return super.schedule(createSWTDispatchCallable(callable), delay, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
|
||||
if (fDisplay.isDisposed()) {
|
||||
if (!super.isShutdown()) super.shutdown();
|
||||
throw new RejectedExecutionException("Display " + fDisplay + " is disposed."); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
return super.schedule(createSWTDispatchRunnable(command), delay, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
|
||||
if (fDisplay.isDisposed()) {
|
||||
if (!super.isShutdown()) super.shutdown();
|
||||
throw new RejectedExecutionException("Display " + fDisplay + " is disposed."); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
return super.scheduleAtFixedRate(createSWTDispatchRunnable(command), initialDelay, period, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
|
||||
if (fDisplay.isDisposed()) {
|
||||
if (!super.isShutdown()) super.shutdown();
|
||||
throw new RejectedExecutionException("Display " + fDisplay + " is disposed."); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
return super.scheduleWithFixedDelay(createSWTDispatchRunnable(command), initialDelay, delay, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Runnable command) {
|
||||
if (fDisplay.isDisposed()) {
|
||||
if (!super.isShutdown()) super.shutdown();
|
||||
throw new RejectedExecutionException("Display " + fDisplay + " is disposed."); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
super.execute(createSWTDispatchRunnable(command));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Future<T> submit(Callable<T> callable) {
|
||||
if (fDisplay.isDisposed()) {
|
||||
if (!super.isShutdown()) super.shutdown();
|
||||
throw new RejectedExecutionException("Display " + fDisplay + " is disposed."); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
return super.submit(createSWTDispatchCallable(callable));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Future<T> submit(Runnable command, T result) {
|
||||
if (fDisplay.isDisposed()) {
|
||||
if (!super.isShutdown()) super.shutdown();
|
||||
throw new RejectedExecutionException("Display " + fDisplay + " is disposed."); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
return super.submit(createSWTDispatchRunnable(command), result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<?> submit(Runnable command) {
|
||||
if (fDisplay.isDisposed()) {
|
||||
if (!super.isShutdown()) super.shutdown();
|
||||
throw new RejectedExecutionException("Display " + fDisplay + " is disposed."); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
return super.submit(createSWTDispatchRunnable(command));
|
||||
}
|
||||
|
||||
/**
|
||||
* Override to prevent clients from shutting down. The executor will be
|
||||
* shut down when the underlying display is discovered to be shut down.
|
||||
*/
|
||||
@Override
|
||||
public void shutdown() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Override to prevent clients from shutting down. The executor will be
|
||||
* shut down when the underlying display is discovered to be shut down.
|
||||
*/
|
||||
@SuppressWarnings({ "cast", "unchecked" })
|
||||
@Override
|
||||
public List<Runnable> shutdownNow() {
|
||||
return (List<Runnable>)Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShutdown() {
|
||||
// TODO Auto-generated method stub
|
||||
return super.isShutdown();
|
||||
}
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 Wind River Systems 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.dd.dsf.ui.concurrent;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
|
||||
public class SWTDispatchDsfExecutor extends DefaultDsfExecutor
|
||||
{
|
||||
|
||||
public SWTDispatchDsfExecutor()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
private <V> Callable<V> createSWTDispatchCallable(final Callable<V> callable)
|
||||
{
|
||||
return new Callable<V>()
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
public V call() throws Exception
|
||||
{
|
||||
final Object[] v = new Object[1];
|
||||
final Throwable[] e = new Throwable[1];
|
||||
|
||||
Display.getDefault().syncExec(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
v[0] = callable.call();
|
||||
}
|
||||
catch(Throwable exception)
|
||||
{
|
||||
e[0] = exception;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(e[0] instanceof RuntimeException)
|
||||
throw (RuntimeException) e[0];
|
||||
else if(e[0] instanceof Exception)
|
||||
throw (Exception) e[0];
|
||||
|
||||
return (V) v[0];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Runnable createSWTDispatchRunnable(final Runnable runnable)
|
||||
{
|
||||
return new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
final Throwable[] e = new Throwable[1];
|
||||
|
||||
Display.getDefault().syncExec(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
runnable.run();
|
||||
}
|
||||
catch(Throwable exception)
|
||||
{
|
||||
e[0] = exception;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(e[0] instanceof RuntimeException)
|
||||
throw (RuntimeException) e[0];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> ScheduledFuture<V> schedule(final Callable<V> callable, long delay,
|
||||
TimeUnit unit) {
|
||||
return super.schedule(createSWTDispatchCallable(callable), delay, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledFuture<?> schedule(Runnable command, long delay,
|
||||
TimeUnit unit) {
|
||||
return super.schedule(createSWTDispatchRunnable(command), delay, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
|
||||
long initialDelay, long period, TimeUnit unit) {
|
||||
return super.scheduleAtFixedRate(createSWTDispatchRunnable(command), initialDelay, period, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
|
||||
long initialDelay, long delay, TimeUnit unit) {
|
||||
return super.scheduleWithFixedDelay(createSWTDispatchRunnable(command), initialDelay, delay, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Runnable command) {
|
||||
super.execute(createSWTDispatchRunnable(command));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Future<T> submit(Callable<T> callable) {
|
||||
return super.submit(createSWTDispatchCallable(callable));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Future<T> submit(Runnable command, T result) {
|
||||
return super.submit(createSWTDispatchRunnable(command), result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<?> submit(Runnable command) {
|
||||
return super.submit(createSWTDispatchRunnable(command));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,2 +1,3 @@
|
|||
org.eclipse.dd.dsf/debug = false
|
||||
org.eclipse.dd.dsf/debug/executor = false
|
||||
org.eclipse.dd.dsf/debug/executorName =
|
||||
|
|
|
@ -36,18 +36,43 @@ import org.eclipse.dd.dsf.DsfPlugin;
|
|||
public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor
|
||||
implements DsfExecutor
|
||||
{
|
||||
/**
|
||||
* Instance counter for DSF executors. Used in the executor's thread name.
|
||||
*/
|
||||
private static int fgInstanceCounter = 0;
|
||||
|
||||
/**
|
||||
* Name of the executor, used in the executor's thread name.
|
||||
*/
|
||||
private String fName;
|
||||
|
||||
/** Thread factory that creates the single thread to be used for this executor */
|
||||
static class DsfThreadFactory implements ThreadFactory {
|
||||
private String fThreadName;
|
||||
DsfThreadFactory(String name) {
|
||||
fThreadName = name;
|
||||
}
|
||||
|
||||
Thread fThread;
|
||||
public Thread newThread(Runnable r) {
|
||||
assert fThread == null; // Should be called only once.
|
||||
fThread = new Thread(new ThreadGroup("DSF Thread Group"), r, "DSF Dispatch Thread", 0); //$NON-NLS-1$//$NON-NLS-2$
|
||||
fThread = new Thread(new ThreadGroup(fThreadName), r, fThreadName, 0);
|
||||
return fThread;
|
||||
}
|
||||
}
|
||||
|
||||
public DefaultDsfExecutor() {
|
||||
super(1, new DsfThreadFactory());
|
||||
this("DSF Executor"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new DSF Executor with the given name.
|
||||
* @param name Name used to create executor's thread.
|
||||
*/
|
||||
public DefaultDsfExecutor(String name) {
|
||||
super(1, new DsfThreadFactory(name + " - " + fgInstanceCounter++)); //$NON-NLS-1$
|
||||
fName = name;
|
||||
|
||||
if(DEBUG_EXECUTOR || ASSERTIONS_ENABLED) {
|
||||
// If tracing, pre-start the dispatch thread, and add it to the map.
|
||||
prestartAllCoreThreads();
|
||||
|
@ -84,10 +109,13 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor
|
|||
// Utilities used for tracing.
|
||||
//
|
||||
static boolean DEBUG_EXECUTOR = false;
|
||||
static String DEBUG_EXECUTOR_NAME = "";
|
||||
static boolean ASSERTIONS_ENABLED = false;
|
||||
static {
|
||||
DEBUG_EXECUTOR = DsfPlugin.DEBUG && "true".equals( //$NON-NLS-1$
|
||||
Platform.getDebugOption("org.eclipse.dd.dsf/debug/executor")); //$NON-NLS-1$
|
||||
DEBUG_EXECUTOR_NAME = DsfPlugin.DEBUG
|
||||
? Platform.getDebugOption("org.eclipse.dd.dsf/debug/executorName") : ""; //$NON-NLS-1$
|
||||
assert (ASSERTIONS_ENABLED = true) == true;
|
||||
}
|
||||
|
||||
|
@ -141,7 +169,7 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor
|
|||
fCurrentlyExecuting = this;
|
||||
|
||||
// Write to console only if tracing is enabled (as opposed to tracing or assertions).
|
||||
if (DEBUG_EXECUTOR) {
|
||||
if (DEBUG_EXECUTOR && ("".equals(DEBUG_EXECUTOR_NAME) || fName.equals(DEBUG_EXECUTOR_NAME))) { //$NON-NLS-1$
|
||||
StringBuilder traceBuilder = new StringBuilder();
|
||||
|
||||
// Record the time
|
||||
|
@ -212,7 +240,9 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor
|
|||
fRunnable = runnable;
|
||||
|
||||
// Check if executable wasn't executed already.
|
||||
if (DEBUG_EXECUTOR && fRunnable instanceof DsfExecutable) {
|
||||
if (fRunnable instanceof DsfExecutable &&
|
||||
DEBUG_EXECUTOR && ("".equals(DEBUG_EXECUTOR_NAME) || fName.equals(DEBUG_EXECUTOR_NAME))) //$NON-NLS-1$
|
||||
{
|
||||
assert !((DsfExecutable)fRunnable).getSubmitted() : "Executable was previously executed."; //$NON-NLS-1$
|
||||
((DsfExecutable)fRunnable).setSubmitted();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue