tmf: Bug 494952: Remove deadlock in Time Chart view
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / views / timechart / TimeChartView.java
index 0501bdf8d4e7c49ca2eb334246aa00c231ec6c0e..28a198ed714d7b8a1f129b92c51b882066cd7220 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2010, 2014 Ericsson
+ * Copyright (c) 2010, 2016 Ericsson
  *
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
@@ -15,6 +15,7 @@ package org.eclipse.tracecompass.tmf.ui.views.timechart;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 
 import org.eclipse.core.resources.IFile;
@@ -29,6 +30,7 @@ import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.resources.ITmfMarker;
 import org.eclipse.tracecompass.tmf.core.signal.TmfEventFilterAppliedSignal;
 import org.eclipse.tracecompass.tmf.core.signal.TmfEventSearchAppliedSignal;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
@@ -75,13 +77,12 @@ public class TimeChartView extends TmfView implements ITimeGraphRangeListener, I
     /** TimeChartView's ID */
     public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.timechart"; //$NON-NLS-1$
 
-    private static final int TIMESTAMP_SCALE = -9;
-
     private final int fDisplayWidth;
     private TimeGraphViewer fViewer;
-    private final ArrayList<TimeChartAnalysisEntry> fTimeAnalysisEntries = new ArrayList<>();
+    private final List<TimeChartAnalysisEntry> fTimeAnalysisEntries = new ArrayList<>();
     private final Map<ITmfTrace, TimeChartDecorationProvider> fDecorationProviders = new HashMap<>();
-    private final ArrayList<DecorateThread> fDecorateThreads = new ArrayList<>();
+    private final List<DecorateThread> fDecorateThreads = new ArrayList<>();
+    private final Map<ITmfTrace, ProcessTraceThread> fProcessTraceThreads = new HashMap<>();
     private long fStartTime = 0;
     private long fStopTime = Long.MAX_VALUE;
     private boolean fRefreshBusy = false;
@@ -110,6 +111,7 @@ public class TimeChartView extends TmfView implements ITimeGraphRangeListener, I
         fViewer.addRangeListener(this);
         fViewer.addSelectionListener(this);
         fViewer.setMinimumItemWidth(1);
+        fViewer.getTimeGraphControl().setBlendSubPixelEvents(true);
 
         IStatusLineManager statusLineManager = getViewSite().getActionBars().getStatusLineManager();
         fViewer.getTimeGraphControl().setStatusLineManager(statusLineManager);
@@ -119,8 +121,7 @@ public class TimeChartView extends TmfView implements ITimeGraphRangeListener, I
             TimeChartAnalysisEntry timeAnalysisEntry = new TimeChartAnalysisEntry(trace, fDisplayWidth * 2);
             fTimeAnalysisEntries.add(timeAnalysisEntry);
             fDecorationProviders.put(trace, new TimeChartDecorationProvider(bookmarksFile));
-            Thread thread = new ProcessTraceThread(timeAnalysisEntry);
-            thread.start();
+            startProcessTraceThread(timeAnalysisEntry);
         }
         fViewer.setInput(fTimeAnalysisEntries.toArray(new TimeChartAnalysisEntry[0]));
 
@@ -131,8 +132,10 @@ public class TimeChartView extends TmfView implements ITimeGraphRangeListener, I
     @Override
     public void dispose() {
         ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
-        for (DecorateThread thread : fDecorateThreads) {
-            thread.cancel();
+        synchronized (fDecorateThreads) {
+            for (DecorateThread thread : fDecorateThreads) {
+                thread.cancel();
+            }
         }
         ColorSettingsManager.removeColorSettingsListener(this);
         super.dispose();
@@ -143,18 +146,50 @@ public class TimeChartView extends TmfView implements ITimeGraphRangeListener, I
         fViewer.setFocus();
     }
 
+    private void startProcessTraceThread(TimeChartAnalysisEntry entry) {
+        synchronized (fProcessTraceThreads) {
+            ProcessTraceThread thread = fProcessTraceThreads.get(entry.getTrace());
+            if (thread != null) {
+                thread.restart();
+            } else {
+                thread = new ProcessTraceThread(entry);
+                fProcessTraceThreads.put(entry.getTrace(), thread);
+                thread.start();
+            }
+        }
+    }
+
     private class ProcessTraceThread extends Thread {
 
         private final TimeChartAnalysisEntry fTimeAnalysisEntry;
+        private boolean fRestart;
 
         public ProcessTraceThread(TimeChartAnalysisEntry timeAnalysisEntry) {
             super("ProcessTraceJob:" + timeAnalysisEntry.getName()); //$NON-NLS-1$
             fTimeAnalysisEntry = timeAnalysisEntry;
         }
 
+        public void restart() {
+            synchronized (fProcessTraceThreads) {
+                fRestart = true;
+            }
+        }
+
         @Override
         public void run() {
-            updateTraceEntry(fTimeAnalysisEntry, Long.MAX_VALUE, 0, Long.MAX_VALUE);
+            while (true) {
+                updateTraceEntry(fTimeAnalysisEntry, Long.MAX_VALUE,
+                        TmfTimestamp.BIG_BANG.toNanos(),
+                        TmfTimestamp.BIG_CRUNCH.toNanos());
+                synchronized (fProcessTraceThreads) {
+                    if (fRestart) {
+                        fRestart = false;
+                    } else {
+                        fProcessTraceThreads.remove(fTimeAnalysisEntry.getTrace());
+                        return;
+                    }
+                }
+            }
         }
     }
 
@@ -235,7 +270,7 @@ public class TimeChartView extends TmfView implements ITimeGraphRangeListener, I
                     return;
                 }
                 fViewer.setInput(fTimeAnalysisEntries.toArray(new TimeChartAnalysisEntry[0]));
-                fViewer.resetStartFinishTime();
+                fViewer.resetStartFinishTime(false);
                 synchronized (fSyncObj) {
                     fRefreshBusy = false;
                     if (fRefreshPending) {
@@ -487,7 +522,7 @@ public class TimeChartView extends TmfView implements ITimeGraphRangeListener, I
                         if (event == null) {
                             break;
                         }
-                        long eventTime = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+                        long eventTime = event.getTimestamp().toNanos();
                         if (eventTime >= timeChartEvent.getTime() && eventTime <= timeChartEvent.getTime() + timeChartEvent.getDuration()) {
                             priority = Math.min(priority, ColorSettingsManager.getColorSettingPriority(event));
                         }
@@ -520,8 +555,8 @@ public class TimeChartView extends TmfView implements ITimeGraphRangeListener, I
         fStartTime = event.getStartTime();
         fStopTime = event.getEndTime();
         itemize(fStartTime, fStopTime);
-        final ITmfTimestamp startTimestamp = new TmfTimestamp(event.getStartTime(), ITmfTimestamp.NANOSECOND_SCALE);
-        final ITmfTimestamp endTimestamp = new TmfTimestamp(event.getEndTime(), ITmfTimestamp.NANOSECOND_SCALE);
+        final ITmfTimestamp startTimestamp = TmfTimestamp.fromNanos(event.getStartTime());
+        final ITmfTimestamp endTimestamp = TmfTimestamp.fromNanos(event.getEndTime());
         TmfTimeRange range = new TmfTimeRange(startTimestamp, endTimestamp);
         broadcast(new TmfWindowRangeUpdatedSignal(this, range));
     }
@@ -541,13 +576,13 @@ public class TimeChartView extends TmfView implements ITimeGraphRangeListener, I
 
     @Override
     public void timeSelected(TimeGraphTimeEvent event) {
-        broadcast(new TmfSelectionRangeUpdatedSignal(this, new TmfTimestamp(event.getBeginTime(), TIMESTAMP_SCALE), new TmfTimestamp(event.getEndTime(), TIMESTAMP_SCALE)));
+        broadcast(new TmfSelectionRangeUpdatedSignal(this, TmfTimestamp.fromNanos(event.getBeginTime()), TmfTimestamp.fromNanos(event.getEndTime())));
     }
 
     @Override
     public void colorSettingsChanged(ColorSetting[] colorSettings) {
-        // Set presentation provider again to trigger re-creation of new color settings which are stored
-        // in the TimeGraphControl class
+        // Set presentation provider again to trigger re-creation of new color
+        // settings which are stored in the TimeGraphControl class
         fViewer.setTimeGraphProvider(fPresentationProvider);
         redecorate();
     }
@@ -557,9 +592,9 @@ public class TimeChartView extends TmfView implements ITimeGraphRangeListener, I
         for (IMarkerDelta delta : event.findMarkerDeltas(IMarker.BOOKMARK, false)) {
             for (TimeChartDecorationProvider provider : fDecorationProviders.values()) {
                 if (delta.getResource().equals(provider.getBookmarksFile())) {
-                    if (delta.getKind() == IResourceDelta.CHANGED && delta.getMarker().getAttribute(IMarker.LOCATION, -1) != -1) {
-                        provider.refreshBookmarks();
-                    } else if (delta.getKind() == IResourceDelta.REMOVED) {
+                    if (delta.getKind() == IResourceDelta.REMOVED ||
+                            delta.getMarker().getAttribute(IMarker.LOCATION, -1) != -1 ||
+                            delta.getMarker().getAttribute(ITmfMarker.MARKER_RANK, (String) null) != null) {
                         provider.refreshBookmarks();
                     }
                 }
@@ -593,8 +628,7 @@ public class TimeChartView extends TmfView implements ITimeGraphRangeListener, I
             timeAnalysisEntry = new TimeChartAnalysisEntry(trace, fDisplayWidth * 2);
             fTimeAnalysisEntries.add(timeAnalysisEntry);
             fDecorationProviders.put(trace, new TimeChartDecorationProvider(bookmarksFile));
-            Thread thread = new ProcessTraceThread(timeAnalysisEntry);
-            thread.start();
+            startProcessTraceThread(timeAnalysisEntry);
         }
         refreshViewer();
     }
@@ -644,9 +678,9 @@ public class TimeChartView extends TmfView implements ITimeGraphRangeListener, I
                 }
             }
             TmfTraceContext ctx = TmfTraceManager.getInstance().getCurrentTraceContext();
-            long beginTime = ctx.getSelectionRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
-            long endTime = ctx.getSelectionRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
-            fViewer.setSelectionRange(beginTime, endTime);
+            long beginTime = ctx.getSelectionRange().getStartTime().toNanos();
+            long endTime = ctx.getSelectionRange().getEndTime().toNanos();
+            fViewer.setSelectionRange(beginTime, endTime, false);
         }
     }
 
@@ -662,7 +696,7 @@ public class TimeChartView extends TmfView implements ITimeGraphRangeListener, I
         for (int i = 0; i < fTimeAnalysisEntries.size(); i++) {
             TimeChartAnalysisEntry timeAnalysisEntry = fTimeAnalysisEntries.get(i);
             if (timeAnalysisEntry.getTrace().equals(trace)) {
-                updateTraceEntry(timeAnalysisEntry, Long.MAX_VALUE, 0, Long.MAX_VALUE);
+                startProcessTraceThread(timeAnalysisEntry);
                 break;
             }
         }
@@ -677,8 +711,9 @@ public class TimeChartView extends TmfView implements ITimeGraphRangeListener, I
      */
     @TmfSignalHandler
     public void selectionRangeUpdated(TmfSelectionRangeUpdatedSignal signal) {
-        final long beginTime = signal.getBeginTime().normalize(0, TIMESTAMP_SCALE).getValue();
-        final long endTime = signal.getEndTime().normalize(0, TIMESTAMP_SCALE).getValue();
+        final long beginTime = signal.getBeginTime().toNanos();
+        final long endTime = signal.getEndTime().toNanos();
+
         Display.getDefault().asyncExec(new Runnable() {
             @Override
             public void run() {
@@ -690,7 +725,7 @@ public class TimeChartView extends TmfView implements ITimeGraphRangeListener, I
                         itemize(fStartTime, fStopTime);
                     }
                 } else {
-                    fViewer.setSelectionRange(beginTime, endTime);
+                    fViewer.setSelectionRange(beginTime, endTime, true);
                 }
             }
         });
@@ -708,8 +743,8 @@ public class TimeChartView extends TmfView implements ITimeGraphRangeListener, I
         if (signal.getSource() == this) {
             return;
         }
-        final long startTime = signal.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
-        final long endTime = signal.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+        final long startTime = signal.getCurrentRange().getStartTime().toNanos();
+        final long endTime = signal.getCurrentRange().getEndTime().toNanos();
         Display.getDefault().asyncExec(new Runnable() {
             @Override
             public void run() {
This page took 0.028517 seconds and 5 git commands to generate.