[Xcb] [PATCH xcb] don't flag extra reply in xcb_take_socket
Uli Schlachter
psychon at znc.in
Tue Aug 21 17:02:08 UTC 2018
Thanks. I took the commit message from your original mail, added it to
this patch and pushed the result.
Cheers,
Uli
P.S.: And now I'll wait for someone to ask for an 1.13.1 release. Plus
someone who volunteers to do that release.
On 20.08.2018 21:06, Erik Kurzinger wrote:
> Hi Uli,
>
> Thanks for taking a look! I tried modifying the 'else' case in _xcb_in_replies_done
> as you suggested, I agree that it's a bit cleaner than what I had.
>
> It still appears to fix the hang in the example program as well as the KWin crash
> I had mentioned so everything looks good. I can't think of a better name than
> 'prev_next' either - it'll have to do :)
>
> Cheers,
> Erik
>
> ---
> src/xcb_in.c | 16 ++++++++++++++--
> src/xcb_out.c | 10 ++++++++--
> 2 files changed, 22 insertions(+), 4 deletions(-)
>
> diff --git a/src/xcb_in.c b/src/xcb_in.c
> index 73209e0..58fe896 100644
> --- a/src/xcb_in.c
> +++ b/src/xcb_in.c
> @@ -958,8 +958,20 @@ 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_next = &c->in.pending_replies;
> + while (*prev_next != pend)
> + prev_next = &(*prev_next)->next;
> + *prev_next = NULL;
> + c->in.pending_replies_tail = prev_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;
> }
>
--
If you have to type the letters "A-E-S" into your source code, you're
doing it wrong.
More information about the Xcb
mailing list