Bug 266985 - ModalContextThread may be blocked in Display.sleep in Linux
Summary: ModalContextThread may be blocked in Display.sleep in Linux
Status: CLOSED WONTFIX
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.4.1   Edit
Hardware: PC Linux-GTK
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Bogdan Gheorghe CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords:
: 528941 (view as bug list)
Depends on:
Blocks:
 
Reported: 2009-03-04 04:15 EST by Feng Yao Yao CLA
Modified: 2020-04-14 02:33 EDT (History)
5 users (show)

See Also:


Attachments
the incorrect sequence (47.18 KB, image/jpeg)
2009-03-04 04:17 EST, Feng Yao Yao CLA
no flags Details
the correct sequence (47.55 KB, image/jpeg)
2009-03-04 04:18 EST, Feng Yao Yao CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Feng Yao Yao CLA 2009-03-04 04:15:22 EST
Build ID: 3.4

Steps To Reproduce:
Run a ModalContext in a plugin's stop function. At that time all the shells in the dispaly have been disposed.
ModalContext may be blocked in display.sleep because of unexpected sequence.


When ModalContextThread is running, the main thread sleep until ModalContextThread is completed.

Sequence when operation is finished in ModalContextThread is:
1.1 ModalContextThread completes the operation, and calls display.syncExec to wake up the display.
1.2 ModalContextThread set a flag "continueEventDispatching" as false, so that main thread would not continue to readAndDispatch and sleep.
1.3 ModalContextThread call display.asyncExec to force the event loop to retrun from sleep.

Sequence when operation is finished in Main thread is:
2.1 display is waken up by ModalContextThread;
2.2 check the flag continueEventDispatching to decide if continue to dispatch event;
2.3 if continueEventDispatching is true, display read and dispatch event 
2.4 display.sleep until waken up or get some messages and go to 2.1.

The incorrect sequence would be 1.1 - 2.1 - 2.2 - 1.2 - 2.3 - 1.3 - 2.4. That means:
-> Main thread is waken up (1.1). 
->Then main thread continue to readAndDispatch events(2.3) since 1.2 has not been done. 
->And then ModalContextThread set continueEventDispatching as false(1.2), and wake up dispaly (1.3). <Please notice that display has not sleep now>. 
->Then display sleep and can never be waken up. 

The same sequence would not cause block on Windows, because display.wakeThread post a null message to the thread. display.sleep would get this message and return.

But on Linux, display.wakeThread calls g_main_context_wakeup which is to interrupt the poll() called in display.sleep. That means if wakeThread is called before display.sleep, or called in display.sleep but before poll function is called, it would not wake up display.

Stack is like this:
4XESTACKTRACE          at org/eclipse/swt/internal/gtk/OS.Call(Native Method)
4XESTACKTRACE          at org/eclipse/swt/widgets/Display.sleep(Bytecode PC:265(Compiled Code))
4XESTACKTRACE          at org/eclipse/jface/operation/ModalContext$ModalContextThread.block(Bytecode PC:29)
4XESTACKTRACE          at org/eclipse/jface/operation/ModalContext.run(Bytecode PC:131)
4XESTACKTRACE          at myTest/ModalContextUtil.run(Bytecode PC:136)
4XESTACKTRACE          at myTest/MyTestPlugin.stop(Bytecode PC:87)
4XESTACKTRACE          at org/eclipse/osgi/framework/internal/core/BundleContextImpl$3.run(Bytecode PC:23)
4XESTACKTRACE          at java/security/AccessController.doPrivileged(Bytecode PC:3)
4XESTACKTRACE          at org/eclipse/osgi/framework/internal/core/BundleContextImpl.stop(Bytecode PC:8)
4XESTACKTRACE          at org/eclipse/osgi/framework/internal/core/BundleHost.stopWorker(Bytecode PC:129)
4XESTACKTRACE          at org/eclipse/osgi/framework/internal/core/AbstractBundle.suspend(Bytecode PC:15)
4XESTACKTRACE          at org/eclipse/osgi/framework/internal/core/Framework.suspendBundle(Bytecode PC:46)
4XESTACKTRACE          at org/eclipse/osgi/framework/internal/core/StartLevelManager.decFWSL(Bytecode PC:139)
4XESTACKTRACE          at org/eclipse/osgi/framework/internal/core/StartLevelManager.doSetStartLevel(Bytecode PC:337)
4XESTACKTRACE          at org/eclipse/osgi/framework/internal/core/StartLevelManager.shutdown(Bytecode PC:2)
4XESTACKTRACE          at org/eclipse/osgi/framework/internal/core/SystemBundle.suspend(Bytecode PC:7)
4XESTACKTRACE          at org/eclipse/osgi/framework/internal/core/Framework.shutdown(Bytecode PC:74)
4XESTACKTRACE          at org/eclipse/osgi/framework/internal/core/Framework.close(Bytecode PC:8)
4XESTACKTRACE          at org/eclipse/osgi/framework/internal/core/OSGi.close(Bytecode PC:4)
4XESTACKTRACE          at org/eclipse/core/runtime/adaptor/EclipseStarter.shutdown(Bytecode PC:89)
4XESTACKTRACE          at org/eclipse/core/runtime/adaptor/EclipseStarter.run(Bytecode PC:217)
4XESTACKTRACE          at sun/reflect/NativeMethodAccessorImpl.invoke0(Native Method)
4XESTACKTRACE          at sun/reflect/NativeMethodAccessorImpl.invoke(Bytecode PC:115)
4XESTACKTRACE          at sun/reflect/DelegatingMethodAccessorImpl.invoke(Bytecode PC:6)
4XESTACKTRACE          at java/lang/reflect/Method.invoke(Bytecode PC:163)
4XESTACKTRACE          at org/eclipse/equinox/launcher/Main.invokeFramework(Bytecode PC:211)
4XESTACKTRACE          at org/eclipse/equinox/launcher/Main.basicRun(Bytecode PC:114)
4XESTACKTRACE          at org/eclipse/equinox/launcher/Main.run(Bytecode PC:4)
4XESTACKTRACE          at com/ibm/rcp/core/internal/launcher/Main.startLaunch(Bytecode PC:171)
4XESTACKTRACE          at com/ibm/rcp/core/internal/launcher/Main.main(Bytecode PC:171)
4XESTACKTRACE          at com/ibm/rcp/core/internal/launcher/Main.run(Bytecode PC:1)
Comment 1 Feng Yao Yao CLA 2009-03-04 04:17:43 EST
Created attachment 127446 [details]
the incorrect sequence
Comment 2 Feng Yao Yao CLA 2009-03-04 04:18:35 EST
Created attachment 127447 [details]
the correct sequence
Comment 3 Felipe Heidrich CLA 2009-03-04 17:47:39 EST
SSQ, do you know about this problem ?

In Display().sleep() I see this comment:

/*
* Bug in GTK. For some reason, g_main_context_wakeup() may 
* fail to wake up the UI thread from the polling function.
* The fix is to sleep for a maximum of 50 milliseconds.
*/

Can you attach your testcase that shows a deadlock ?
Comment 4 Feng Yao Yao CLA 2009-03-04 21:09:12 EST
Following is the test code:

import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.operation.*;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class ModalContextTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Display display = new Display();
		
		IRunnableWithProgress runnable = new IRunnableWithProgress(){

			public void run(IProgressMonitor monitor) throws InvocationTargetException,
					InterruptedException {
				System.out.println("I'm running");
				Thread.currentThread().sleep(50);	
				System.out.println("I return");
			}};
		try {
			ModalContext.run(runnable, true, new NullProgressMonitor(), display);
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.println("done!");
		display.dispose();
	}
	
	
}


You know this is very difficult to reproduce. To reproduce the incorrect sequence easily, I add some code in display.sleep like this:

		if (OS.g_main_context_acquire (context)) {
			result = OS.g_main_context_prepare (context, max_priority);
			int nfds;
			while ((nfds = OS.g_main_context_query (context, max_priority [0], timeout, fds, allocated_nfds)) > allocated_nfds) {
				OS.g_free (fds);
				allocated_nfds = nfds;
				fds = OS.g_malloc (OS.GPollFD_sizeof() * allocated_nfds);
			}
			////////////////////my code////////////////////
			try {
				Thread.currentThread().sleep(50);
				System.out.println("poll will start and wake is "+ wake);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			//////////////////my code end/////////////////
			int /*long*/ poll = OS.g_main_context_get_poll_func (context);
Comment 5 Feng Yao Yao CLA 2009-03-04 21:22:07 EST
I don't think this is caused by GTK bug. Following is display.wakeThread:
void wakeThread () {
	OS.g_main_context_wakeup (0);
	wake = true;
}

But as I said, g_main_context_wakeup can only wake up the poll function but the sleeping display.

On Windows, you can find wakeThread would post a thread message, so display.sleep can receive message and be waken up in any case.
Comment 6 Feng Yao Yao CLA 2009-03-05 21:38:08 EST
I find another report about this problem: 188320

It was reported for 3.2.2 and the patch was provided. But obviously it has not been put in 3.4.1.
Comment 7 Andrey Rodionov CLA 2012-08-13 10:02:30 EDT
This issue reproduces from time to time. Eclipse completely hangs.

OS: Ubuntu 12.04
Eclipse Version: 4.2.0
Eclipse Build id: I20120608-1400

Seems like something from unity caused this bug to occur more frequently.

Here is jstack:

"main" prio=10 tid=0x00007f63d8008000 nid=0x8ad runnable [0x00007f63dda63000]
   java.lang.Thread.State: RUNNABLE
	at org.eclipse.swt.internal.gtk.OS.Call(Native Method)
	at org.eclipse.swt.widgets.Display.sleep(Display.java:4036)
	at org.eclipse.ui.application.WorkbenchAdvisor.eventLoopIdle(WorkbenchAdvisor.java:364)
	at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor.eventLoopIdle(IDEWorkbenchAdvisor.java:917)
	at org.eclipse.ui.internal.Workbench$3.eventLoopIdle(Workbench.java:459)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1026)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:916)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:86)
	at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:585)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:540)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:124)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:353)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:629)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1414)
Comment 8 Klemen Živkovič CLA 2017-12-19 05:09:09 EST
Same here.

"main" #1 prio=6 os_prio=0 tid=0x00007f72dc00a000 nid=0x7443 runnable [0x00007f72e3e30000]
   java.lang.Thread.State: RUNNABLE
        at org.eclipse.swt.internal.gtk.OS.Call(Native Method)
        at org.eclipse.swt.widgets.Display.sleep(Display.java:5066)
        at org.eclipse.ui.application.WorkbenchAdvisor.eventLoopIdle(WorkbenchAdvisor.java:368)
        at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor.eventLoopIdle(IDEWorkbenchAdvisor.java:888)
        at org.eclipse.ui.internal.Workbench$3.eventLoopIdle(Workbench.java:526)
        at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1126)
        at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336)
        at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022)
        at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150)
        at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693)
        at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336)
        at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610)
        at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148)
        at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138)
        at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
        at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
        at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
        at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388)
        at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673)
        at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610)
        at org.eclipse.equinox.launcher.Main.run(Main.java:1519)
        at org.eclipse.equinox.launcher.Main.main(Main.java:1492)

   Locked ownable synchronizers:
        - None



wmctrl -m
Name: Compiz
Class: N/A
PID: N/A
Window manager's "showing the desktop" mode: OFF

uname -a
Linux debian-kz 4.9.0-4-amd64 #1 SMP Debian 4.9.51-1 (2017-09-28) x86_64 GNU/Linux
Comment 9 Klemen Živkovič CLA 2017-12-19 05:26:48 EST
Using:

Eclipse Platform
Version: 4.6.3.v20170301-0400
Build id: M20170301-0400
Comment 10 Karsten Thoms CLA 2018-04-23 15:38:03 EDT
*** Bug 528941 has been marked as a duplicate of this bug. ***
Comment 11 Eclipse Genie CLA 2020-04-14 02:33:04 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug.

If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.