204333 - Display.post(Event) hangs on GTK (back port to 3.4.x)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
index ca87570..3eaffa6 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
@@ -2897,67 +2897,79 @@
  * 
  */
 public boolean post (Event event) {
-	synchronized (Device.class) {
-		if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
-		if (event == null) error (SWT.ERROR_NULL_ARGUMENT);
-		if (!OS.GDK_WINDOWING_X11()) return false;
-		int /*long*/ xDisplay = OS.GDK_DISPLAY ();
-		int type = event.type;
-		switch (type) {
-			case SWT.KeyDown:
-			case SWT.KeyUp: {
-				int keyCode = 0;
-				int /*long*/ keysym = untranslateKey (event.keyCode);
-				if (keysym != 0) keyCode = OS.XKeysymToKeycode (xDisplay, keysym);
-				if (keyCode == 0) {
-					char key = event.character;
-					switch (key) {
-						case SWT.BS: keysym = OS.GDK_BackSpace; break;
-						case SWT.CR: keysym = OS.GDK_Return; break;
-						case SWT.DEL: keysym = OS.GDK_Delete; break;
-						case SWT.ESC: keysym = OS.GDK_Escape; break;
-						case SWT.TAB: keysym = OS.GDK_Tab; break;
-						case SWT.LF: keysym = OS.GDK_Linefeed; break;
-						default:
-							keysym = key;
+	/*
+	* Get the operating system lock before synchronizing on the device
+	* lock so that the device lock will not be held should another
+	* thread already be in the operating system.  This avoids deadlock
+	* should the other thread need the device lock.
+	*/
+	Lock lock = OS.lock;
+	lock.lock();
+	try {
+		synchronized (Device.class) {
+			if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
+			if (event == null) error (SWT.ERROR_NULL_ARGUMENT);
+			if (!OS.GDK_WINDOWING_X11()) return false;
+			int /*long*/ xDisplay = OS.GDK_DISPLAY ();
+			int type = event.type;
+			switch (type) {
+				case SWT.KeyDown:
+				case SWT.KeyUp: {
+					int keyCode = 0;
+					int /*long*/ keysym = untranslateKey (event.keyCode);
+					if (keysym != 0) keyCode = OS.XKeysymToKeycode (xDisplay, keysym);
+					if (keyCode == 0) {
+						char key = event.character;
+						switch (key) {
+							case SWT.BS: keysym = OS.GDK_BackSpace; break;
+							case SWT.CR: keysym = OS.GDK_Return; break;
+							case SWT.DEL: keysym = OS.GDK_Delete; break;
+							case SWT.ESC: keysym = OS.GDK_Escape; break;
+							case SWT.TAB: keysym = OS.GDK_Tab; break;
+							case SWT.LF: keysym = OS.GDK_Linefeed; break;
+							default:
+								keysym = key;
+						}
+						keyCode = OS.XKeysymToKeycode (xDisplay, keysym);
+						if (keyCode == 0) return false;
 					}
-					keyCode = OS.XKeysymToKeycode (xDisplay, keysym);
-					if (keyCode == 0) return false;
+					OS.XTestFakeKeyEvent (xDisplay, keyCode, type == SWT.KeyDown, 0);
+					return true;
 				}
-				OS.XTestFakeKeyEvent (xDisplay, keyCode, type == SWT.KeyDown, 0);
-				return true;
-			}
-			case SWT.MouseDown:
-			case SWT.MouseMove: 
-			case SWT.MouseUp: {
-				if (type == SWT.MouseMove) {
-					OS.XTestFakeMotionEvent (xDisplay, -1, event.x, event.y, 0);
-				} else {
-					int button = event.button;
-					switch (button) {
-						case 1:
-						case 2:
-						case 3:	break;
-						case 4: button = 6;	break;
-						case 5: button = 7;	break;
-						default: return false;
+				case SWT.MouseDown:
+				case SWT.MouseMove: 
+				case SWT.MouseUp: {
+					if (type == SWT.MouseMove) {
+						OS.XTestFakeMotionEvent (xDisplay, -1, event.x, event.y, 0);
+					} else {
+						int button = event.button;
+						switch (button) {
+							case 1:
+							case 2:
+							case 3:	break;
+							case 4: button = 6;	break;
+							case 5: button = 7;	break;
+							default: return false;
+						}
+						OS.XTestFakeButtonEvent (xDisplay, button, type == SWT.MouseDown, 0);
 					}
-					OS.XTestFakeButtonEvent (xDisplay, button, type == SWT.MouseDown, 0);
+					return true;
 				}
-				return true;
+				/*
+				* This code is intentionally commented. After posting a
+				* mouse wheel event the system may respond unpredictably
+				* to subsequent mouse actions.
+				*/
+//				case SWT.MouseWheel: {
+//					if (event.count == 0) return false;
+//					int button = event.count < 0 ? 5 : 4;
+//					OS.XTestFakeButtonEvent (xDisplay, button, type == SWT.MouseWheel, 0);			
+//				}
 			}
-			/*
-			* This code is intentionally commented. After posting a
-			* mouse wheel event the system may respond unpredictably
-			* to subsequent mouse actions.
-			*/
-//			case SWT.MouseWheel: {
-//				if (event.count == 0) return false;
-//				int button = event.count < 0 ? 5 : 4;
-//				OS.XTestFakeButtonEvent (xDisplay, button, type == SWT.MouseWheel, 0);			
-//			}
+			return false;
 		}
-		return false;
+	} finally {
+		lock.unlock();
 	}
 }