ado@elsie.UUCP (07/12/88)
VERSION:
X11 release 2
CLIENT MACHINE:
Sun 3/160
CLIENT OPERATING SYSTEM:
Sun UNIX 4.2 Release 3.5
DISPLAY:
Sun B&W
SYNOPSIS:
Clients can terminate abnormally (and erroneously) if the server
falls behind.
DESCRIPTION:
The problem comes about when the socket buffer fills up (at the 4096
character mark on an as-shipped 3.5 system). When this happens,
writes to the socket return EMSGSIZE in errno (rather than,
for example, EWOULDBLOCK).
The function in XlibInt.c that handles output notices the EMSGSIZE
error and gets into a loop where it halves the write size each time
through. When the write size drops to zero, errno is set to EINVAL
and the client punts.
REPEAT-BY:
Compile and run the attached code from xterm with uwm running,
then tap RETURN in the xterm window after you've opened the window.
Note the "XIO: Invalid argument" message.
(Since the appearance of the message depends on whether the server
keeps up with write requests, it's somewhat nondeterministic.
If the message does not appear, just tap RETURN a second time, then
load up the server with some superfluous windows and try again.)
#include "stdio.h"
#include "X11/Xlib.h"
#define NBPC 8
#define WIDTH 500
#define HEIGHT 500
char data[HEIGHT][WIDTH / NBPC];
main()
{
Display * display;
Window window;
GC gc;
Visual * visual;
int y, x;
XImage * ximage;
for (y = 0; y < HEIGHT; ++y)
for (x = 0; x < sizeof data[y]; ++x)
data[y][x] = x + y;
display = XOpenDisplay((char *) NULL);
XSynchronize(display, 1);
window = XCreateSimpleWindow(display, RootWindow(display, 0),
0, 0, WIDTH, HEIGHT, 5, 1, 0);
XMapWindow(display, window);
(void) getchar();
gc = DefaultGC(display, 0);
visual = DefaultVisual(display, 0);
ximage = XCreateImage(display, visual, 1, XYBitmap, 0, data,
WIDTH, HEIGHT, NBPC, 0);
(void) XPutImage(display, window, gc, ximage,
0, 0, 0, 0, WIDTH, HEIGHT);
(void) getchar();
return 0;
}
FIX:
I don't know if Sun's 4.0 changes what errno gets set to; in any event,
a workaround in the X library is useful for Sun 3.5 binary sites
(like ours). We'll assume that if a message of size 1 fails with an
EMSGSIZE error, we're on a system that sometimes gives inappropriate
EMSGSIZE errors.
*** lib/X/XlibInt.c Tue Jul 12 09:59:36 1988
--- lib/X/XlibInt.c Tue Jul 12 09:59:40 1988
***************
*** 310,316 ****
--- 310,323 ----
#endif
#ifdef EMSGSIZE
} else if (errno == EMSGSIZE) {
+ #ifdef ASWAS
todo = todo >> 1;
+ #else /* !defined ASWAS */
+ if (todo == 1) {
+ _XWaitForWritable(dpy);
+ todo = total;
+ } else todo = todo >> 1;
+ #endif /* !defined ASWAS */
#endif
} else {
(*_XIOErrorFunction)(dpy);
--
ado@ncifcrf.gov ADO is a trademark of Ampex.