diff options
author | djkurtz@chromium.org <djkurtz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-24 03:08:30 +0000 |
---|---|---|
committer | djkurtz@chromium.org <djkurtz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-24 03:08:30 +0000 |
commit | f30e71d6e2be936025c18c304995e4953671c9db (patch) | |
tree | 00f45528c4e87375225d75bcf7e000e830dadf13 | |
parent | 8cacfa2e8bdaebfcdd9c0171656ab1500181c0f8 (diff) | |
download | chromium_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.cc | 2 |
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); } |