Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1020)

Unified Diff: editor/tools/plugins/com.google.dart.tools.core/src/com/google/dart/tools/core/internal/model/delta/DeltaProcessingState.java

Issue 11364134: Merge libv1. (Closed) Base URL: https://dart.googlecode.com/svn/experimental/lib_v2/dart
Patch Set: Reupload due to error Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: editor/tools/plugins/com.google.dart.tools.core/src/com/google/dart/tools/core/internal/model/delta/DeltaProcessingState.java
diff --git a/editor/tools/plugins/com.google.dart.tools.core/src/com/google/dart/tools/core/internal/model/delta/DeltaProcessingState.java b/editor/tools/plugins/com.google.dart.tools.core/src/com/google/dart/tools/core/internal/model/delta/DeltaProcessingState.java
index 6f90e67f143e96f5d6ff7c36a0b203c02481e33d..979725bf12dbabf269d69301c87494e6d2736572 100644
--- a/editor/tools/plugins/com.google.dart.tools.core/src/com/google/dart/tools/core/internal/model/delta/DeltaProcessingState.java
+++ b/editor/tools/plugins/com.google.dart.tools.core/src/com/google/dart/tools/core/internal/model/delta/DeltaProcessingState.java
@@ -15,26 +15,26 @@ package com.google.dart.tools.core.internal.model.delta;
import com.google.dart.tools.core.DartCore;
import com.google.dart.tools.core.internal.model.DartModelManager;
-import com.google.dart.tools.core.model.DartElement;
-import com.google.dart.tools.core.model.DartModelException;
-import com.google.dart.tools.core.model.DartProject;
import com.google.dart.tools.core.model.ElementChangedListener;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.ISafeRunnable;
-import org.eclipse.core.runtime.SafeRunner;
-import java.util.HashSet;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
/**
* Instances of the class <code>DeltaProcessingState</code> keep the global states used during Dart
* element delta processing.
*/
public class DeltaProcessingState implements IResourceChangeListener {
-
/**
* Collection of listeners for Dart element deltas. These listeners are notified from
* {@link DeltaProcessor#fire(com.google.dart.tools.core.model.DartElementDelta, int)}.
@@ -44,41 +44,28 @@ public class DeltaProcessingState implements IResourceChangeListener {
private final static int INIT_ELEMENT_CHANGED_LISTENER_ARRAY_SIZE = 8;
public ElementChangedListener[] elementChangedListeners = new ElementChangedListener[INIT_ELEMENT_CHANGED_LISTENER_ARRAY_SIZE];
public int[] elementChangedListenerMasks = new int[INIT_ELEMENT_CHANGED_LISTENER_ARRAY_SIZE];
- public int elementChangedListenerCount = 0;
- /**
- * Collection of pre Dart resource change listeners. These listeners are notified when
- * {@link #resourceChanged(IResourceChangeEvent)} is called, just before when the
- * {@link DeltaProcessor} is called.
- * <p>
- * A NPE occurs when the two arrays are different sizes, thus we enforce this with a private int.
- */
- private final static int INIT_PRE_RESOURCE_CHANGE_ARRAY_SIZE = 1;
- private IResourceChangeListener[] preResourceChangeListeners = new IResourceChangeListener[INIT_PRE_RESOURCE_CHANGE_ARRAY_SIZE];
- private int[] preResourceChangeEventMasks = new int[INIT_PRE_RESOURCE_CHANGE_ARRAY_SIZE];
- private int preResourceChangeListenerCount = 0;
+ public int elementChangedListenerCount = 0;
/**
* The delta processor for the current thread.
*/
private ThreadLocal<DeltaProcessor> deltaProcessors = new ThreadLocal<DeltaProcessor>();
-// /**
-// * Threads that are currently running initializeRoots()
-// */
-// private Set<Thread> initializingThreads = Collections.synchronizedSet(new HashSet<Thread>());
+ private ExecutorService threadPool;
/**
- * Workaround for bug 15168 circular errors not reported This is a cache of the projects before
- * any project addition/deletion has started.
+ * Create a DeltaProcessingState instance. This constructor call should be paired with a call to
+ * dispose().
*/
- private HashSet<String> dartProjectNamesCache;
+ public DeltaProcessingState() {
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(
+ this,
+ IResourceChangeEvent.POST_CHANGE | IResourceChangeEvent.PRE_DELETE
+ | IResourceChangeEvent.PRE_CLOSE);
- /**
- * A list of DartElement used as a scope for external archives refresh during POST_CHANGE. This is
- * null if no refresh is needed.
- */
- private HashSet<DartElement> externalElementsToRefresh;
+ threadPool = Executors.newSingleThreadExecutor();
+ }
/**
* Need to clone defensively the listener information, in case some listener is reacting to some
@@ -127,67 +114,13 @@ public class DeltaProcessingState implements IResourceChangeListener {
elementChangedListenerCount++;
}
- /**
- * Adds the given element to the list of elements used as a scope for external jars refresh.
- */
- public synchronized void addForRefresh(DartElement externalElement) {
- if (externalElementsToRefresh == null) {
- externalElementsToRefresh = new HashSet<DartElement>();
- }
- externalElementsToRefresh.add(externalElement);
- }
+ public void dispose() {
+ ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
- /**
- * Adds a pre-resource change listener onto this class. The listeners are called from
- * {@link DeltaProcessingState#resourceChanged(IResourceChangeEvent)}.
- *
- * @see #removePreResourceChangedListener(IResourceChangeListener)
- */
- public synchronized void addPreResourceChangedListener(IResourceChangeListener listener,
- int eventMask) {
- for (int i = 0; i < preResourceChangeListenerCount; i++) {
- if (preResourceChangeListeners[i] == listener) {
- preResourceChangeEventMasks[i] |= eventMask;
- return;
- }
- }
- // may need to grow, no need to clone, since iterators will have cached
- // original arrays and max boundary and we only add to the end.
- int length;
- if ((length = preResourceChangeListeners.length) == preResourceChangeListenerCount) {
- System.arraycopy(
- preResourceChangeListeners,
- 0,
- preResourceChangeListeners = new IResourceChangeListener[length * 2],
- 0,
- length);
- System.arraycopy(
- preResourceChangeEventMasks,
- 0,
- preResourceChangeEventMasks = new int[length * 2],
- 0,
- length);
- }
- preResourceChangeListeners[preResourceChangeListenerCount] = listener;
- preResourceChangeEventMasks[preResourceChangeListenerCount] = eventMask;
- preResourceChangeListenerCount++;
- }
-
- public void doNotUse() {
- // reset the delta processor of the current thread to avoid to keep it in
- // memory
- // https://bugs.eclipse.org/bugs/show_bug.cgi?id=269476
- deltaProcessors.set(null);
- }
-
- public DartProject findDartProject(String name) {
- if (getOldDartProjectNames().contains(name)) {
- return DartModelManager.getInstance().getDartModel().getDartProject(name);
- }
- return null;
+ threadPool.shutdown();
}
- public DeltaProcessor getDeltaProcessor() {
+ public IDeltaProcessor getDeltaProcessor() {
DeltaProcessor deltaProcessor = deltaProcessors.get();
if (deltaProcessor != null) {
return deltaProcessor;
@@ -198,24 +131,26 @@ public class DeltaProcessingState implements IResourceChangeListener {
}
/**
- * Workaround for bug 15168 circular errors not reported Returns the list of Dart projects before
- * resource delta processing has started.
+ * Block until the delta processor has processed all outstanding changes in the queue, or until
+ * timeoutMillis has been reached.
+ *
+ * @param timeoutMillis the maximum number of milliseconds to wait
+ * @throws InterruptedException
*/
- public synchronized HashSet<String> getOldDartProjectNames() {
- if (dartProjectNamesCache == null) {
- HashSet<String> result = new HashSet<String>();
- DartProject[] projects;
- try {
- projects = DartModelManager.getInstance().getDartModel().getDartProjects();
- for (DartProject dartProject : projects) {
- result.add(dartProject.getElementName());
- }
- } catch (DartModelException dme) {
- return dartProjectNamesCache;
+ public void processAllChanges(long timeoutMillis) throws InterruptedException {
+ final CountDownLatch latch = new CountDownLatch(1);
+
+ // We put a task in the queue and wait for it to be run. It is a single-threaded, non
+ // re-ordering queue, so we know that when our task has run, the other tasks in the queue
+ // already finished.
+ threadPool.execute(new Runnable() {
+ @Override
+ public void run() {
+ latch.countDown();
}
- return dartProjectNamesCache = result;
- }
- return dartProjectNamesCache;
+ });
+
+ latch.await(timeoutMillis, TimeUnit.MILLISECONDS);
}
/**
@@ -253,54 +188,6 @@ public class DeltaProcessingState implements IResourceChangeListener {
}
}
- public synchronized HashSet<DartElement> removeExternalElementsToRefresh() {
- HashSet<DartElement> result = externalElementsToRefresh;
- externalElementsToRefresh = null;
- return result;
- }
-
- /**
- * Removes the passed listener from the {@link #preResourceChangeListeners} array.
- *
- * @see #addPreResourceChangedListener(IResourceChangeListener, int)
- */
- public synchronized void removePreResourceChangedListener(IResourceChangeListener listener) {
- for (int i = 0; i < preResourceChangeListenerCount; i++) {
- if (preResourceChangeListeners[i] == listener) {
- // need to clone defensively since we might be in the middle of listener
- // notifications (#fire)
- int length = preResourceChangeListeners.length;
- IResourceChangeListener[] newListeners = new IResourceChangeListener[length];
- int[] newEventMasks = new int[length];
- System.arraycopy(preResourceChangeListeners, 0, newListeners, 0, i);
- System.arraycopy(preResourceChangeEventMasks, 0, newEventMasks, 0, i);
-
- // copy trailing listeners
- int trailingLength = preResourceChangeListenerCount - i - 1;
- if (trailingLength > 0) {
- System.arraycopy(preResourceChangeListeners, i + 1, newListeners, i, trailingLength);
- System.arraycopy(preResourceChangeEventMasks, i + 1, newEventMasks, i, trailingLength);
- }
-
- // update manager listener state (#fire need to iterate over original
- // listeners through a local variable to hold onto
- // the original ones)
- preResourceChangeListeners = newListeners;
- preResourceChangeEventMasks = newEventMasks;
- preResourceChangeListenerCount--;
- return;
- }
- }
- }
-
- /**
- * Calling this method resets the project names map cache by setting
- * {@link #dartProjectNamesCache} to <code>null</code>.
- */
- public synchronized void resetOldDartProjectNames() {
- dartProjectNamesCache = null;
- }
-
/**
* This is the only method from {@link IResourceChangeListener}, the workspace change listener
* (this), is attached to the workspace in {@link DartModelManager#startup()}, which is called
@@ -312,50 +199,82 @@ public class DeltaProcessingState implements IResourceChangeListener {
*/
@Override
public void resourceChanged(final IResourceChangeEvent event) {
- // for each of the pre-resource change listeners, loop through and notify the listener of the change event
- for (int i = 0; i < preResourceChangeListenerCount; i++) {
- // wrap callbacks with Safe runnable for subsequent listeners to be called
- // when some are causing grief
- final IResourceChangeListener listener = preResourceChangeListeners[i];
- if ((preResourceChangeEventMasks[i] & event.getType()) != 0) {
- SafeRunner.run(new ISafeRunnable() {
- @Override
- public void handleException(Throwable exception) {
- DartCore.logError(
- "Exception occurred in listener of pre Dart resource change notification", exception); //$NON-NLS-1$
+ try {
+ if (event.getDelta() != null) {
+ IResourceDelta[] children = event.getDelta().getAffectedChildren();
+
+ if (children.length > 0) {
+ IProject project = children[0].getResource().getProject();
+
+ if (project.exists() && project.isOpen()) {
+ if (project.hasNature(DartCore.DART_PROJECT_NATURE)) {
+ processEvent(event);
+ }
}
+ }
+ } else {
+ IProject project = event.getResource().getProject();
- @Override
- public void run() throws Exception {
- listener.resourceChanged(event);
+ if (project.exists() && project.isOpen()) {
+ if (project.hasNature(DartCore.DART_PROJECT_NATURE)) {
+ processEvent(event);
}
- });
+ }
}
+ } catch (CoreException e) {
+ DartCore.logError(e);
}
- try {
- if (event.getDelta() != null) {
- IResourceDelta[] children = event.getDelta().getAffectedChildren();
- if (children.length > 0
- && children[0].getResource().getProject().hasNature(DartCore.DART_PROJECT_NATURE)) {
- getDeltaProcessor().resourceChanged(event);
+ }
+
+ private boolean isDeleteEvent(int eventType, DeltaProcessorDelta delta) {
+ if (eventType == IResourceChangeEvent.PRE_DELETE || eventType == IResourceChangeEvent.PRE_CLOSE) {
+ return true;
+ }
+
+ if (delta == null) {
+ return false;
+ } else {
+ return delta.isDeleteEvent();
+ }
+ }
+
+ /**
+ * Given an IResourceChangeEvent, convert its information into a DeltaProcessorDelta object, and
+ * process that information in a separate thread.
+ *
+ * @param event
+ */
+ private void processEvent(IResourceChangeEvent event) {
+ final int eventType = event.getType();
+ final IResource resource = event.getResource();
+ final DeltaProcessorDelta delta = DeltaProcessorDelta.createFrom(event.getDelta());
+
+ // Add the processing work to the end of the thread queue.
+ threadPool.submit(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ DeltaProcessor deltaProcessor = ((DeltaProcessor) getDeltaProcessor());
+
+ deltaProcessor.handleResourceChanged(eventType, resource, delta);
+ } catch (Throwable t) {
+ DartCore.logError(t);
+ } finally {
+ if (eventType == IResourceChangeEvent.POST_CHANGE) {
+ deltaProcessors.set(null);
+ }
}
- } else if (event.getResource().getProject().hasNature(DartCore.DART_PROJECT_NATURE)) {
- getDeltaProcessor().resourceChanged(event);
}
- } catch (CoreException e) {
- //ignore
- } finally {
- // TODO (jerome) see 47631, may want to get rid of following so as to
- // reuse delta processor ?
- if (event.getType() == IResourceChangeEvent.POST_CHANGE) {
- deltaProcessors.set(null);
- } else {
- // If we are going to reuse the delta processor of this thread, don't
- // hang on to state
- // that isn't meant to be reused.
- // https://bugs.eclipse.org/bugs/show_bug.cgi?id=273385
- getDeltaProcessor().overridenEventType = -1;
+ });
+
+ // wait on any delete events
+ if (isDeleteEvent(eventType, delta)) {
+ try {
+ processAllChanges(60 * 1000);
+ } catch (InterruptedException e) {
+
}
}
}
+
}

Powered by Google App Engine
This is Rietveld 408576698