Bug 21866 - [Workbench] Using workbench window as runnable context does not refresh status
Summary: [Workbench] Using workbench window as runnable context does not refresh status
Status: RESOLVED INVALID
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 2.0   Edit
Hardware: PC Windows 2000
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Platform-UI-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords: investigate
Depends on:
Blocks:
 
Reported: 2002-07-24 14:07 EDT by Ritchie Schacher CLA
Modified: 2004-12-22 14:56 EST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ritchie Schacher CLA 2002-07-24 14:07:02 EDT
I have code which does the following:

try {
	getRunnableContext().run(false, true, getRunnable());
} catch (InvocationTargetException e) {
} catch (InterruptedException e) {
}

where the runnable context is the active workbench window.

This is done during a resource change notification.  The problem is that
the status line does not update when my runnable sets messages on the 
IProgressMonitor.  I saw that eclipse handles this using 
org.eclipse.ui.internal.dialogs.EventLoopProgressMonitor to wrap the monitor 
passed in using a wrapping runnable.

For example, I used:
protected IRunnableWithProgress getRunnable() {
		final IRunnableWithProgress wrappable = xxx;
		return new IRunnableWithProgress() {
			public void run(IProgressMonitor monitor) throws 
InterruptedException, InvocationTargetException {
				IProgressMonitor monitorWrap = new 
EventLoopProgressMonitor(monitor);
				wrappable.run(monitorWrap);
			}
		};	
	}

and so that I don't have to use an internal class, I made a copy of 
EventLoopProgressMonitor.

The issues:
1)  It would be nice if the workbench window as runnble context would take care 
of this automatically.
2)  If not, it would be nice if the EventLoopProgressMonitor was not internal, 
so that I don't have to copy it, or to have some exposed api which works.
3)  Is my workaround safe?

Thanks
-Ritchie
Comment 1 Nick Edgar CLA 2002-07-25 11:15:58 EDT
Yes, unfortunately this workaround is required to keep the UI responsive.
We are investigating better approaches to progress monitoring.

The currently recommended approach is to use fork=true and then do a 
Display.syncExec whenever you need to talk to the UI thread.
Have you tried this?  If this doesn't work for you, it would be helpful to know 
why not.
Comment 2 Ritchie Schacher CLA 2002-07-25 11:27:28 EDT
I didn't try the sync exec for progress monitor updates, but I did try 
fork=true, and the system deadlocked and I had to kill it.  As I mentioned, 
this is during a resource change notification on type POST_AUTO_BUILD.

My code has grown more complex; this is to cover me whether the notification is 
coming from the display thread or not.  This seems to work for the test cases 
I've tried - adding from the repo, deleting projects, and saving from editors.

	protected void runxxx() {
		final IRunnableWithProgress runnableWithProg = xxx;
		final IRunnableContext context = getRunnableContext();
		final Display display = Display.getCurrent() == null ? 
Display.getDefault() : Display.getCurrent();
		Runnable simpleRunnable = new Runnable() {
			public void run() {
				try { 
					if (context != null && display != null)
						context.run(false, true, 
runnableWithProg);
					else
						runnableWithProg.run(new 
NullProgressMonitor());
				} catch (InvocationTargetException e) {
					
				} catch (InterruptedException e) {}
			}
		};
		if (display == null) 
			simpleRunnable.run();
		else
			display.syncExec(simpleRunnable);
	}
Comment 3 Nick Edgar CLA 2002-07-25 14:40:31 EDT
How is the autobuild being triggered when you encounter deadlocks?
What kind of work are you doing in response to the autobuild?  Are you making 
further modifications to the workspace?

An autobuild can occur due to any workspace change, including a file save, 
which also reports progress in the status line.  So if you also want to use the 
status line, it will be reporting progress twice, which will look funny.

If you are encountering deadlocks, one way to track down what's happening is to 
run eclipse from a command line window with -vm c:\jre\bin\java.exe (instead of 
javaw.exe).  When the deadlock is hit, use ctrl+break in the command line 
window to get a dump of all threads.

You might want to try queuing all your post-auto-build work within an asyncExec 
(not syncExec).  That way it will run after the autobuild notification unwinds 
(releasing the workspace lock), and after the UI is processing events again.
This may help avoid the deadlock.

Comment 4 Ritchie Schacher CLA 2002-07-25 15:11:59 EDT
I don't remember which resource change scenario it was that caused the deadlock 
(add, remove, or save).  Note that autobuild may or may not have been on; this 
is just the notification I listen for because that is when the tree is unlocked 
and I can make further modifications.

My listener will not modify resources, but may modify the markers in the task 
list.

I thought about queueing it in an asyncexec, but then there might be a gap 
between operations when the UI might become "enabled" and then it will 
mysteriously go "disabled" again while my operation runs, as opposed to a 
continuous pause during the resource change.  On slow machines, or the first 
time classes in the plugin are loaded, this could be a noticable delay.

I agree it might look funny when I hijack the status line, but the alternative 
is not to report status at all, or async it with the possibility of a delay.
Comment 5 Nick Edgar CLA 2002-07-25 15:43:26 EDT
The delay should not be noticeable.  It's worth a try.
Comment 6 Ritchie Schacher CLA 2002-07-25 16:09:09 EDT
Ok, I'll give it a try, but it might be a couple days before I can revisit it.  
Will provide an update.  Thanks.
Comment 7 John Arthorne CLA 2004-12-22 14:56:52 EST
Using a forked operation and asyncExec for posting updates in the UI is the
correct approach. Also see the IProgressService added in 3.0 that has various
options for running a modal context (busyCursorWhile being the principle one).