--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
xlib.timeout.diff
Description: Mac BinHex archive