| Summary: | Race condition in ModalContext#block when running IRunnableWithProgress in a separate thread | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | [RT] RAP | Reporter: | Phil Xue <phil.xue> | ||||||||
| Component: | JFace | Assignee: | Project Inbox <rap-inbox> | ||||||||
| Status: | RESOLVED DUPLICATE | QA Contact: | |||||||||
| Severity: | normal | ||||||||||
| Priority: | P2 | CC: | digga1404, kristoffer, neubauer | ||||||||
| Version: | 1.3 | ||||||||||
| Target Milestone: | --- | ||||||||||
| Hardware: | PC | ||||||||||
| OS: | Windows XP | ||||||||||
| Whiteboard: | |||||||||||
| Attachments: |
|
||||||||||
Created attachment 172704 [details]
thread dump of UIThread waiting infinitely on ModalContext$ModalContextThread.block()
I appear to have the same issue.
I am doing a getContainer().run(true, false, new IRunnableWithProgress() {...}); in the getNextPage() call. in RAP 1.2.1 it worked fine.
But with 1.3.0 it seems that while the progressbar is updated just fine. Actually switching to the next page requires the user to provoke a screen refresh by resizing something (dialog or window will do)
Created attachment 173054 [details]
a patch to solve race conditions
A patch is attached
Phil, could you create a patch against the CVS HEAD instead of providing the complete class. This will help us to easy evaluate your changes. Created attachment 180631 [details]
A patch against CVS head
Thanks for your thorough analysis, Phil. This is very likely a dup of bug 315418, which has been fixed with bug 327906 in CVS HEAD. Please reopen if the problem persists. *** This bug has been marked as a duplicate of bug 327906 *** |
Build Identifier: 1.3.0.20100615-1704 Symptom: Wizard hangs with all UI components in disabled state. UIThread waits indefinitely on ModalContext$ModalContextThread.block() (thread dump attached) Condition to Reproduce: Run IRunnableWithProgress in a separate thread (ModalContextThread) in Wizard IRunnableContext#Run(true, false, IRunnableWithProgress) Cause: The problem starts from when ModalContext is finishing run() method, in its finally block, it does these 3 things: 1. dispatches all queued events and wait for them to finish before running this run() which does nothing. display.syncExec(new Runnable() { public void run() { // do nothing } }); 2. sets continueEventDispatching to false so the loop will exit in block() continueEventDispatching = false; 3. wakes UIThread force event loop to exit display.asyncExec(null); The UIThread is blocked on ModalContext$ModalContextThread.block()#display.sleep() before (1) was called. When (1) is executed ModalContextThread will be blocked until its empty run() method is called, in the meanwhile this wakes up UIThread from display.sleep() which starts processing queued events with display.readAndDispatch() in UIThread, the last queued event is the empty run() in (1), when its turn comes the ModalContextThread will be waken up to execute the empty run() method and eventually unblocks display.syncExec and continue to (2), at this point of time UIThread and ModalContextThread are running concurrently. Deadlock happens when ModalContextThread finishes (2) and (3) before UIThread enters block()#display.sleep(), which causes UIThread to wait forever. Workaround: 1. set folk to false (run runnable in current thread) 2. move the wizard with mouse drag which initiates an UI update request that would wake the UIThread Reproducible: Always