From 6b0a5f2fc88f38fcc18155ba77674fe15eefc6aa Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 16 May 2008 21:58:38 +0000 Subject: [PATCH] [231156] - [concurrency][view model] Improve performance of the executor used in View model. --- .../ui/concurrent/SimpleDisplayExecutor.java | 74 +++++++++++++++++++ .../dd/dsf/ui/viewmodel/AbstractVMNode.java | 5 +- .../dsf/ui/viewmodel/AbstractVMProvider.java | 10 +-- 3 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/SimpleDisplayExecutor.java diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/SimpleDisplayExecutor.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/SimpleDisplayExecutor.java new file mode 100644 index 00000000000..77e9f1c0dcf --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/SimpleDisplayExecutor.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2008 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.Map; +import java.util.concurrent.Executor; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.widgets.Display; + +/** + * A simple executor which uses the display thread to run the submitted + * runnables. It only implements the {@link Executor}, and NOT the more + * sophisticated {@link DsfExecutor} (which extends + * {@link java.util.concurrent.ScheduledExecutorService}). However, this + * implementation is much more efficient than DisplayDsfExecutor as it does + * not use a separate thread or maintain its own queue. + */ +public class SimpleDisplayExecutor implements Executor{ + /** + * Internal mapping of display objects to executors. + */ + private static Map fExecutors = Collections.synchronizedMap( new HashMap() ); + + /** + * Factory method for display executors. + * @param display Display to create an executor for. + * @return The new (or re-used) executor. + */ + public static SimpleDisplayExecutor getSimpleDisplayExecutor(Display display) { + synchronized (fExecutors) { + SimpleDisplayExecutor executor = fExecutors.get(display); + if (executor == null) { + executor = new SimpleDisplayExecutor(display); + fExecutors.put(display, executor); + } + return executor; + } + } + + /** + * The display class used by this executor to execute the submitted runnables. + */ + private final Display fDisplay; + + private SimpleDisplayExecutor(Display display) { + fDisplay = display; + } + + public void execute(Runnable command) { + try { + fDisplay.asyncExec(command); + } catch (SWTException e) { + if (e.code == SWT.ERROR_DEVICE_DISPOSED) { + throw new RejectedExecutionException("Display " + fDisplay + " is disposed", e); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + throw e; + } + } + } +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java index f52dc404d36..9e6227e8e75 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java @@ -10,10 +10,11 @@ *******************************************************************************/ package org.eclipse.dd.dsf.ui.viewmodel; +import java.util.concurrent.Executor; + import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; @@ -39,7 +40,7 @@ abstract public class AbstractVMNode implements IVMNode { /** * Accessor method for sub-classes. */ - protected DsfExecutor getExecutor() { + protected Executor getExecutor() { return fProvider.getExecutor(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java index 1ff99595544..31031d7596e 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -17,13 +17,13 @@ import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import java.util.Map; +import java.util.concurrent.Executor; import java.util.concurrent.RejectedExecutionException; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.ui.concurrent.DisplayDsfExecutor; +import org.eclipse.dd.dsf.ui.concurrent.SimpleDisplayExecutor; import org.eclipse.dd.dsf.ui.concurrent.ViewerDataRequestMonitor; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; @@ -75,7 +75,7 @@ abstract public class AbstractVMProvider implements IVMProvider * IPresentationContext object (bug 213629). For now utilize the * assumption that there is only one display. */ - private final DsfExecutor fExecutor = DisplayDsfExecutor.getDisplayDsfExecutor(Display.getDefault()); + private final Executor fExecutor = SimpleDisplayExecutor.getSimpleDisplayExecutor(Display.getDefault()); /** * The element content provider implementation that this provider delegates to. @@ -527,12 +527,11 @@ abstract public class AbstractVMProvider implements IVMProvider * need to worry about the executor throwing the {@link RejectedExecutionException} * exception. */ - public DsfExecutor getExecutor() { + public Executor getExecutor() { return fExecutor; } public IModelProxy createModelProxy(Object element, IPresentationContext context) { - assert getExecutor().isInExecutorThread(); // Iterate through the current active proxies to try to find a proxy with the same // element and re-use it if found. At the same time purge proxies that are no longer @@ -568,7 +567,6 @@ abstract public class AbstractVMProvider implements IVMProvider * @see IColumnPresentationFactory#createColumnPresentation(IPresentationContext, Object) */ public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) { - assert fExecutor.isInExecutorThread(); return null; }