Accepting request 629254 from home:michalsrb:bnc1101560:openSUSE:Tumbleweed
- u_don-t-flag-extra-reply-in-xcb_take_socket.patch * Fix IO errors with KWin in combination with NVIDIA driver. (bnc#1101560) OBS-URL: https://build.opensuse.org/request/show/629254 OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/libxcb?expand=0&rev=54
This commit is contained in:
parent
ed94b18e4a
commit
781bff0c5e
@ -1,3 +1,10 @@
|
||||
-------------------------------------------------------------------
|
||||
Mon Aug 13 09:06:27 UTC 2018 - msrb@suse.com
|
||||
|
||||
- u_don-t-flag-extra-reply-in-xcb_take_socket.patch
|
||||
* Fix IO errors with KWin in combination with NVIDIA driver.
|
||||
(bnc#1101560)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Mar 5 14:15:26 UTC 2018 - sndirsch@suse.com
|
||||
|
||||
|
@ -36,6 +36,7 @@ Source: %{name}-%{version}.tar.bz2
|
||||
Source1: baselibs.conf
|
||||
Patch1: bug-262309_xcb-xauthlocalhostname.diff
|
||||
Patch2: n_If-auth-with-credentials-for-hostname-fails-retry-with-XAUTHLOCALHOSTNAME.patch
|
||||
Patch3: u_don-t-flag-extra-reply-in-xcb_take_socket.patch
|
||||
BuildRequires: autoconf >= 2.57
|
||||
BuildRequires: automake
|
||||
BuildRequires: libtool
|
||||
@ -390,6 +391,7 @@ libxcb.
|
||||
%setup -q
|
||||
%patch1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
|
||||
%build
|
||||
./autogen.sh
|
||||
|
103
u_don-t-flag-extra-reply-in-xcb_take_socket.patch
Normal file
103
u_don-t-flag-extra-reply-in-xcb_take_socket.patch
Normal file
@ -0,0 +1,103 @@
|
||||
Author: Erik Kurzinger <ekurzinger@nvidia.com>
|
||||
Subject: don't flag extra reply in xcb_take_socket
|
||||
Patch-Mainline: To-be-upstreamed
|
||||
Signed-off-by: Michal Srb <msrb@suse.com>
|
||||
References: bnc#1101560
|
||||
|
||||
If any flags are specified in a call to xcb_take_socket,
|
||||
they should only be applied to replies for requests sent
|
||||
after that function returns (and until the socket is
|
||||
re-acquired by XCB).
|
||||
|
||||
Previously, they would also be incorrectly applied to the
|
||||
reply for the last request sent before the socket was taken.
|
||||
For instance, in this example program the reply for the
|
||||
GetInputFocus request gets discarded, even though it was
|
||||
sent before the socket was taken. This results in the
|
||||
call to retrieve the reply hanging indefinitely.
|
||||
|
||||
static void return_socket(void *closure) {}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
Display *dpy = XOpenDisplay(NULL);
|
||||
xcb_connection_t *c = XGetXCBConnection(dpy);
|
||||
|
||||
xcb_get_input_focus_cookie_t cookie = xcb_get_input_focus_unchecked(c);
|
||||
xcb_flush(c);
|
||||
|
||||
uint64_t seq;
|
||||
xcb_take_socket(c, return_socket, dpy, XCB_REQUEST_DISCARD_REPLY, &seq);
|
||||
|
||||
xcb_generic_error_t *err;
|
||||
xcb_get_input_focus_reply(c, cookie, &err);
|
||||
}
|
||||
|
||||
In practice, this has been causing intermittent KWin crashes when
|
||||
used in combination with the proprietary NVIDIA driver such as
|
||||
https://bugs.kde.org/show_bug.cgi?id=386370 since when Xlib fails to
|
||||
retrieve one of these incorrectly discarded replies it triggers
|
||||
an IO error.
|
||||
|
||||
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
|
||||
---
|
||||
src/xcb_in.c | 21 +++++++++++++++++++--
|
||||
src/xcb_out.c | 10 ++++++++--
|
||||
2 files changed, 27 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/xcb_in.c b/src/xcb_in.c
|
||||
index 73209e0..4333ad3 100644
|
||||
--- a/src/xcb_in.c
|
||||
+++ b/src/xcb_in.c
|
||||
@@ -958,8 +958,25 @@ void _xcb_in_replies_done(xcb_connection_t *c)
|
||||
pend = container_of(c->in.pending_replies_tail, struct pending_reply, next);
|
||||
if(pend->workaround == WORKAROUND_EXTERNAL_SOCKET_OWNER)
|
||||
{
|
||||
- pend->last_request = c->out.request;
|
||||
- pend->workaround = WORKAROUND_NONE;
|
||||
+ if (XCB_SEQUENCE_COMPARE(pend->first_request, <=, c->out.request)) {
|
||||
+ pend->last_request = c->out.request;
|
||||
+ pend->workaround = WORKAROUND_NONE;
|
||||
+ } else {
|
||||
+ /* The socket was taken, but no requests were actually sent
|
||||
+ * so just discard the pending_reply that was created.
|
||||
+ */
|
||||
+ struct pending_reply *prev_pend = c->in.pending_replies;
|
||||
+ if (prev_pend == pend) {
|
||||
+ c->in.pending_replies = NULL;
|
||||
+ c->in.pending_replies_tail = &c->in.pending_replies;
|
||||
+ } else {
|
||||
+ while (prev_pend->next != pend)
|
||||
+ prev_pend = prev_pend->next;
|
||||
+ prev_pend->next = NULL;
|
||||
+ c->in.pending_replies_tail = &prev_pend->next;
|
||||
+ }
|
||||
+ free(pend);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/src/xcb_out.c b/src/xcb_out.c
|
||||
index 3601a5f..c9593e5 100644
|
||||
--- a/src/xcb_out.c
|
||||
+++ b/src/xcb_out.c
|
||||
@@ -387,8 +387,14 @@ int xcb_take_socket(xcb_connection_t *c, void (*return_socket)(void *closure), v
|
||||
{
|
||||
c->out.return_socket = return_socket;
|
||||
c->out.socket_closure = closure;
|
||||
- if(flags)
|
||||
- _xcb_in_expect_reply(c, c->out.request, WORKAROUND_EXTERNAL_SOCKET_OWNER, flags);
|
||||
+ if(flags) {
|
||||
+ /* c->out.request + 1 will be the first request sent by the external
|
||||
+ * socket owner. If the socket is returned before this request is sent
|
||||
+ * it will be detected in _xcb_in_replies_done and this pending_reply
|
||||
+ * will be discarded.
|
||||
+ */
|
||||
+ _xcb_in_expect_reply(c, c->out.request + 1, WORKAROUND_EXTERNAL_SOCKET_OWNER, flags);
|
||||
+ }
|
||||
assert(c->out.request == c->out.request_written);
|
||||
*sent = c->out.request;
|
||||
}
|
||||
--
|
||||
2.16.4
|
||||
|
Loading…
x
Reference in New Issue
Block a user