[Xcb] [PATCH v2 libX11 2/3] Avoid reading events from connection when it's not necessary.

Rami Ylimäki rami.ylimaki at vincit.fi
Wed Mar 23 02:10:26 PDT 2011


This commit changes poll_for_event to check for queued events
only. This optimizes unnecessary system calls away in certain
situations. For example, calling XInternAtoms would read from the
connection a bit too much without the fix.

The xrestop utility is a good candidate for verifying this fix.

before:
$ strace xrestop -m 1 2>&1 | grep EAGAIN | wc -l
2679
$ strace xrestop -m 2 2>&1 | grep EAGAIN | wc -l
5353

after:
strace xrestop -m 1 2>&1 | grep EAGAIN | wc -l
2
strace xrestop -m 2 2>&1 | grep EAGAIN | wc -l
2

_XReply uses xcb_wait_for_reply to read a reply. We only care about
handling events that precede the reply. Those events must have been
already queued when xcb_wait_for_reply returns.

_XReadEvents uses xcb_wait_for_event to read an event. There is no
need to check the connection for new events after xcb_wait_for_event
returns. We can just handle the events that were queued by
xcb_wait_for_event in addition to the replies that precede them.

_XEventsQueued should check the connection status if events haven't
been queued. This is accomplished by extracting the xcb_poll_for_event
call from poll_for_event. _XEventsQueued is the only function that
actually needed the connection to be checked in poll_for_event.

Signed-off-by: Rami Ylimäki <rami.ylimaki at vincit.fi>
---

Fixed the commit message to contain a test case and to be a little bit
more clear about _XReadEvents.

 src/xcb_io.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/src/xcb_io.c b/src/xcb_io.c
index 8930736..0ffda40 100644
--- a/src/xcb_io.c
+++ b/src/xcb_io.c
@@ -207,7 +207,7 @@ static xcb_generic_reply_t *poll_for_event(Display *dpy)
 	assert(dpy->xcb->event_owner == XlibOwnsEventQueue && !dpy->xcb->event_waiter);
 
 	if(!dpy->xcb->next_event)
-		dpy->xcb->next_event = xcb_poll_for_event(dpy->xcb->connection);
+		dpy->xcb->next_event = xcb_poll_for_queued_event(dpy->xcb->connection);
 
 	if(dpy->xcb->next_event)
 	{
@@ -301,6 +301,8 @@ int _XEventsQueued(Display *dpy, int mode)
 	 * can reasonably claim there are no new events right now. */
 	if(!dpy->xcb->event_waiter)
 	{
+		if(!dpy->xcb->next_event)
+			dpy->xcb->next_event = xcb_poll_for_event(dpy->xcb->connection);
 		while((response = poll_for_response(dpy)))
 			handle_response(dpy, response, False);
 		if(xcb_connection_has_error(dpy->xcb->connection))
-- 
1.6.3.3



More information about the Xcb mailing list