Hi all

Attached are a couple of patches to get MWF working on Solaris 10.  The
first works around the problem of missing methods in the native X
libraries: Xutf8ResetIC() and Xutf8LookupString().

The second patch would also assist any other slow systems that have
small network buffers.  The wake/wake_receive socket pair can deadlock
if too many wake packets are sent while the XEvent loop in
UpdateMessageQueue() is processing a large number of events, causing the
wake_receive poll to be delayed.  On Solaris, if more than 10 wake
packets are buffered it will deadlock.  The patch just makes the wake
socket non-blocking, on the grounds that it doesn't really matter how
many prods the loop gets so long as it wakes up once.

OK to commit these?

- Dick

diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Keyboard.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Keyboard.cs
index fc0c7fe..4ad67fc 100644
--- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Keyboard.cs
+++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Keyboard.cs
@@ -208,6 +208,8 @@ namespace System.Windows.Forms {
 				XSetICFocus (xic);
 		}
 
+		private bool have_Xutf8ResetIC = true;
+
 		public void FocusOut (IntPtr window)
 		{
 			if (xim == IntPtr.Zero)
@@ -216,7 +218,13 @@ namespace System.Windows.Forms {
 			this.client_window = IntPtr.Zero;
 			IntPtr xic = GetXic (window);
 			if (xic != IntPtr.Zero) {
-				Xutf8ResetIC (xic);
+				if (have_Xutf8ResetIC) {
+					try {
+						Xutf8ResetIC (xic);
+					} catch (EntryPointNotFoundException) {
+						have_Xutf8ResetIC = false;
+					}
+				}
 				XUnsetICFocus (xic);
 			}
 		}
@@ -1173,6 +1181,8 @@ namespace System.Windows.Forms {
 			}
 		}
 
+		private bool have_Xutf8LookupString = true;
+
 		private int LookupString (ref XEvent xevent, int len, out XKeySym keysym, out IntPtr status)
 		{
 			IntPtr keysym_res;
@@ -1180,9 +1190,26 @@ namespace System.Windows.Forms {
 
 			status = IntPtr.Zero;
 			IntPtr xic = GetXic (client_window);
-			if (xic != IntPtr.Zero) {
+			if (xic != IntPtr.Zero && have_Xutf8LookupString) {
 				do {
-					res = Xutf8LookupString (xic, ref xevent, lookup_byte_buffer, 100, out keysym_res,  out status);
+					try {
+						res = Xutf8LookupString (xic, ref xevent, lookup_byte_buffer, 100, out keysym_res,  out status);
+					} catch (EntryPointNotFoundException) {
+						have_Xutf8LookupString = false;
+
+						/* Duplicate of the non-xic clause */
+						do {
+							res = XLookupString (ref xevent, lookup_byte_buffer, 100, out keysym_res, out status);
+							if ((int) status != -1) // XLookupBufferOverflow
+								break;
+							lookup_byte_buffer = new byte [lookup_byte_buffer.Length << 1];
+						} while (true);
+						lookup_buffer.Length = 0;
+						string s2 = Encoding.ASCII.GetString (lookup_byte_buffer, 0, res);
+						lookup_buffer.Append (s2);
+						keysym = (XKeySym) keysym_res.ToInt32 ();
+						return res;
+					}
 					if ((int) status != -1) // XLookupBufferOverflow
 						break;
 					lookup_byte_buffer = new byte [lookup_byte_buffer.Length << 1];
diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs
index 2890de6..d00c40d 100644
--- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs
+++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs
@@ -499,6 +499,12 @@ namespace System.Windows.Forms {
 
 				wake = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
 				wake.Connect(listen.LocalEndPoint);
+
+				// Make this non-blocking, so it doesn't
+				// deadlock if too many wakes are sent
+				// before the wake_receive end is polled
+				wake.Blocking = false;
+
 				wake_receive = listen.Accept();
 
 				#if __MonoCS__
@@ -1230,7 +1236,13 @@ namespace System.Windows.Forms {
 		}
 
 		void WakeupMain () {
-			wake.Send (new byte [] { 0xFF });
+			try {
+				wake.Send (new byte [] { 0xFF });
+			} catch (SocketException ex) {
+				if (ex.SocketErrorCode != SocketError.WouldBlock) {
+					throw;
+				}
+			}
 		}
 
 		XEventQueue ThreadQueue(Thread thread) {
_______________________________________________
Mono-winforms-list maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-winforms-list

Reply via email to