x11: Reduce chances XPending does recvmsg() syscall
XPending() will do a recvmsg() syscall if there are no items in the queue. In most cases, this is unnecessary because we know that there is data to be read of the connection or there are items already read which simply need to be processed. Discovering both of those conditions can be done without recvmsg() in the hot paths. Before this path, every iteration of the main loop had the potential to submit a recvmsg() syscall. This reduces that overhead drastically. XFlush() on the other-hand knows if it needs to write data or not and will do no IO in the case the buffer is empty. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3653 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4006>
This commit is contained in:
parent
1247452d19
commit
971bf15f26
@ -33,7 +33,9 @@ meta_x11_event_source_prepare (GSource *source,
|
||||
|
||||
*timeout = -1;
|
||||
|
||||
return XPending (event_source->xdisplay);
|
||||
XFlush (event_source->xdisplay);
|
||||
|
||||
return XEventsQueued (event_source->xdisplay, QueuedAlready) > 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -41,7 +43,8 @@ meta_x11_event_source_check (GSource *source)
|
||||
{
|
||||
MetaX11EventSource *event_source = (MetaX11EventSource *) source;
|
||||
|
||||
return XPending (event_source->xdisplay);
|
||||
return (event_source->event_poll_fd.revents & G_IO_IN) != 0 ||
|
||||
XEventsQueued (event_source->xdisplay, QueuedAlready) > 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -52,12 +55,16 @@ meta_x11_event_source_dispatch (GSource *source,
|
||||
MetaX11EventSource *event_source = (MetaX11EventSource *) source;
|
||||
MetaX11EventFunc event_func = (MetaX11EventFunc) callback;
|
||||
gboolean retval = G_SOURCE_CONTINUE;
|
||||
int pending;
|
||||
|
||||
while (retval == G_SOURCE_CONTINUE &&
|
||||
XPending (event_source->xdisplay))
|
||||
pending = XPending (event_source->xdisplay);
|
||||
|
||||
while (retval == G_SOURCE_CONTINUE && pending > 0)
|
||||
{
|
||||
XEvent xevent;
|
||||
|
||||
pending--;
|
||||
|
||||
XNextEvent (event_source->xdisplay, &xevent);
|
||||
retval = event_func (&xevent, user_data);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user