[PATCH] Fix XNextRequest() after direct usage of XCB

Uli Schlachter psychon at znc.in
Sat May 10 05:55:11 PDT 2014


On 10.05.2014 00:21, otaylor at redhat.com wrote:
> From: "Owen W. Taylor" <otaylor at fishsoup.net>
> 
> When XCB owns the X socket, dpy->request is not updated, so
> NextRequest() and XNextRequest() return the wrong value. There's
> nothing we can do to fix NextRequest() while retaining ABI compat,
> but change XNextRequest() to grab the socket back from XCB,
> updating dpy->request.
> 
> Signed-off-by: Owen W. Taylor <otaylor at fishsoup.net>

Reviewed-by: Uli Schlachter <psychon at znc.in>

(And this also makes this function thread safe on 32bit archs were reading a
64bit value isn't atomic)

> ---
>  src/Macros.c  | 14 +++++++++++++-
>  src/Xxcbint.h |  2 ++
>  src/xcb_io.c  | 11 +++++++++++
>  3 files changed, 26 insertions(+), 1 deletion(-)
> 
> diff --git a/src/Macros.c b/src/Macros.c
> index cfc083a..394a764 100644
> --- a/src/Macros.c
> +++ b/src/Macros.c
> @@ -30,6 +30,7 @@ in this Software without prior written authorization from The Open Group.
>  #include "Xlibint.h"
>  #define XUTIL_DEFINE_FUNCTIONS
>  #include "Xutil.h"
> +#include "Xxcbint.h"
>  
>  /*
>   * This file makes full definitions of routines for each macro.
> @@ -135,9 +136,20 @@ int XBitmapPad(Display *dpy) { return (BitmapPad(dpy)); }
>  
>  int XImageByteOrder(Display *dpy) { return (ImageByteOrder(dpy)); }
>  
> +/* XNextRequest() differs from the rest of the functions here because it is
> + * no longer a macro wrapper - when libX11 is being used mixed together
> + * with direct use of xcb, the next request field of the Display structure will
> + * not be updated. We can't fix the NextRequest() macro in any easy way,
> + * but we can at least make XNextRequest() do the right thing.
> + */
>  unsigned long XNextRequest(Display *dpy)
>  {
> -    return (NextRequest(dpy));
> +    unsigned long next_request;
> +    LockDisplay(dpy);
> +    next_request = _XNextRequest(dpy);
> +    UnlockDisplay(dpy);
> +
> +    return next_request;
>  }
>  
>  unsigned long XLastKnownRequestProcessed(Display *dpy)
> diff --git a/src/Xxcbint.h b/src/Xxcbint.h
> index a8c9a67..bf41c23 100644
> --- a/src/Xxcbint.h
> +++ b/src/Xxcbint.h
> @@ -46,4 +46,6 @@ typedef struct _X11XCBPrivate {
>  int _XConnectXCB(Display *dpy, _Xconst char *display, int *screenp);
>  void _XFreeX11XCBStructure(Display *dpy);
>  
> +unsigned long _XNextRequest(Display *dpy);
> +
>  #endif /* XXCBINT_H */
> diff --git a/src/xcb_io.c b/src/xcb_io.c
> index 727c6c7..5987329 100644
> --- a/src/xcb_io.c
> +++ b/src/xcb_io.c
> @@ -774,3 +774,14 @@ void _XEatDataWords(Display *dpy, unsigned long n)
>  		dpy->xcb->reply_consumed = dpy->xcb->reply_length;
>  	_XFreeReplyData(dpy, False);
>  }
> +
> +unsigned long
> +_XNextRequest(Display *dpy)
> +{
> +    /* This will update dpy->request. The assumption is that the next thing
> +     * that the application will do is make a request so there's little
> +     * overhead.
> +     */
> +    require_socket(dpy);
> +    return NextRequest(dpy);
> +}
> 


-- 
"Are you preparing for another war, Plutarch?" I ask.
"Oh, not now. Now we're in that sweet period where everyone agrees that our
recent horrors should never be repeated," he says. "But collective thinking is
usually short-lived. We're fickle, stupid beings with poor memories and a great
gift for self-destruction.


More information about the xorg-devel mailing list