Rob Braun observed the following issue with XCloseDisplay() hanging indefinitely. Any comments?

--Torrey

At 12:11 AM -0700 9/20/03, Rob Braun wrote:
From: Rob Braun <[EMAIL PROTECTED]>
To: [EMAIL PROTECTED]
Subject: XWaitForReadable timeout

Howdy.  While running osx2x, I came across an interesting timeout issue
in libX11's XWaitForReadable() function.  The background on the issue
is that osx2x is essentially x2x, but with the source side being OS X.
I fired this up at home, and have been using it quite successfully.
However, I noticed that if the target X11 machine went offline, or
otherwise uncleanly left the network (in this case, it got a different
DHCP address on renew), I couldn't disconnect from that machine, and
osx2x would hang forever.

On inspection, osx2x was trying to disconnect from the remote display
by doing an XCloseDisplay(), which would eventually call down to
XWaitForReadable().  There, libX11 was looping on select.  So, I
added a timeout to the select() call, and if the select() timed out,
then something bad has happened, and XWaitForReadable() errors out.
This appears to be the correct behavior under such conditions.

The alternative is to wait for the TCP socket to timeout, which will
take roughly 90 seconds.  This is waaaay too long for an interactive
app, in my opinion.  The timeout I used in the call to select() was
5 seconds, which I'm sure people can argue over, but it seemed a
reasonable value to pick.

Anyway, I thought I'd alert you to the issue, and I've attached the
patch I used to fix the problem.  It seems like XCloseDisplay(),
and XSync() should be able to take timeouts as arguments...

Rob

Index: XlibInt.c
===================================================================
RCS file: /cvs/xc/lib/X11/XlibInt.c,v
retrieving revision 3.37
diff -u -d -r3.37 XlibInt.c
--- XlibInt.c 23 May 2003 14:38:27 -0000 3.37
+++ XlibInt.c 20 Sep 2003 06:58:20 -0000
@@ -476,7 +476,10 @@
#endif
for (;;) {
#ifndef USE_POLL
+ struct timeval tv;
FD_SET(fd, &r_mask);
+ tv.tv_sec = 5;
+ tv.tv_usec = 0;
if (!(dpy->flags & XlibDisplayProcConni))
for (ilist=dpy->im_fd_info; ilist; ilist=ilist->next) {
FD_SET(ilist->fd, &r_mask);
@@ -490,12 +493,16 @@
(dpy->flags & XlibDisplayProcConni) ? 1 : 1+dpy->im_fd_length,
-1);
#else
- result = Select(highest_fd + 1, &r_mask, NULL, NULL, NULL);
+ result = Select(highest_fd + 1, &r_mask, NULL, NULL, &tv);
#endif
InternalLockDisplay(dpy, dpy->flags & XlibDisplayReply);
if (result == -1 && !ECHECK(EINTR)) _XIOError(dpy);
- if (result <= 0)
+ if (result < 0)
+ continue;
+ if (result == 0 && ECHECK(EINTR))
continue;
+ if (result == 0)
+ _XIOError(dpy);
#ifdef USE_POLL
if (filedes[0].revents & (POLLIN|POLLHUP|POLLERR))
#else

Attachment: xlib.timeout.diff
Description: Mac BinHex archive



Reply via email to