Bug 49316 - [Workbench] isStarting() public API of Workbench
Summary: [Workbench] isStarting() public API of Workbench
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.0   Edit
Hardware: PC Windows XP
: P3 enhancement with 1 vote (vote)
Target Milestone: 3.5 M4   Edit
Assignee: Boris Bokowski CLA
QA Contact:
URL:
Whiteboard:
Keywords: api
Depends on:
Blocks:
 
Reported: 2003-12-23 12:39 EST by julien CLA
Modified: 2008-12-01 16:17 EST (History)
8 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description julien CLA 2003-12-23 12:39:07 EST
During the Eclipse startup, it is very important for a plugin to get the 
workbench state since some actions can be done only after startup the 
Workbench.

julien
omondo
Comment 1 Michael Van Meekeren CLA 2004-08-04 16:30:45 EDT
Could you provide a case where your plugin is being loaded but the workbench has
not been started yet?
Comment 2 Lester Lopez CLA 2004-08-04 16:34:29 EDT
I also find it important to know if the workbench is starting. For example, I 
have an editor that warns the user via a warning dialog in its init
(IEditorSite, IEditorInput) method if some condition is met. If I leave the 
editor open and restart the workbench, my editor is re-initialized and the 
warning dialog will show up again. I can (and did, until 3.0) avoid this by 
checking for Workbench.isStarting()...
Comment 3 Michael Van Meekeren CLA 2004-08-04 16:57:55 EDT
Have you looked at the comments in Workbench, and the WorkbenchAdvisor class
yet?  Specifically the postStartup() method?
Comment 4 Lester Lopez CLA 2004-08-04 17:35:25 EDT
I looked at the comments and didn't find anything helpful. Are you implying to 
extend WorkbenchAdvisor and implement postStartup to be notified when the 
workbench has started? If so, the WorkbenchAdvisor in use is 
IDEWorkbenchAdvisor, passed to the Workbench constructor by IDEApplication, 
and there is no way to extend it and somehow tell IDEApplication to use an 
instance of my class instead.
Comment 5 Michael Van Meekeren CLA 2004-08-05 09:23:51 EDT
Right, did you see the section in the R3.0 documentation called "Customizing the
workbench" this will at least help clarify what WorkbenchAdvisor is and
IWorkbenchConfigurer etc... , then you can decide if this works for you.

If not have you considered moving your warning to a time when the editor is made
visible instead of the init?  My question would be if you did use the
"isStarting()" method to discover whether the Workbench was starting, what did
you do with the error?  Fail silently or...
Comment 6 Nick Edgar CLA 2004-08-05 12:26:04 EDT
Regular plugins cannot replace or extend the WorkbenchAdvisor.

Note that Workbench.isStarting() was an internal method, so the request to add
something similar as API is an enhancement request.

We'll need more details about your use case.  To reiterate, you have a view that
when created during a session can perform some logic immediately, but in the
restart case it needs to wait until the rest of the workbench is up and running.
 Can you provide more details about what exactly it's checking for (other views?
other workbench state?)

There may be other workarounds, e.g. using the startup extension point, which
runs after the workbench is restored; or doing the logic in a display.asyncExec,
which wil get run after the event loop starts running (after the workbench is
restored).
Comment 7 Tod Creasey CLA 2006-04-13 16:08:03 EDT
Use PlatformUI.isWorkbenchRunning()
Comment 8 Boris Bokowski CLA 2006-04-13 16:15:35 EDT
Note this:

	private boolean runEventLoop = true;

	public boolean isRunning() {
		return runEventLoop;
	}

PlatformUI.isWorkbenchRunning() returns true even though the workbench is not properly initialized.
Comment 9 Tod Creasey CLA 2007-06-14 08:23:24 EDT
There are currently no plans to work on this 
Comment 10 Shubhvardhan CLA 2007-12-04 06:05:15 EST
I am using while(PlatformUI.getWorkbench().getWorkbenchWindowCount() == 0); as a workaround. This waits till the workbench is up and has atleast one window. Can this lead to any issues?
Comment 11 Tod Creasey CLA 2007-12-04 08:52:55 EST
Just because the windows are up doesn't mean that initialization is done but it should generally be safe. I think Nicks suggestion of using the startup extension point is considerably safer.

Generally guessing about state will get you into trouble somewhere.
Comment 12 Shubhvardhan CLA 2007-12-05 07:15:03 EST
I re-implemented postStartup() in the class I extended from workbenchadviser.
Here, I set a static bool to true;

Another thread polls for this value and does a thread.yield() until this is set.
Comment 13 Tod Creasey CLA 2007-12-05 07:51:30 EST
Rather than creating Thread and then yielding them it might be easier to create a Job with a scheduling rule - that way no Thread is taken out of the Thread pool and deadlock issues are easier to avoid.
Comment 14 Boris Bokowski CLA 2007-12-05 09:05:29 EST
It might be even simpler to use Display.asyncExec or .timerExec instead of a thread and yield.
Comment 15 Shubhvardhan CLA 2007-12-06 02:51:59 EST
I m terribly new to eclipse/ Java, so i think i ll pick that advice. Thanks
Comment 16 Shubhvardhan CLA 2007-12-06 02:52:46 EST
Display.async results in a deadlock for me
Comment 17 Tod Creasey CLA 2007-12-06 08:53:49 EST
If you are blocking in your async then you can deadlock. You should never block in the UI if at all possible.
Comment 18 Boris Bokowski CLA 2007-12-06 11:11:59 EST
(In reply to comment #12)
> I re-implemented postStartup() in the class I extended from workbenchadviser.
> Here, I set a static bool to true;
> 
> Another thread polls for this value and does a thread.yield() until this is
> set.

My suggestion was to do this:

public static boolean started = false;
public void postStartup() {
  started = true;
}

somewhere else:

// the following should only be done after the workbench is initialized properly
Display.getDefault().asyncExec(new Runnable(){
  public void run() {
    if (MyWorkbenchAdvisor.started) {
      // do what needs to be done
    } else {
      // wait 0.5 seconds and then check again
      Display.getDefault().timerExec(500, this);
    }
  }
});
Comment 19 Shubhvardhan CLA 2007-12-07 04:25:54 EST
correct me if I am wrong..
Display.asyncExec is safe only if you are in the main thread?
Comment 20 Boris Bokowski CLA 2007-12-07 07:58:42 EST
(In reply to comment #19)
> correct me if I am wrong..
> Display.asyncExec is safe only if you are in the main thread?

wrong.
Comment 21 Tod Creasey CLA 2007-12-07 09:10:19 EST
asyncExec is a no-op in the main Thread.

If you lock on the UI Thread you can deadlock the UI - how you got to the UI Thread  makes no difference.
Comment 22 Boris Bokowski CLA 2007-12-07 09:40:39 EST
(In reply to comment #21)
> asyncExec is a no-op in the main Thread.

Display.asyncExec won't run the given runnable immediately, it will delay it until the next time events are processed. This is true even if you are on the UI thread.
Comment 23 Chris Lee CLA 2008-09-10 15:03:27 EDT
I'm actually finding some use cases for needing to know whether the workbench is in 'startup' mode or not - in particular because it affects how our editors get loaded. Can we reopen this bug?

In the init (IEditorSite, IEditorInput) method, we do an asyncExec of some of our editor loading to make most of the UI appear faster.  However, asyncExec behaves very differently during startup, in that all calls are delayed until the workbench is available.

In this case, we have a deadlock issue: occasionally a client of our UI needs access to that information that we've asyncExec'd, so our normal course of action is to just run the display loop - however, when this happens during startup (since editors are restored during startup, this is very easy to reproduce), our asyncExec call didn't actually put anything in the display queue.

I've looked at potential solutions that involve DisplayAccess to make a "privileged startup thread" that is allowed to post the asyncExec, and using the temporary preference to use 3.2 threading, but both get rather messy and cause other issues - we make use of ModalContext and progress dialogs here; as well, this area of our code is extensible, so clients can use syncExec and asyncExec. See bugs #178875, #182176, and #219913.

Since this is a problem for both our Eclipse IDE integration as well as our RCP app, we can't override the workbench advisor or that stuff.

The best way for us to fix this is to know what the workbench startup state is, and take different actions depending on that state.


Our "API friendly" solution at the moment is to have something like this:

  public class WorkbenchState implements IStartup
  {
    private static boolean started = false;
    public void earlyStartup ()
    {
        Display.getDefault ().asyncExec (new Runnable () 
        {
            public void run ()
            {
                started = true;
            }
        });
    }
    
    public static boolean isStarted ()
    {
        return started;
    }
  }

However, it is much easier to just use 

  !((Workbench)PlatformUI.getWorkbench ()).isStarting ();

and it would be great if this was just part of the API...
Comment 24 Boris Bokowski CLA 2008-09-10 15:20:18 EDT
Reopening. The use case makes sense to me.
Comment 25 Boris Bokowski CLA 2008-12-01 16:17:51 EST
New API in IWorkbench is released to HEAD.