Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!bloom-beacon!ATR-22.HAC.COM!rtyle From: rtyle@ATR-22.HAC.COM (Ross Tyler) Newsgroups: comp.windows.x Subject: (none) Message-ID: <8810181350.AA01296@atr-22.hac.com> Date: 18 Oct 88 13:50:38 GMT Sender: daemon@bloom-beacon.MIT.EDU Organization: The Internet Lines: 32 There is a bug in Xlib Version 11 Release 2 that may cause deadlock. When a client calls XNextEvent and there are no events queued, XNextEvent calls _XReadEvents to read all the whole events pending on the socket. _XReadEvents must read at least one new event. Before events are read, however, any pending output is flushed with _XFlush. If there is pending output and the output cannot be written to the socket immediately (EWOULDBLOCK) then _XWaitForWritable is called. While _XWaitForWritable is waiting for the socket to become writable, all whole pending input events are queued. It is conceivable then that after _XReadEvents call to _XFlush that new events have been queued. This is the bug. _XReadEvents does not check to see if new events have been queued and will block until at least one more input event is pending on the socket. The event that the client was waiting for may actually have already been queued and another event may never come. Deadlock! The fix can be done in XlibInt.c routine _XReadEvents () by adding this piece of code at the beginning: /* _XFlush via _XWaitForWritable may queue new events for us. ** if it does then simply return with these. */ struct _XSQEvent *tail; tail = dpy->tail; _XFlush (dpy); if (tail != dpy->tail) return; Note that this probably won't occur on systems where EWOULDBLOCK is not defined (the call to _XWaitForWritable is within a conditional compile block). In any case its occurance would most likely be rare because writes to sockets are typically buffered in the kernel without blocking the writer until buffer space is exhausted.