Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 315418 - Progress Dialog will not automatically close during UICallback
Summary: Progress Dialog will not automatically close during UICallback
Status: RESOLVED FIXED
Alias: None
Product: RAP
Classification: RT
Component: Workbench (show other bugs)
Version: 1.3   Edit
Hardware: All All
: P1 normal (vote)
Target Milestone: 1.4 M3   Edit
Assignee: Ralf Sternberg CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on: 327906
Blocks:
  Show dependency tree
 
Reported: 2010-06-02 12:17 EDT by Austin Riddle CLA
Modified: 2010-10-18 07:45 EDT (History)
3 users (show)

See Also:


Attachments
Sample project illustrating the problem (463.03 KB, application/x-zip-compressed)
2010-06-02 12:17 EDT, Austin Riddle CLA
no flags Details
Fix for the progress dialog hanging during a UICallback (1.14 KB, patch)
2010-08-11 18:21 EDT, Austin Riddle CLA
no flags Details | Diff
Fix for progress dialog hang and delay in closing during a UICallback (2.75 KB, patch)
2010-10-08 13:02 EDT, Austin Riddle CLA
no flags Details | Diff
Example application to reproduce the problem (12.46 KB, application/octet-stream)
2010-10-13 08:57 EDT, Ralf Sternberg CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Austin Riddle CLA 2010-06-02 12:17:36 EDT
Created attachment 170829 [details]
Sample project illustrating the problem

Version: CVS HEAD

Symptoms:  When a progress dialog is opened either via PlatformUI progress service or ProgressDialog directly and a UICallback is active at the time, then the progress dialog must be manually "moved" before it will close when the tasks are done.

Steps to reproduce:

Use sample project, and click on the file menu option called "Show Progress".
Do this a few times and you will find that the progress dialog will stay open even though the tasks are finished.

If you comment out lines 60-64 of Application.java within the sample project (remove the ui callback), then the progress dialog will work fine.

This causes our users to sit and wait for a long time while they are trying to determine what is going on.
Comment 1 Austin Riddle CLA 2010-07-16 13:52:36 EDT
(In reply to comment #0)

Has anyone been able to reproduce this with the attached sample project?
Comment 2 Ivan Furnadjiev CLA 2010-07-16 15:50:29 EDT
Yes... I did, but unable to find the reason after short debugging.
Comment 3 Austin Riddle CLA 2010-07-16 17:13:26 EDT
This issue also occurs in wizards using the progress bar in the container. The wizard will just sit there until moved.  If there is a next page, the wizard will not show the next page until moved. If not (a click on finish spawned the progress), the wizard dialog will stay up until moved.  Hope this helps.
Comment 4 Austin Riddle CLA 2010-08-03 12:50:37 EDT
This is a very important bug for us because our clients mistakenly think that the app is hung, which is somewhat embarrassing, since we can't really tell all of our users to just "move" the dialog to make it go away.

I was doing some more testing and found some interesting behavior.  The first time I use the progress dialog I get the following in my client side log for the progress steps:

021352 DEBUG: org.eclipse.swt.Request[38]: sending request [ org.eclipse.swt.events.widgetSelected=w73; w73.bounds.x=null; w73.bounds.y=null; w73.bounds.width=auto; w73.bounds.height=auto; w5.activeControl=w5; org.eclipse.swt.events.menuHidden=w8; w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=4; ]021506 DEBUG: org.eclipse.swt.Request[38]: sending request [ 1018858233=34,13; 2063204500=54,13; 859583391=375,13; 895559168=386,13; 2097538400=123,13; w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=5; ]022464 DEBUG: org.eclipse.swt.Request[38]: sending request [ w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=6; ]022540 DEBUG: org.eclipse.swt.Request[38]: sending request [ 1595229976=34,13; w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=7; ]023457 DEBUG: org.eclipse.swt.Request[38]: sending request [ w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=8; ]023537 DEBUG: org.eclipse.swt.Request[38]: sending request [ 2136239237=34,13; w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=9; ]024462 DEBUG: org.eclipse.swt.Request[38]: sending request [ w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=10; ]024535 DEBUG: org.eclipse.swt.Request[38]: sending request [ 291328829=34,13; w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=11; ]025457 DEBUG: org.eclipse.swt.Request[38]: sending request [ w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=12; ]025532 DEBUG: org.eclipse.swt.Request[38]: sending request [ 869413585=34,13; w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=13; ]026455 DEBUG: org.eclipse.swt.Request[38]: sending request [ w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=14; ]026533 DEBUG: org.eclipse.swt.Request[38]: sending request [ 940566724=34,13; w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=15; ]027455 DEBUG: org.eclipse.swt.Request[38]: sending request [ w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=16; ]027530 DEBUG: org.eclipse.swt.Request[38]: sending request [ 1191201656=34,13; w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=17; ]028467 DEBUG: org.eclipse.swt.Request[38]: sending request [ w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=18; ]028551 DEBUG: org.eclipse.swt.Request[38]: sending request [ 1590384136=34,13; w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=19; ]029469 DEBUG: org.eclipse.swt.Request[38]: sending request [ w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=20; ]029543 DEBUG: org.eclipse.swt.Request[38]: sending request [ 1686549717=34,13; w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=21; ]030467 DEBUG: org.eclipse.swt.Request[38]: sending request [ w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=22; ]030547 DEBUG: org.eclipse.swt.Request[38]: sending request [ 1040167659=34,13; w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=23; ]031463 DEBUG: org.eclipse.swt.Request[38]: sending request [ w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=24; ]031540 DEBUG: org.eclipse.swt.Request[38]: sending request [ 1675460918=34,13; w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=25; ]-

-------------------------------------------------------------------------------
The second time I use the dialog, it hangs as described with the following entries in the log for the progress steps:
-------------------------------------------------------------------------------
036022 DEBUG: org.eclipse.swt.Request[38]: sending request [ w5.activeControl=w5; org.eclipse.swt.events.menuShown=w8; w1.cursorLocation.x=18; w1.cursorLocation.y=28; w1.focusControl=w7; uiRoot=w1; requestCounter=26; ]036920 DEBUG: org.eclipse.swt.Request[38]: sending request [ org.eclipse.swt.events.widgetSelected=w73; w73.bounds.x=null; w73.bounds.y=null; w73.bounds.width=auto; w73.bounds.height=auto; w5.activeControl=w5; org.eclipse.swt.events.menuHidden=w8; w1.cursorLocation.x=27; w1.cursorLocation.y=65; uiRoot=w1; requestCounter=27; ]037047 DEBUG: org.eclipse.swt.Request[38]: sending request [ w1.cursorLocation.x=27; w1.cursorLocation.y=65; uiRoot=w1; requestCounter=28; ]037126 DEBUG: org.eclipse.swt.Request[38]: sending request [ 627988622=37,13; w1.cursorLocation.x=27; w1.cursorLocation.y=66; uiRoot=w1; requestCounter=29; ]038001 DEBUG: org.eclipse.swt.Request[38]: sending request [ w1.cursorLocation.x=-1; w1.cursorLocation.y=-1; uiRoot=w1; requestCounter=30; ]038997 DEBUG: org.eclipse.swt.Request[38]: sending request [ w1.cursorLocation.x=-1; w1.cursorLocation.y=-1; uiRoot=w1; requestCounter=31; ]039994 DEBUG: org.eclipse.swt.Request[38]: sending request [ w1.cursorLocation.x=-1; w1.cursorLocation.y=-1; uiRoot=w1; requestCounter=32; ]040995 DEBUG: org.eclipse.swt.Request[38]: sending request [ w1.cursorLocation.x=-1; w1.cursorLocation.y=-1; uiRoot=w1; requestCounter=33; ]042014 DEBUG: org.eclipse.swt.Request[38]: sending request [ w1.cursorLocation.x=-1; w1.cursorLocation.y=-1; uiRoot=w1; requestCounter=34; ]043007 DEBUG: org.eclipse.swt.Request[38]: sending request [ w1.cursorLocation.x=-1; w1.cursorLocation.y=-1; uiRoot=w1; requestCounter=35; ]044004 DEBUG: org.eclipse.swt.Request[38]: sending request [ w1.cursorLocation.x=-1; w1.cursorLocation.y=-1; uiRoot=w1; requestCounter=36; ]045006 DEBUG: org.eclipse.swt.Request[38]: sending request [ w1.cursorLocation.x=-1; w1.cursorLocation.y=-1; uiRoot=w1; requestCounter=37; ]046002 DEBUG: org.eclipse.swt.Request[38]: sending request [ w1.cursorLocation.x=-1; w1.cursorLocation.y=-1; uiRoot=w1; requestCounter=38; ]047000 DEBUG: org.eclipse.swt.Request[38]: sending request [ w1.cursorLocation.x=-1; w1.cursorLocation.y=-1; uiRoot=w1; requestCounter=39; ]

-------------------------------------------------------------------------------
Then after I move the dialog I receive the following and the dialog disappears.
-------------------------------------------------------------------------------
064541 DEBUG: org.eclipse.swt.Request[38]: sending request [ w86.activeControl=w86; w86.bounds.x=338; w86.bounds.y=292; w1.cursorLocation.x=576; w1.cursorLocation.y=301; w1.focusControl=w86; uiRoot=w1; requestCounter=40; ]


Notice that there are double the amount of requests when the dialog is working properly and that the format of the missing requests is like:

[ 1191201656=34,13; w1.cursorLocation.x=50; w1.cursorLocation.y=69; uiRoot=w1; requestCounter=17; ]

Any thoughts?
Comment 5 Austin Riddle CLA 2010-08-11 18:21:18 EDT
Created attachment 176415 [details]
Fix for the progress dialog hanging during a UICallback

This patch fixes the issue.  What was happening is that when the display thread was sleeping during the progress operation, the lock was never woken up from its wait() call because of the test on the size that was returned from IdManager.getInstance().remove( id ) in deactivateUICallBacksFor(id) from ModalContextThread.run().

The remove() call would return the size of the list of active UI callback ids, which would include the original/existing UI Callback AND the one created from UICallBackServiceHandler.activateUICallBacksFor( key ) in ModalContext.run(...).

So since the code would only send a UI callback if size == 0, the progress dialog would not terminate.

In other words, the ModalContext.run(...) method would block until all of the UICallbacks were removed from the IdManager, which would not happen.

I think that this is the right change to fix the problem and does not seem to have any undesirable results.
Comment 6 Rüdiger Herrmann CLA 2010-08-12 15:02:40 EDT
Thanks a lot for the patch and for investigating this. I can look into the patch not before mid September (vacation and other things)
I assume that you are working against CVS HEAD and thus the delay doesn't hurt you much.
Comment 7 Austin Riddle CLA 2010-08-12 15:51:51 EDT
We maintain our own set of patches/changes to the target platform, so the delay does not affect us per se.

I am sure you all are very busy.  You all are doing a good job and I appreciate when people do have an initial/triage look at bugs and provide some feedback to indicate that it has not just been sent to /dev/null ;)

Keep up the good work!
Comment 8 Austin Riddle CLA 2010-10-08 13:02:26 EDT
Created attachment 180502 [details]
Fix for progress dialog hang and delay in closing during a UICallback

Hi Ivan,

The patch I just uploaded in conjunction with Tim's patch in bug #301261 resolves this issue for us.  In the sample project, the progress dialog can be started multiple times and it will always close when it is finished. It also works in our app. If you want to talk more about the changes in this patch just let me know. Hopefully this can make it into HEAD soon.
Comment 9 Ralf Sternberg CLA 2010-10-13 08:43:35 EDT
Hi Austin,

first, thanks a lot for raising this issue and providing test code and patches! I reduced the code to a naked application that only reproduces the UICallBack problem described here.

Regarding your change to UICallBackServiceHandler#deactivateUICallBacksFor():
I see that your change solves this problem, but I'm not convinced that the fix is in the right place. The idea of activating / deactivating the UICallBack by id is that the UICallBack mechanism is kept alive as long as it is needed by someone. When the ModalContext calls the deactivate method, it thereby signals that it does not need the UICallback anymore. But since the Application class also expressed interest in it by calling activate with another id, that means that the standing request is still needed (size == 1). So there is no need for deactivateUICallBacksFor() to disable the standing request. Why should it call sendUICallBack() then?

I think the problem is that sometimes the UICallBack is blocked although there are still changes to render. That seems to be a case that is not correctly handled in the UICallBackManager. However, this issue needs further investigation.
Comment 10 Ralf Sternberg CLA 2010-10-13 08:57:00 EDT
Created attachment 180762 [details]
Example application to reproduce the problem
Comment 11 Ralf Sternberg CLA 2010-10-13 08:59:02 EDT
(In reply to comment #4)
Austin, I think that these observations are related to the TextSizeDetermination rather than to this problem. In the first run after restarting the server, the strings "Task: 0", "Task: 1", etc. are measured on the client and the actual sizes are transferred to the server in separate requests. This causes the double requests in the first run and the parameters like "1191201656=34,13;". In subsequent runs, the sizes are already cached on the server.
Comment 12 Cole Markham CLA 2010-10-13 10:33:29 EDT
(In reply to comment #9)
Ralf,

The latest patch represents two separate attempts on our part to fix the issue. It is quite possible that deactivateUICallBacksFor does not need to be changed after the patch to ModalContext.
Comment 13 Austin Riddle CLA 2010-10-13 10:36:55 EDT
(In reply to comment #9)
Hi Ralf, 

Sorry about the original bloated sample project.  I tend to work on multiple things at a time and my BugDemo bundle is the junk project for reproducing bugs. Next time I will try to only include the necessary code to reproduce the problem.
Comment 14 Ralf Sternberg CLA 2010-10-13 16:56:53 EDT
(In reply to comment #12)
Hi Cole, indeed your modification in ModalContext seems to fix the problem without the need for changing UICallBackServiceHandler. I first overlooked this part because this is original JFace code and I didn't see why we should change it. But on a closer look, it seems to be broken in JFace indeed - the variable continueEventDispatching is shared between different threads (read by UIThread, written by ModalContextThread) without synchronization, right? I'll look at it again tomorrow ;-)
Comment 15 Ralf Sternberg CLA 2010-10-13 16:57:20 EDT
(In reply to comment #13)
Hi Austin,
no worries! It's great to have a piece of code to reproduce. But I found it easier for testing to cut out everything that might distract me ;-)
Comment 16 Ralf Sternberg CLA 2010-10-15 11:30:47 EDT
This problem is caused by Display#wake not working properly while the UIThread is running. I opened bug 327906 for this problem.
Display#wake is indirectly called by display.asyncExec(null) in the ModalContextThread's run method (line 164).
Comment 17 Ralf Sternberg CLA 2010-10-18 07:45:21 EDT
This bug should be fixed by the change to bug 327906. Please reopen if you can still reproduce the problem.