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