1
0
Fork 0
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:
Pawel Piech 2007-12-20 19:20:09 +00:00
parent 2b3d31bb31
commit 0ce3cca4da
4 changed files with 267 additions and 142 deletions

View file

@ -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();
}
}

View file

@ -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));
}
}

View file

@ -1,2 +1,3 @@
org.eclipse.dd.dsf/debug = false
org.eclipse.dd.dsf/debug/executor = false
org.eclipse.dd.dsf/debug/executorName =

View file

@ -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();
}