Bug 173995 - [Progress] Switch progress monitoring to asyncExec
Summary: [Progress] Switch progress monitoring to asyncExec
Status: VERIFIED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.2.1   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 3.4 M3   Edit
Assignee: Tod Creasey CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 203306
  Show dependency tree
 
Reported: 2007-02-13 07:34 EST by Martin Novák CLA
Modified: 2007-10-29 14:12 EDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Novák CLA 2007-02-13 07:34:45 EST
Create some code - it has 2 parts one is running in UI and one is code running in background.
Call background code: workbench.getProgressService().busyCursorWhile(this); UI code is just updating user interface [-;
Let's imagine that the background code has some synchronized section. It enters this synchronized section, and provides feedback to user using progress monitor. This synchronized is long running action.
Also background thread/some other thread sent before/during background sync section some stuff to UI which also acquires this background thread lock.
So what's the problem - when calling progress monitor AccumulatingProgressMonitor - this class acquires RunnableLock, but this RunnableLock has already been acquired by other UI runner (Display.asyncExec) when there was something to be sent to UI.

The problem is generally about UI sync/asyncexec rules. I think that main problem is that AccumulatingProgressMonitor uses Display.syncExec in some parts. I think that any progressmonitor shouldn't acquire any lock and also shouldn't block processing anyhow, because this can cause such pains.
Comment 1 Martin Novák CLA 2007-02-13 12:36:24 EST
I have put some my thoughts about this problem to my blog: http://www.puakma.net/puakma/martinplog.pma/ViewEntry?OpenPage&ID=14
Comment 2 Tod Creasey CLA 2007-02-13 14:04:46 EST
I see your issue - the problem is that asyncExecs can happen at any time - if we switch to them you can potentialy get updates at strange times which may also include behaviour like monitors moving backwards.

I don't think that switching to asyncExecs is a safe answer - not locking the Ui Thread is. The lack of updates from the progress monitor is only your first symptom - the generally prevention of updates in the UI is something t be avoided.
Comment 3 Tod Creasey CLA 2007-02-13 14:18:44 EST
Actually I think I want to think out this more.

As asyncExecs are ordered I think it may be safe to do something using them instead of syncExecs in this case.

I still think you need to be very careful with code in synchronized blocks calling out to the UI in using syncExecs. We can reduce the danger of this by reducing out use of syncExec but we are only one place where you could run into trouble with this.
Comment 4 Eclipse Webmaster CLA 2007-07-29 09:21:45 EDT
Changing OS from Mac OS to Mac OS X as per bug 185991
Comment 5 Martin Oberhuber CLA 2007-09-13 13:23:14 EDT
I've got an actual deadlock (bug 203306) due to this issue, and I have seen similar deadlocks before, and now I understand why this happens.

The problems are, that 
1.) My client has to lock a single shared resource,
2.) I do want to provide progress reporting while holding on to it,
3.) Being an open Framework I cannot avoid being called by others on the
    UI thread (and needing the shared resource there)

With the IProgressMonitor, one is not easily aware of the fact that progress reporting calls out into the UI and may actually block there. I whole-heartedly agree with Martin saying that any kind of progress reporting should never block. 

I'm actually thinking about writing an AsyncProgressMonitor wrapper to work around my situation, where my wrapper would ensure that the wrapped monitor is always called asynchronously. This is problematic though, because I cannot easily decouple from isCanceled(); and, it would be a workaround for my concrete situation only, whereas switching to asyncExec in core Eclipse everywhere would fix it once and for all.

I agree that because asyncExecs are ordered, there is no threat of mixing things up - actually, using ONLY asyncExecs may be safer than a mixture of syncExec and asyncExec.
Comment 6 Martin Oberhuber CLA 2007-09-13 14:35:22 EDT
It's also interesting to note that when it comes to progress reporting in the Job framework, all calls are synchronous without UI until it comes to a progress listener; the progress listener gives UI feedback, e.g. through
   ProgressMonitorFocusJobDialog#getBlockingProgressMonitor()
which always does runAsync().
Comment 7 Tod Creasey CLA 2007-10-11 14:41:02 EDT
Fixed for build >20071011
Comment 8 Tod Creasey CLA 2007-10-29 14:12:08 EDT
Verified in I20071029-0100