Bug 95658 [Workbench] Events are being dispatched and async/syncExecs are run before the Workbench is in a good state
As part of plug-in startup and activation, anyone can call Display.readAndDispatch() to process UI events. This will also run any outstanding asyncExecs and syncExecs. For example, ModalContext.ModalContextThread#block calls readAndDispatch. This in turn is indirectly called by ProgressManager#run, which is called by CVS's AllRootsElement when the repositories view is created. The code that restores the Workbench is written in a way that it assumes no events are dispatched and no async/syncExecs are run before the 'real' UI event loop runs. This is a false assumption. I am attaching source for a modified UISynchronizer that delays at least the async/syncExecs until it is safe to run them. However, this creates a new problem in that ModalContext.ModalContextThread#block actually blocks forever because the syncExec in ModalContext.ModalContextThread#run is not being executed. We should either be prepared for anyone to call into Workbench methods even before we run the event loop, or use something along the lines of the attached UISycnhronizer to prevent this from happening.
bundles/org.eclipse.jface/src/org/eclipse/jface/operation/ModalContext.java
/**
     * Runs the given runnable in a modal context, passing it a progress monitor.
     * <p>
     * The modal nesting level is increased by one from the perspective
     * of the given runnable.
     * </p>
     *<p>
     * If the supplied operation implements <code>IThreadListener</code>, it
     * will be notified of any thread changes required to execute the operation.
     * Specifically, the operation will be notified of the thread that will call its 
     * <code>run</code> method before it is called, and will be notified of the
     * change of control back to the thread calling this method when the operation
     * completes.  These thread change notifications give the operation an 
     * opportunity to transfer any thread-local state to the execution thread before 
     * control is transferred to the new thread.
     *</p>
     * @param operation the runnable to run
     * @param fork <code>true</code> if the runnable should run in a separate thread,
     *   and <code>false</code> if in the same thread
     * @param monitor the progress monitor to use to display progress and receive
     *   requests for cancelation
     * @param display the display to be used to read and dispatch events
     * @exception InvocationTargetException if the run method must propagate a checked exception,
     * 	it should wrap it inside an <code>InvocationTargetException</code>; runtime exceptions and errors are automatically
     *  wrapped in an <code>InvocationTargetException</code> by this method
     * @exception InterruptedException if the operation detects a request to cancel, 
     *  using <code>IProgressMonitor.isCanceled()</code>, it should exit by throwing 
     *  <code>InterruptedException</code>; this method propagates the exception
     */
    public static void run(IRunnableWithProgress operation, boolean fork,