summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordjkurtz@chromium.org <djkurtz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-24 03:08:30 +0000
committerdjkurtz@chromium.org <djkurtz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-24 03:08:30 +0000
commitf30e71d6e2be936025c18c304995e4953671c9db (patch)
tree00f45528c4e87375225d75bcf7e000e830dadf13
parent8cacfa2e8bdaebfcdd9c0171656ab1500181c0f8 (diff)
downloadchromium_src-f30e71d6e2be936025c18c304995e4953671c9db.zip
chromium_src-f30e71d6e2be936025c18c304995e4953671c9db.tar.gz
chromium_src-f30e71d6e2be936025c18c304995e4953671c9db.tar.bz2
ui/display/chromeos: Flush Xlib output buffer after calling XUngrabServer
One of the horrors of using Xlib is its Output buffer. When calling Xlib functions, the X command bitstream is not actually sent right away. Commands are first queued up in the Xlib output buffer, and only sent over the wire when the output buffer is flushed. X clients typically don't have to worry about this, since (a) commands that require return a response are flushed immediately, and (b) they usually have an event loop that calls XPending() (XNextEvent(), or XWindowEvent()), which does a Flush internally. Chrome, however, listens to the Xserver fd, and only enters its XPending() loop if the File Can be Read Without Blocking. Now, when output configurator updates the Output Configuration, it does it while grabbing the server: XGrabServer // Update a bunch of stuff XUngrabServer When the X server is grabbed by a client, it ignores requests from all other X clients. In particular, it ignores requests from the Chrome GPU process. But the "XUngrabServer()" command doesn't generate a response. So, the command just sits there in the Xlib output buffer... Meanwhile, the browser process continues on and will request that the GPU process do some stuff, for which the GPU process will send a request to the X server. The GPU process blocks, waiting for the X server's response which never arrives. After 10 seconds, the GPU watchdog timer expires, restarting the GPU Process. As a side effect of this, the X server will send some data to the Browser process, its X connection becomes readable, Chrome fetches some events, and finally gets around to sending the XUngrabServer() request, un-grabbing the server after ~10 seconds. The quick and dirty fix is to just send an explicit XFlush() after XUngrabServer(). The scary thing is that there could be other places throughout Chrome that need the same treatment. Signed-off-by: Daniel Kurtz <djkurtz@chromium.org> BUG=chromium:366125 TEST=connect hdmi monitor TEST=switch to mirror mode (Ctrl+F4) TEST=unplug monitor => No ui freeze. GPU process does not crash (/var/log/ui/ui.LATEST) TEST=re-plug monitor => No ui freeze. GPU process does not crash (/var/log/ui/ui.LATEST) R=oshima@chromium.org R=dbehr@chromium.org R=marcheu@chromium.org Review URL: https://codereview.chromium.org/249253005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@265823 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ui/display/chromeos/x11/native_display_delegate_x11.cc2
1 files changed, 2 insertions, 0 deletions
diff --git a/ui/display/chromeos/x11/native_display_delegate_x11.cc b/ui/display/chromeos/x11/native_display_delegate_x11.cc
index 3dff81b..7003605 100644
--- a/ui/display/chromeos/x11/native_display_delegate_x11.cc
+++ b/ui/display/chromeos/x11/native_display_delegate_x11.cc
@@ -197,6 +197,8 @@ void NativeDisplayDelegateX11::UngrabServer() {
XRRFreeScreenResources(screen_);
screen_ = NULL;
XUngrabServer(display_);
+ // crbug.com/366125
+ XFlush(display_);
}
void NativeDisplayDelegateX11::SyncWithServer() { XSync(display_, 0); }