This is the mail archive of the
cygwin-xfree@cygwin.com
mailing list for the Cygwin XFree86 project.
Re: XIO error... anyone seen it? [found and fixed]
On Thu, Nov 08, 2001 at 02:17:49PM -0800, Brian Genisio wrote:
> Cyg/XF86 friends,
>
> Ok... after plenty of debugging, and goofing with the problem, in order to
> re-create it, I finally found what the problem is, AND the fix.
>
> As you recall, I had 2 cygwin-X applications, and both were heavy graphic
> hogs. One primarily uses XPutImage, and the other uses XpmCreate* functions.
> Both were randomly dying with a fatal error of 105, which indicates a full
> buffer. These calls to XPutImage were failing when they were putting HUGE
> images to the X server. (1280x1024 5000+ colors at 32 bits/color)
>
> Well, when I traced back the problem, I found that in the XpmCreate calls, it
> was still dying in the XPutImage calls within the XpmCreate.... I found the
> common culprit between the two applications.
>
> Ok... time to debug the X11 library :)
>
> XPutImage breaks the images up recursively, to handle the maximum request
> length of the Display in PutSubImage (lib/X11/PutImage.c). It then sends the
> data out through the Send*image->Data->_XSend (lib/X11/XlibInt.c).
>
> Within the _XSend command, it does a bunch of buffer manipulation, and finally
> calls _X11TransWritev to write it out to the socket. If this call fails, it
> checks the macro ETEST(), which is really (errno == EAGAIN || errno ==
> EWOULDBLOCK). If either of these are true, we want to try again, so _XSend
> calls _XWaitForWritable.
>
> _XWaitForWritable is a function that waits for the socket to be writeable, so
> it can successfully call _X11TransWritev the next time through the while loop.
> So, if I change the definition of ETEST() to (errno == EAGAIN || errno ==
> EWOULDBLOCK || errno == ENOBUFS), my problem is fixed!!!
>
> Why? Because there is no buffer space available on the socket, after 5000+
> AllocColor requests. It needs to be cleaned out. _XWaitForWritable waits for
> this to happen, and writing out happily works the next time around.
>
> Should we add the folowing line to XlibInt.c? :
> #ifdef __CYGWIN__
> #define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
>
> Or, is there a better solution? What do you (Cyg/XF86 developers) think?
Seems like a reasonable assessment Brian. We could do this, although I'd
like to understand why there isn't any buffer space on the socket.
Is there a test application you can email to me for testing..?
Alan.