[comp.windows.x] XNextEvent/XPending bug in v10?

soiffer@tekcrl.TEK.COM (Neil Soiffer) (08/29/87)

As has been mentioned before in this group, if the server sends a
large number of events to the client, then the server blocks on write.
The client in the meantime, may be sending requests to the server,
but because the server is blocked, the client fills its write buffer 
and blocks also.  Deadlock.  An XIOError is eventually generated after
the connection is closed.  [I am told that in X11, the server will not
block so this is only an X10 problem.]

Most programs (mine included) have a main loop that looks like:

	do forever
	   XNextEvent(&event)
	   process event...

XNextEvent (and other library calls that deal with input) limit
the amount read from the server in a single call to "BUFFSIZE" bytes.
This means that calling XNextEvent won't necessarily read all pending
input onto the X input queue -- hence the server may not unblock.
It seems like the obvious thing to do is to add "XPending()" to the
top of the loop to get all pending events [assuming you don't fill the
write buffer in one loop iteration].  However, XPending limits the amount
it reads to "BUFFSIZE" also, hence a single call to XPending won't do.

My question:  why do XPending and XNextEvent have these limits?  What
will I break if I change the code to loop until all the pending input
that 'ioctl' claims is there is read?

Hint to others:  looking thru the code, the only way that I can see
to get around this problem is to put 'XSync(0)' at the top of the loop.
This will cause all events to be read until the reply is found.
This is somewhat slow because 'read' is called with bytes=sizeof(XEvent)
instead of calling 'read' with a large buffer.

Does anybody have any other ideas/suggestions how to handle this problem?

	Neil Soiffer
	Textronix Computer Research Lab
	UUCP:  ...!tektronix!tekchips!soiffer
	ARPA:  soiffer%tekchips.tek.com@relay.cs.net
	CSNET: soiffer%tekchips.tek.com

jg@jumbo.dec.com (Jim Gettys) (08/30/87)

Yeah, the routines should probably read as much as possible.  It still
would not prevent deadlock, but make it less likely.

In V11, the problem is solved in a better way, requiring more sweeping
changes.  The connection is run in non-blocking mode, and if you would block
writing data to the server, events are enqueued in the meanwhile by
reading events from the connection until all data has successfully
been written.  This still does not entirely prevent problems, as a 
completely antisocial client may not ever do anything with his connection 
and the server still has to give up sending him data eventually.  

Then again, dealing with catatonia is hard under any circumstances....
				Jim Gettys
				Digital Equipment Corporation.