Bug 188320 - Possible Deadlock in JFace ModalContext
Summary: Possible Deadlock in JFace ModalContext
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.2.2   Edit
Hardware: PC Linux-GTK
: P3 normal (vote)
Target Milestone: 3.5 M7   Edit
Assignee: Silenio Quarti CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-05-22 10:17 EDT by Tobias Vogele CLA
Modified: 2009-09-02 07:58 EDT (History)
6 users (show)

See Also:


Attachments
Patch for problem. (1.52 KB, patch)
2007-05-22 13:52 EDT, Silenio Quarti CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Vogele CLA 2007-05-22 10:17:23 EDT
Build ID: M20070212-1330

The inner class ModalContextThread is not threadsafe and sometimes leads to a deadlock, at least under Linux + GTK.

The problem is, that the block() method not always returns, when the run() method is finished. 

Have a look at these two methods:
The block() method is called in the SWT thread and does basically this:

while(continueEventDispatching)
  if (!display.readAndDispatch())
    display.sleep();

The run method is called in an own thread and does (after the execution of the task) basically this:

display.syncExec(new Runnable(){});
continueEventDispatching = false;
display.asyncExec(null);

The asyncExec(null) should wake up the SWT thread from display.sleep(). 
Unfortunately, this does not work, when the asyncExec() is executed exactly between the display.readAndDispatch() and the display.sleep(). This can happen, because there is no synchronisation. In this case the display.sleep() does not return immediately, but waits for the next event, which may come never.

You can see the same problem in the following code snippet:

  public static void main(String[] args) throws InterruptedException {
    final Shell shell = new Shell();
    while(true){
      if (! shell.getDisplay().readAndDispatch()){
        Thread async = new Thread(){
          public void run() {
            shell.getDisplay().asyncExec(null);
          }
        };
        async.start();
        async.join();
        System.out.println("sleep");
        shell.getDisplay().sleep();
        System.out.println("wakeup");
      }
    }
  }


A fix for this problem would be to call 
  display.asyncExec(new Runnable(){
    public void run(){
    }
  });
In contrast to using the null argument, this Runnable generates a real event instead of just waking up the SWT thread. So the SWT thread does not really begin to sleep.
Comment 1 Steve Northover CLA 2007-05-22 12:48:21 EDT
This one is ours.
Comment 2 Steve Northover CLA 2007-05-22 12:50:13 EDT
Consider for 3.3 RC2.
Comment 3 Silenio Quarti CLA 2007-05-22 13:52:35 EDT
Created attachment 68179 [details]
Patch for problem.
Comment 4 Dieter Leinweber CLA 2008-02-01 13:17:01 EST
It seems that the bug is still alive. I have an application that worked well until end of last year. Then there was a hardware failure. The new hardware is dual core and runs under a 64 bit Linux, with Eclipse 3.3.1.1 (compared to single core and 32 bit Linux before).

The application uses ModalContext quite often. On the new hardware the application sometimes seems to hang. As soon as I move the mouse the application continues. The same application still runs without problems on a single core 32 bit Windows machine (Eclipse 3.3.1.1).

I've played around a little bit and tested something like

        try {
            ModalContext.run(new IRunnableWithProgress() {
                public void run(IProgressMonitor monitor)
                        throws InvocationTargetException,
                               InterruptedException {
                    System.out.println("Start");

                    // Do something here...

                    System.out.println("Stop");

                    throw new InterruptedException("Dummy");
                }
            }, true, new NullProgressMonitor(), SWTBase.getDisplay());
        } catch (Exception e) {
            e.printStackTrace();
        }

If the "hang" occurs, the real work is already done, the "Stop" was printed, but the Exception is not thrown. 

As all the real work completes successfully. it seems to me that something goes wrong in the ModalContext.run() method. I'm assuming that it must have to do something with the dual core hardware.

Comment 5 Steve Northover CLA 2008-02-01 17:00:12 EST
Silenio, please put the patch in or use the same solution that we used for the same problem on Mac Leopard.
Comment 6 Feng Yao Yao CLA 2009-03-10 04:01:49 EDT
I still see this problem in SWT-GTK 3.4. 

https://bugs.eclipse.org/bugs/show_bug.cgi?id=266985
Comment 7 Steve Northover CLA 2009-03-10 17:17:15 EDT
Let's fix this for 3.5 M7.
Comment 8 Bogdan Gheorghe CLA 2009-04-13 11:10:15 EDT
Fixed in HEAD > 20090413