Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 1 | From 5235a7f3692a4c3c90dd4ac1be3c670388904bbe Mon Sep 17 00:00:00 2001 |
| 2 | From: Tatu Frisk <tatu.frisk@ge.com> |
| 3 | Date: Tue, 14 Mar 2017 14:41:27 +0200 |
| 4 | Subject: [PATCH] Fix hanging issue in _XReply |
| 5 | |
| 6 | Assume event queue is empty if another thread is blocking waiting for event. |
| 7 | |
| 8 | If one thread was blocking waiting for an event and another thread sent a |
| 9 | reply to the X server, both threads got blocked until an event was |
| 10 | received. |
| 11 | |
| 12 | Upstream-Status: Submitted [https://patchwork.freedesktop.org/patch/171458/] |
| 13 | |
| 14 | This patch needs to be removed once the corresponding patch has been merged upstream. |
| 15 | |
| 16 | https://patchwork.freedesktop.org/patch/171458/ |
| 17 | |
| 18 | Signed-off-by: Tatu Frisk <tatu.frisk@ge.com> |
| 19 | Signed-off-by: Jose Alarcon <jose.alarcon@ge.com> |
| 20 | --- |
| 21 | src/xcb_io.c | 19 +++++++------------ |
| 22 | 1 file changed, 7 insertions(+), 12 deletions(-) |
| 23 | |
| 24 | diff --git a/src/xcb_io.c b/src/xcb_io.c |
| 25 | index 5987329..c64eb04 100644 |
| 26 | --- a/src/xcb_io.c |
| 27 | +++ b/src/xcb_io.c |
| 28 | @@ -609,22 +609,17 @@ Status _XReply(Display *dpy, xReply *rep, int extra, Bool discard) |
| 29 | * letting anyone else process this sequence number, we |
| 30 | * need to process any events that should have come |
| 31 | * earlier. */ |
| 32 | - |
| 33 | if(dpy->xcb->event_owner == XlibOwnsEventQueue) |
| 34 | { |
| 35 | xcb_generic_reply_t *event; |
| 36 | - /* If some thread is already waiting for events, |
| 37 | - * it will get the first one. That thread must |
| 38 | - * process that event before we can continue. */ |
| 39 | - /* FIXME: That event might be after this reply, |
| 40 | - * and might never even come--or there might be |
| 41 | - * multiple threads trying to get events. */ |
| 42 | - while(dpy->xcb->event_waiter) |
| 43 | - { /* need braces around ConditionWait */ |
| 44 | - ConditionWait(dpy, dpy->xcb->event_notify); |
| 45 | + |
| 46 | + /* Assume event queue is empty if another thread is blocking |
| 47 | + * waiting for event. */ |
| 48 | + if(!dpy->xcb->event_waiter) |
| 49 | + { |
| 50 | + while((event = poll_for_response(dpy))) |
| 51 | + handle_response(dpy, event, True); |
| 52 | } |
| 53 | - while((event = poll_for_event(dpy))) |
| 54 | - handle_response(dpy, event, True); |
| 55 | } |
| 56 | |
| 57 | req->reply_waiter = 0; |
| 58 | -- |
| 59 | 2.10.1 |
| 60 | |