tmf: Bug: 499359: Fix deadlock in table when closing trace selection
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / viewers / events / TmfEventsTable.java
index c62b70d720b0442bdcbe30b426fc4b3800fcb082..9e9cd729002f52593a7ab008fd6f0051d553c626 100644 (file)
@@ -53,10 +53,12 @@ import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.ListenerList;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.EValidator;
 import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.action.IMenuListener;
@@ -117,6 +119,7 @@ import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.Menu;
 import org.eclipse.swt.widgets.MessageBox;
 import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
 import org.eclipse.swt.widgets.TableColumn;
 import org.eclipse.swt.widgets.TableItem;
 import org.eclipse.swt.widgets.Text;
@@ -230,7 +233,21 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
     private static final int FILTER_SUMMARY_INDEX = 1;
     private static final int EVENT_COLUMNS_START_INDEX = MARGIN_COLUMN_INDEX + 1;
 
-    private final class ColumnMovedListener extends ControlAdapter {
+    private final ISchedulingRule fTimeSelectMutexRule = new ISchedulingRule() {
+        @Override
+        public boolean isConflicting(ISchedulingRule rule) {
+            return (rule == this);
+        }
+
+        @Override
+        public boolean contains(ISchedulingRule rule) {
+            return (rule == this);
+        }
+    };
+
+    private Job fTimeSelectJob = null;
+
+    private final class ColumnListener extends ControlAdapter {
         /*
          * Make sure that the margin column is always first and keep the column
          * order variable up to date.
@@ -238,18 +255,27 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
         @Override
         public void controlMoved(ControlEvent e) {
             int[] order = fTable.getColumnOrder();
-            if (order[0] == MARGIN_COLUMN_INDEX) {
-                fColumnOrder = order;
-                return;
-            }
-            for (int i = order.length - 1; i > 0; i--) {
-                if (order[i] == MARGIN_COLUMN_INDEX) {
-                    order[i] = order[i - 1];
-                    order[i - 1] = MARGIN_COLUMN_INDEX;
+            if (order[0] != MARGIN_COLUMN_INDEX) {
+                for (int i = order.length - 1; i > 0; i--) {
+                    if (order[i] == MARGIN_COLUMN_INDEX) {
+                        order[i] = order[i - 1];
+                        order[i - 1] = MARGIN_COLUMN_INDEX;
+                    }
                 }
+                fTable.setColumnOrder(order);
+            }
+            fColumnOrder = order;
+            fTable.layout();
+        }
+
+        @Override
+        public void controlResized(ControlEvent e) {
+            TableColumn column = (TableColumn) e.widget;
+            if (column.getResizable() && !isExpanded(column)) {
+                int i = (int) column.getData(Key.INDEX);
+                fColumnSize[i] = column.getWidth();
+                column.setData(Key.WIDTH, fColumnSize[i]);
             }
-            fTable.setColumnOrder(order);
-            fColumnOrder = fTable.getColumnOrder();
         }
     }
 
@@ -630,6 +656,13 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
          * @since 1.1
          */
         String WIDTH = "$width"; //$NON-NLS-1$
+
+        /**
+         * The position of the column
+         *
+         * @since 2.1
+         */
+        String INDEX = "$index"; //$NON-NLS-1$
     }
 
     /**
@@ -639,8 +672,11 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
      * @author Patrick Tasse
      */
     public static enum HeaderState {
-        /** No search filter is applied
-         * @since 2.0*/
+        /**
+         * No search filter is applied
+         *
+         * @since 2.0
+         */
         NO_SEARCH,
 
         /** A search filter is applied */
@@ -664,9 +700,11 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
 
     private Composite fComposite;
     private SashForm fSashForm;
+    private Composite fTableComposite;
     private TmfRawEventViewer fRawViewer;
     private ITmfTrace fTrace;
     private volatile boolean fPackDone = false;
+    private volatile boolean fPackMarginDone = false;
     private HeaderState fHeaderState = HeaderState.NO_SEARCH;
     private long fSelectedRank = -1;
     private long fSelectedBeginRank = -1;
@@ -729,6 +767,10 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
     private MenuManager fTablePopupMenuManager;
     private MenuManager fHeaderPopupMenuManager;
 
+    private boolean[] fColumnResizable;
+
+    private int[] fColumnSize;
+
     // ------------------------------------------------------------------------
     // Constructors
     // ------------------------------------------------------------------------
@@ -812,16 +854,16 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
         fSashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
 
         // Create a composite for the table and its header bar
-        Composite tableComposite = new Composite(fSashForm, SWT.NONE);
-        tableComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+        fTableComposite = new Composite(fSashForm, SWT.NONE);
+        fTableComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
         gl = new GridLayout(1, false);
         gl.marginHeight = 0;
         gl.marginWidth = 0;
         gl.verticalSpacing = 0;
-        tableComposite.setLayout(gl);
+        fTableComposite.setLayout(gl);
 
         // Create an events table header bar
-        fHeaderBar = new TmfEventsTableHeader(tableComposite, SWT.NONE, new IEventsTableHeaderListener() {
+        fHeaderBar = new TmfEventsTableHeader(fTableComposite, SWT.NONE, new IEventsTableHeaderListener() {
             @Override
             public void filterSelected(ITmfFilter filter) {
                 if (filter instanceof TmfFilterMatchesNode) {
@@ -849,7 +891,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
 
         // Create a virtual table
         final int style = SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION;
-        fTable = new TmfVirtualTable(tableComposite, style);
+        fTable = new TmfVirtualTable(fTableComposite, style);
 
         // Set the table layout
         final GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
@@ -863,6 +905,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
         for (ITmfEventAspect<?> aspect : aspects) {
             if (aspect != null) {
                 fColumns.add(new TmfEventTableColumn(aspect));
+
             }
         }
 
@@ -870,20 +913,28 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
         fColumns.add(MARGIN_COLUMN_INDEX, collapseCol);
 
         fHeaderMenu = new Menu(fTable);
+
+        fColumnSize = new int[fColumns.size()];
+        fColumnResizable = new boolean[fColumns.size()];
+        int i = 0;
         // Create the UI columns in the table
         for (TmfEventTableColumn col : fColumns) {
             TableColumn column = fTable.newTableColumn(SWT.LEFT);
             column.setText(col.getHeaderName());
             column.setToolTipText(col.getHeaderTooltip());
             column.setData(Key.ASPECT, col.getEventAspect());
-            column.pack();
+            column.setData(Key.INDEX, i);
             if (col instanceof TmfMarginColumn) {
                 column.setResizable(false);
             } else {
+                column.pack();
                 column.setMoveable(true);
-                column.setData(Key.WIDTH, -1);
+                column.setData(Key.WIDTH, column.getWidth());
+                fColumnSize[i] = column.getWidth();
             }
-            column.addControlListener(new ColumnMovedListener());
+            column.addControlListener(new ColumnListener());
+            fColumnResizable[i] = column.getResizable();
+            i++;
         }
         fColumnOrder = fTable.getColumnOrder();
 
@@ -903,15 +954,12 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
         // Handle the table item requests
         fTable.addListener(SWT.SetData, new SetDataListener());
 
-        fTable.addListener(SWT.MenuDetect, new Listener() {
-            @Override
-            public void handleEvent(Event event) {
-                fLastMenuCursorLocation = new Point(event.x, event.y);
-                Point pt = fTable.getDisplay().map(null, fTable, fLastMenuCursorLocation);
-                Rectangle clientArea = fTable.getClientArea();
-                boolean header = clientArea.y <= pt.y && pt.y < (clientArea.y + fTable.getHeaderHeight());
-                fTable.setMenu(header ? fHeaderMenu : fTablePopup);
-            }
+        fTable.addMenuDetectListener(event -> {
+            fLastMenuCursorLocation = new Point(event.x, event.y);
+            Point pt = fTable.getDisplay().map(null, fTable, fLastMenuCursorLocation);
+            Rectangle clientArea = fTable.getClientArea();
+            boolean header = clientArea.y <= pt.y && pt.y < (clientArea.y + fTable.getHeaderHeight());
+            fTable.setMenu(header ? fHeaderMenu : fTablePopup);
         });
 
         fTable.addMouseListener(new MouseDoubleClickListener());
@@ -963,18 +1011,25 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
      * @param column
      *            the column
      */
-    private static IAction createHeaderAction(final TableColumn column) {
+    private IAction createHeaderAction(final TableColumn column) {
         final IAction columnMenuAction = new Action(column.getText(), IAction.AS_CHECK_BOX) {
             @Override
             public void run() {
-                if (isChecked()) {
-                    column.setWidth((int) column.getData(Key.WIDTH));
+                boolean isChecked = isChecked();
+                if (isChecked) {
+                    int width = (int) column.getData(Key.WIDTH);
                     column.setResizable(true);
+                    if (width == 0) {
+                        column.pack();
+                    } else {
+                        column.setWidth(width);
+                    }
                 } else {
-                    column.setData(Key.WIDTH, column.getWidth());
-                    column.setWidth(0);
                     column.setResizable(false);
+                    column.setWidth(0);
                 }
+                int pos = (int) column.getData(Key.INDEX);
+                fColumnResizable[pos] = isChecked;
             }
         };
         columnMenuAction.setChecked(column.getResizable());
@@ -986,23 +1041,16 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
             @Override
             public void run() {
                 for (TableColumn column : fTable.getColumns()) {
-                    final Object widthVal = column.getData(Key.WIDTH);
-                    if (widthVal instanceof Integer) {
-                        Integer width = (Integer) widthVal;
-                        if (!column.getResizable()) {
+                    int index = (int) column.getData(Key.INDEX);
+                    if (index != MARGIN_COLUMN_INDEX) {
+                        final int width = (int) column.getData(Key.WIDTH);
+                        column.setResizable(true);
+                        if (width == 0) {
+                            column.pack();
+                        } else {
                             column.setWidth(width);
-                            column.setResizable(true);
-                            /*
-                             * This is because Linux always resizes the last
-                             * column to fill in the void, this means that
-                             * hiding a column resizes others and we can have 10
-                             * columns that are 1000 pixels wide by hiding the
-                             * last one progressively.
-                             */
-                            if (IS_LINUX) {
-                                column.pack();
-                            }
                         }
+                        fColumnResizable[index] = true;
                     }
                 }
             }
@@ -1051,7 +1099,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
         final IAction showTableAction = new Action(Messages.TmfEventsTable_ShowTableActionText) {
             @Override
             public void run() {
-                fTable.setVisible(true);
+                fTableComposite.setVisible(true);
                 fSashForm.layout();
             }
         };
@@ -1059,7 +1107,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
         final IAction hideTableAction = new Action(Messages.TmfEventsTable_HideTableActionText) {
             @Override
             public void run() {
-                fTable.setVisible(false);
+                fTableComposite.setVisible(false);
                 fSashForm.layout();
             }
         };
@@ -1102,6 +1150,11 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
                 if (cs == null) {
                     return;
                 }
+                Long lineNo = cs.getLineNo();
+                if (lineNo == null) {
+                    /* Not enough information to provide a full callsite */
+                    return;
+                }
 
                 String fileName = cs.getFileName();
                 final String trimmedPath = fileName.replaceAll("\\.\\./", EMPTY_STRING); //$NON-NLS-1$
@@ -1123,7 +1176,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
                              * the line number, then seek there.
                              */
                             ITextEditor textEditor = (ITextEditor) editor;
-                            int lineNumber = Long.valueOf(cs.getLineNumber()).intValue();
+                            int lineNumber = lineNo.intValue();
                             IDocument document = textEditor.getDocumentProvider().getDocument(textEditor.getEditorInput());
 
                             IRegion region = document.getLineInformation(lineNumber - 1);
@@ -1139,10 +1192,11 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
                          */
                         IMarker marker = null;
                         final ArrayList<IFile> files = new ArrayList<>();
+                        IPath p = new Path(trimmedPath);
                         ResourcesPlugin.getWorkspace().getRoot().accept(new IResourceVisitor() {
                             @Override
                             public boolean visit(IResource resource) throws CoreException {
-                                if (resource instanceof IFile && resource.getFullPath().toString().endsWith(trimmedPath)) {
+                                if (resource instanceof IFile && resource.getFullPath().toString().endsWith(p.lastSegment())) {
                                     files.add((IFile) resource);
                                 }
                                 return true;
@@ -1171,7 +1225,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
                         }
                         if (file != null) {
                             marker = file.createMarker(IMarker.MARKER);
-                            marker.setAttribute(IMarker.LINE_NUMBER, Long.valueOf(cs.getLineNumber()).intValue());
+                            marker.setAttribute(IMarker.LINE_NUMBER, lineNo.intValue());
                             IDE.openEditor(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(), marker);
                             marker.delete();
                         } else if (files.isEmpty()) {
@@ -1684,6 +1738,10 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
                 item.setFont(i, fBoldFont);
             }
         }
+        if (!fPackMarginDone) {
+            packMarginColumn();
+            fPackMarginDone = true;
+        }
     }
 
     /**
@@ -1795,15 +1853,15 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
                                 applyHeader();
                                 if ((e.stateMask & SWT.CTRL) != 0) {
                                     applySearchAsFilter();
-                                } else {
-                                    /*
-                                     * Set focus on the table so that the next
-                                     * carriage return goes to the next result
-                                     */
-                                    TmfEventsTable.this.getTable().setFocus();
                                 }
+                                /*
+                                 * Set focus on the table so that the next
+                                 * carriage return goes to the next result
+                                 */
+                                TmfEventsTable.this.getTable().setFocus();
                             } else if (e.character == SWT.ESC) {
                                 tableEditor.getEditor().dispose();
+                                TmfEventsTable.this.getTable().setFocus();
                             }
                         }
                     });
@@ -2476,6 +2534,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
             final int selection = index + 1 + (eventFilter != null ? +1 : 0);
 
             display.asyncExec(new Runnable() {
+
                 @Override
                 public void run() {
                     if (monitor.isCanceled()) {
@@ -2499,6 +2558,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
                 }
             });
             return Status.OK_STATUS;
+
         }
 
         @Override
@@ -2510,6 +2570,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
                 fSearchThread = null;
             }
         }
+
     }
 
     /**
@@ -2559,9 +2620,8 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
     /**
      * Pack the columns.
      *
-     * @return
-     *            Whether or not a pack was done in this call. Otherwise, it was already done by a
-     *            previous call
+     * @return Whether or not a pack was done in this call. Otherwise, it was
+     *         already done by a previous call
      *
      * @since 2.0
      */
@@ -2593,19 +2653,25 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
     }
 
     private void packSingleColumn(int i, final TableColumn column) {
-        final int headerWidth = column.getWidth();
+        if (i != MARGIN_COLUMN_INDEX && !column.getResizable()) {
+            return;
+        }
+        Object data = column.getData(Key.WIDTH);
+        final int headerWidth = data instanceof Integer ? (int) data : -1;
         column.pack();
         /*
          * Workaround for Linux which doesn't consider the image width of
          * search/filter row in TableColumn.pack() after having executed
          * TableItem.setImage(null) for other rows than search/filter row.
          */
-        if (IS_LINUX && (i == 0) && fCollapseFilterEnabled) {
+        if (IS_LINUX && (i == MARGIN_COLUMN_INDEX) && fCollapseFilterEnabled) {
             column.setWidth(column.getWidth() + SEARCH_IMAGE.getBounds().width);
         }
 
         if (column.getWidth() < headerWidth) {
             column.setWidth(headerWidth);
+        } else if (i != MARGIN_COLUMN_INDEX) {
+            column.setData(Key.WIDTH, column.getWidth());
         }
     }
 
@@ -2627,6 +2693,32 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
         return true;
     }
 
+    /**
+     * Returns true if the column is expanded to take extra available space.
+     * This is the last non-zero-width visible column in the column order on
+     * Linux. This column's width should not be persisted.
+     *
+     * @param column
+     *            the column
+     * @return true if the column is expanded.
+     */
+    private static boolean isExpanded(TableColumn column) {
+        if (IS_LINUX) {
+            Table table = column.getParent();
+            int[] order = table.getColumnOrder();
+            for (int i = order.length - 1; i >= 0; i--) {
+                TableColumn col = table.getColumn(order[i]);
+                if (col == column) {
+                    return true;
+                }
+                if (col.getWidth() > 0) {
+                    return false;
+                }
+            }
+        }
+        return false;
+    }
+
     /**
      * Get the array of item strings (e.g., what to display in each cell of the
      * table row) corresponding to the columns and trace event passed in
@@ -2698,6 +2790,26 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
         return fColumnOrder;
     }
 
+    /**
+     * Get column widths
+     *
+     * @return the current visual widths of the receiver's columns
+     * @since 2.1
+     */
+    public int[] getColumnWidth() {
+        return fColumnSize;
+    }
+
+    /**
+     * Get whether the columns are resizable
+     *
+     * @return an array stating if each column is resizable
+     * @since 2.1
+     */
+    public boolean[] getColumnResizable() {
+        return fColumnResizable;
+    }
+
     /**
      * Sets the order that the columns in the receiver should be displayed in to
      * the given argument which is described in terms of the zero-relative
@@ -2718,6 +2830,39 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
         fColumnOrder = fTable.getColumnOrder();
     }
 
+    /**
+     * Sets the column width and resizability
+     *
+     * @param width
+     *            an array of widths
+     * @param resizable
+     *            an array of bools saying if a column is resizable or not
+     * @since 2.1
+     */
+    public void setColumnWidth(int[] width, boolean[] resizable) {
+        int length = fTable.getColumns().length;
+        if (width == null || resizable == null || resizable.length != length || width.length != length) {
+            return;
+        }
+        int i = 0;
+        for (TableColumn column : fTable.getColumns()) {
+            if (i != MARGIN_COLUMN_INDEX) {
+                column.setData(Key.WIDTH, width[i]);
+                column.setResizable(resizable[i]);
+                if (column.getResizable()) {
+                    column.setWidth((int) column.getData(Key.WIDTH));
+                } else {
+                    column.setWidth(0);
+                }
+            }
+            i++;
+        }
+        fColumnSize = width;
+        fColumnResizable = resizable;
+        /* Don't pack, it would override these settings */
+        fPackDone = true;
+    }
+
     /**
      * Notify this table that is got the UI focus.
      */
@@ -2732,7 +2877,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
      * @param site
      *            the site that the context menus will be registered for
      *
-     * @since 2.0
+     * @since 1.2
      */
     public void registerContextMenus(IWorkbenchPartSite site) {
         if (site instanceof IEditorSite) {
@@ -3183,143 +3328,167 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
     public void selectionRangeUpdated(final TmfSelectionRangeUpdatedSignal signal) {
         if ((signal.getSource() != this) && (fTrace != null) && (!fTable.isDisposed())) {
 
-            /*
-             * Create a request for one event that will be queued after other
-             * ongoing requests. When this request is completed do the work to
-             * select the actual event with the timestamp specified in the
-             * signal. This procedure prevents the method fTrace.getRank() from
-             * interfering and delaying ongoing requests.
-             */
-            final TmfEventRequest subRequest = new TmfEventRequest(ITmfEvent.class,
-                    TmfTimeRange.ETERNITY, 0, 1, ExecutionType.FOREGROUND) {
-
-                ITmfTimestamp ts = signal.getBeginTime();
-                ITmfTimestamp tf = signal.getEndTime();
+            Job timeSelectJob;
+            synchronized (fTimeSelectMutexRule) {
+                timeSelectJob = fTimeSelectJob;
+                if (timeSelectJob != null) {
+                    timeSelectJob.cancel();
+                }
 
-                @Override
-                public void handleSuccess() {
-                    super.handleSuccess();
-                    if (fTrace == null) {
-                        return;
-                    }
+                /*
+                 * Run in separate thread to not block UI thread for too long.
+                 */
+                timeSelectJob = new Job("Events table selection job") { //$NON-NLS-1$
+                    ITmfTimestamp ts = signal.getBeginTime();
+                    ITmfTimestamp tf = signal.getEndTime();
 
-                    final Pair<Long, Long> selection = getSelectedRanks();
-                    updateDisplayWithSelection(selection.getFirst().longValue(), selection.getSecond().longValue());
-                }
+                    @Override
+                    protected IStatus run(IProgressMonitor monitor) {
+                        if (fTrace == null) {
+                            return Status.OK_STATUS;
+                        }
 
-                /**
-                 * Verify if the event is within the trace range and adjust if
-                 * necessary.
-                 *
-                 * @return A pair of rank representing the selected area
-                 **/
-                private Pair<Long, Long> getSelectedRanks() {
+                        final Pair<Long, Long> selection = getSelectedRanks(monitor);
 
-                    /* Clamp the timestamp value to fit inside of the trace */
-                    ITmfTimestamp timestampBegin = ts;
-                    if (timestampBegin.compareTo(fTrace.getStartTime()) < 0) {
-                        timestampBegin = fTrace.getStartTime();
-                    }
-                    if (timestampBegin.compareTo(fTrace.getEndTime()) > 0) {
-                        timestampBegin = fTrace.getEndTime();
+                        if (monitor.isCanceled() || (selection == null)) {
+                            return Status.CANCEL_STATUS;
+                        }
+                        updateDisplayWithSelection(selection.getFirst().longValue(), selection.getSecond().longValue());
+                        return Status.OK_STATUS;
                     }
 
-                    ITmfTimestamp timestampEnd = tf;
-                    if (timestampEnd.compareTo(fTrace.getStartTime()) < 0) {
-                        timestampEnd = fTrace.getStartTime();
-                    }
-                    if (timestampEnd.compareTo(fTrace.getEndTime()) > 0) {
-                        timestampEnd = fTrace.getEndTime();
-                    }
+                    /**
+                     * Verify if the event is within the trace range and adjust if
+                     * necessary.
+                     * @param monitor
+                     *                a progress monitor
+                     * @return A pair of rank representing the selected area
+                     **/
+                    @Nullable
+                    private Pair<Long, Long> getSelectedRanks(IProgressMonitor monitor) {
+
+                        /* Clamp the timestamp value to fit inside of the trace */
+                        ITmfTimestamp timestampBegin = ts;
+                        if (timestampBegin.compareTo(fTrace.getStartTime()) < 0) {
+                            timestampBegin = fTrace.getStartTime();
+                        }
+                        if (timestampBegin.compareTo(fTrace.getEndTime()) > 0) {
+                            timestampBegin = fTrace.getEndTime();
+                        }
 
-                    ITmfTimestamp tb;
-                    ITmfTimestamp te;
-                    long rankBegin;
-                    long rankEnd;
-                    ITmfContext contextBegin;
-                    ITmfContext contextEnd;
-
-                    /* Adjust the rank of the selection to the right range */
-                    if (timestampBegin.compareTo(timestampEnd) > 0) {
-                        te = timestampEnd;
-                        contextEnd = fTrace.seekEvent(te);
-                        rankEnd = contextEnd.getRank();
-                        contextEnd.dispose();
-                        /*
-                         * To include all events at the begin time, seek at the
-                         * next nanosecond and then use the previous rank
-                         */
-                        tb = timestampBegin.normalize(1, ITmfTimestamp.NANOSECOND_SCALE);
-                        if (tb.compareTo(fTrace.getEndTime()) <= 0) {
-                            contextBegin = fTrace.seekEvent(tb);
-                            rankBegin = contextBegin.getRank();
-                            contextBegin.dispose();
-                        } else {
-                            rankBegin = ITmfContext.UNKNOWN_RANK;
+                        ITmfTimestamp timestampEnd = tf;
+                        if (timestampEnd.compareTo(fTrace.getStartTime()) < 0) {
+                            timestampEnd = fTrace.getStartTime();
                         }
-                        rankBegin = (rankBegin == ITmfContext.UNKNOWN_RANK ? fTrace.getNbEvents() : rankBegin) - 1;
-                        /*
-                         * If no events in selection range, select only the next
-                         * event
-                         */
-                        rankBegin = rankBegin >= rankEnd ? rankBegin : rankEnd;
-                    } else {
-                        tb = timestampBegin;
-                        contextBegin = fTrace.seekEvent(tb);
-                        rankBegin = contextBegin.getRank();
-                        contextBegin.dispose();
-                        /*
-                         * To include all events at the end time, seek at the
-                         * next nanosecond and then use the previous rank
-                         */
-                        te = timestampEnd.normalize(1, ITmfTimestamp.NANOSECOND_SCALE);
-                        if (te.compareTo(fTrace.getEndTime()) <= 0) {
+                        if (timestampEnd.compareTo(fTrace.getEndTime()) > 0) {
+                            timestampEnd = fTrace.getEndTime();
+                        }
+
+                        ITmfTimestamp tb;
+                        ITmfTimestamp te;
+                        long rankBegin;
+                        long rankEnd;
+                        ITmfContext contextBegin;
+                        ITmfContext contextEnd;
+                        if (monitor.isCanceled()) {
+                            return null;
+                        }
+
+                        /* Adjust the rank of the selection to the right range */
+                        if (timestampBegin.compareTo(timestampEnd) > 0) {
+                            te = timestampEnd;
                             contextEnd = fTrace.seekEvent(te);
                             rankEnd = contextEnd.getRank();
                             contextEnd.dispose();
+
+                            if (monitor.isCanceled()) {
+                                return null;
+                            }
+                            /*
+                             * To include all events at the begin time, seek at the
+                             * next nanosecond and then use the previous rank
+                             */
+                            tb = timestampBegin.normalize(1, ITmfTimestamp.NANOSECOND_SCALE);
+                            if (tb.compareTo(fTrace.getEndTime()) <= 0) {
+                                contextBegin = fTrace.seekEvent(tb);
+                                rankBegin = contextBegin.getRank();
+                                contextBegin.dispose();
+                            } else {
+                                rankBegin = ITmfContext.UNKNOWN_RANK;
+                            }
+                            rankBegin = (rankBegin == ITmfContext.UNKNOWN_RANK ? fTrace.getNbEvents() : rankBegin) - 1;
+                            /*
+                             * If no events in selection range, select only the next
+                             * event
+                             */
+                            rankBegin = rankBegin >= rankEnd ? rankBegin : rankEnd;
                         } else {
-                            rankEnd = ITmfContext.UNKNOWN_RANK;
+                            tb = timestampBegin;
+                            contextBegin = fTrace.seekEvent(tb);
+                            rankBegin = contextBegin.getRank();
+                            contextBegin.dispose();
+                            if (monitor.isCanceled()) {
+                                return null;
+                            }
+                            /*
+                             * To include all events at the end time, seek at the
+                             * next nanosecond and then use the previous rank
+                             */
+                            te = timestampEnd.normalize(1, ITmfTimestamp.NANOSECOND_SCALE);
+                            if (te.compareTo(fTrace.getEndTime()) <= 0) {
+                                contextEnd = fTrace.seekEvent(te);
+                                rankEnd = contextEnd.getRank();
+                                contextEnd.dispose();
+                            } else {
+                                rankEnd = ITmfContext.UNKNOWN_RANK;
+                            }
+                            rankEnd = (rankEnd == ITmfContext.UNKNOWN_RANK ? fTrace.getNbEvents() : rankEnd) - 1;
+                            /*
+                             * If no events in selection range, select only the next
+                             * event
+                             */
+                            rankEnd = rankEnd >= rankBegin ? rankEnd : rankBegin;
                         }
-                        rankEnd = (rankEnd == ITmfContext.UNKNOWN_RANK ? fTrace.getNbEvents() : rankEnd) - 1;
-                        /*
-                         * If no events in selection range, select only the next
-                         * event
-                         */
-                        rankEnd = rankEnd >= rankBegin ? rankEnd : rankBegin;
+                        return new Pair<>(Long.valueOf(rankBegin), Long.valueOf(rankEnd));
                     }
-                    return new Pair<>(Long.valueOf(rankBegin), Long.valueOf(rankEnd));
-                }
 
-                private void updateDisplayWithSelection(final long rankBegin, final long rankEnd) {
-                    PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-                        @Override
-                        public void run() {
-                            // Return if table is disposed
-                            if (fTable.isDisposed()) {
-                                return;
-                            }
+                    private void updateDisplayWithSelection(final long rankBegin, final long rankEnd) {
+                        PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+                            @Override
+                            public void run() {
+                                // Return if table is disposed
+                                if (fTable.isDisposed()) {
+                                    return;
+                                }
 
-                            fSelectedRank = rankEnd;
-                            long toReveal = fSelectedBeginRank != rankBegin ? rankBegin : rankEnd;
-                            fSelectedBeginRank = rankBegin;
-                            int indexBegin = (int) rankBegin;
-                            int indexEnd = (int) rankEnd;
+                                fSelectedRank = rankEnd;
+                                long toReveal = fSelectedBeginRank != rankBegin ? rankBegin : rankEnd;
+                                fSelectedBeginRank = rankBegin;
+                                int indexBegin = (int) rankBegin;
+                                int indexEnd = (int) rankEnd;
 
-                            if (fTable.getData(Key.FILTER_OBJ) != null) {
-                                /* +1 for top filter status row */
-                                indexBegin = fCache.getFilteredEventIndex(rankBegin) + 1;
-                                indexEnd = rankEnd == rankBegin ? indexBegin : fCache.getFilteredEventIndex(rankEnd) + 1;
+                                if (fTable.getData(Key.FILTER_OBJ) != null) {
+                                    /* +1 for top filter status row */
+                                    indexBegin = fCache.getFilteredEventIndex(rankBegin) + 1;
+                                    indexEnd = rankEnd == rankBegin ? indexBegin : fCache.getFilteredEventIndex(rankEnd) + 1;
+                                }
+                                /* +1 for header row */
+                                fTable.setSelectionRange(indexBegin + 1, indexEnd + 1);
+                                fRawViewer.selectAndReveal(toReveal);
+                                updateStatusLine(null);
                             }
-                            /* +1 for header row */
-                            fTable.setSelectionRange(indexBegin + 1, indexEnd + 1);
-                            fRawViewer.selectAndReveal(toReveal);
-                            updateStatusLine(null);
-                        }
-                    });
-                }
-            };
-
-            ((ITmfEventProvider) fTrace).sendRequest(subRequest);
+                        });
+                    }
+                };
+                timeSelectJob.setSystem(true);
+                /*
+                 *  Make subsequent jobs not run concurrently so that they are
+                 *  executed in order.
+                 */
+                timeSelectJob.setRule(fTimeSelectMutexRule);
+                timeSelectJob.schedule();
+                fTimeSelectJob = timeSelectJob;
+            }
         }
     }
 
@@ -3354,8 +3523,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
      */
     private static final class TmfMarginColumn extends TmfEventTableColumn {
 
-        private static final @NonNull ITmfEventAspect<String> MARGIN_ASPECT =
-                new ITmfEventAspect<String>() {
+        private static final @NonNull ITmfEventAspect<String> MARGIN_ASPECT = new ITmfEventAspect<String>() {
 
             @Override
             public String getName() {
@@ -3383,5 +3551,4 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS
             super(MARGIN_ASPECT);
         }
     }
-
-}
+}
\ No newline at end of file
This page took 0.052502 seconds and 5 git commands to generate.