[PATCH v2 xserver] xwayland: Don't roundtrip in DRI2 authentication mechanism

Tiago Vignatti tiago.vignatti at intel.com
Mon Feb 4 08:54:59 PST 2013


Signed-off-by: Tiago Vignatti <tiago.vignatti at intel.com>
---
v2: - added AuthMagic3, for passing ClientPtr
    - fixed server internal ABI issue, by maintaining DRI2Authenticate intact
    - fixed multiple clients accesses to DRI2 authenticate, using Wayland
      callback mechanism to ensure they all go atomically

 hw/xfree86/dri2/dri2.c             |   16 ++++++++++--
 hw/xfree86/dri2/dri2.h             |   12 ++++++---
 hw/xfree86/dri2/dri2ext.c          |   45 +++++++++++++++++++++++++++++++--
 hw/xfree86/xwayland/xwayland-drm.c |   49 +++++++++++++++++++++++++++++-------
 hw/xfree86/xwayland/xwayland.h     |    2 +-
 5 files changed, 107 insertions(+), 17 deletions(-)

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index b08618a..54efeae 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -107,6 +107,7 @@ typedef struct _DRI2Screen {
     DRI2GetMSCProcPtr GetMSC;
     DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC;
     DRI2AuthMagic2ProcPtr AuthMagic;
+    DRI2AuthMagic3ProcPtr AuthMagic3;
     DRI2AuthMagicProcPtr LegacyAuthMagic;
     DRI2ReuseBufferNotifyProcPtr ReuseBufferNotify;
     DRI2SwapLimitValidateProcPtr SwapLimitValidate;
@@ -1133,6 +1134,17 @@ DRI2Authenticate(ScreenPtr pScreen, uint32_t magic)
     return TRUE;
 }
 
+Bool
+DRI2XWaylandAuthenticate(ClientPtr client, ScreenPtr pScreen, uint32_t magic)
+{
+    DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+
+    if (ds == NULL || (*ds->AuthMagic3) (client, pScreen, magic))
+        return FALSE;
+
+    return TRUE;
+}
+
 static int
 DRI2ConfigNotify(WindowPtr pWin, int x, int y, int w, int h, int bw,
                  WindowPtr pSib)
@@ -1222,10 +1234,10 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
      *
      * If a driver is built without xwayland support, we'll die before we get
      * here. If a driver is built with xwayland support, it'll support
-     * AuthMagic2, or crash; we don't care about xwayland ABI yet.
+     * AuthMagic3, or crash; we don't care about xwayland ABI yet.
      */
     if (xorgWayland) {
-        ds->AuthMagic = info->AuthMagic2;
+        ds->AuthMagic3 = info->AuthMagic3;
     }
     
     if (info->version >= 5) {
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index cec9634..1323cd7 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -65,6 +65,8 @@ typedef void (*DRI2CopyRegionProcPtr) (DrawablePtr pDraw,
 typedef void (*DRI2WaitProcPtr) (WindowPtr pWin, unsigned int sequence);
 typedef int (*DRI2AuthMagicProcPtr) (int fd, uint32_t magic);
 typedef int (*DRI2AuthMagic2ProcPtr) (ScreenPtr pScreen, uint32_t magic);
+typedef int (*DRI2AuthMagic3ProcPtr) (ClientPtr client,
+                                      ScreenPtr pScreen, uint32_t magic);
 
 /**
  * Schedule a buffer swap
@@ -219,9 +221,7 @@ typedef struct {
      * is unnecessary, but it's slightly different in master.
      */
     /* AuthMagic callback which passes extra context */
-    /* If this is NULL the AuthMagic callback is used */
-    /* If this is non-NULL the AuthMagic callback is ignored */
-    DRI2AuthMagic2ProcPtr AuthMagic2;
+    DRI2AuthMagic3ProcPtr AuthMagic3;
 } DRI2InfoRec, *DRI2InfoPtr;
 
 extern _X_EXPORT int DRI2EventBase;
@@ -240,6 +240,12 @@ extern _X_EXPORT Bool DRI2Connect(ScreenPtr pScreen,
 
 extern _X_EXPORT Bool DRI2Authenticate(ScreenPtr pScreen, uint32_t magic);
 
+extern _X_EXPORT void DRI2SendAuthReply(ClientPtr client, int status);
+
+extern _X_EXPORT Bool DRI2XWaylandAuthenticate(ClientPtr client,
+                                               ScreenPtr pScreen,
+                                               uint32_t magic);
+
 extern _X_EXPORT int DRI2CreateDrawable(ClientPtr client,
                                         DrawablePtr pDraw,
                                         XID id,
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index 2579a5c..30add45 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -46,8 +46,8 @@
 #include "dri2.h"
 #include "protocol-versions.h"
 
-/* The only xf86 include */
 #include "xf86Module.h"
+#include "xf86Priv.h" /* xorgWayland */
 
 static ExtensionEntry *dri2Extension;
 extern Bool DRI2ModuleSetup(void);
@@ -155,6 +155,44 @@ ProcDRI2Authenticate(ClientPtr client)
     return Success;
 }
 
+void
+DRI2SendAuthReply(ClientPtr client, int status)
+{
+    xDRI2AuthenticateReply rep;
+
+    REQUEST_SIZE_MATCH(xDRI2AuthenticateReq);
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.length = 0;
+    rep.authenticated = status;
+
+    WriteToClient(client, sizeof(xDRI2AuthenticateReply), &rep);
+
+    if (client->ignoreCount > 0)
+        AttendClient(client);
+}
+
+static int
+ProcDRI2XWaylandAuthenticate(ClientPtr client)
+{
+    REQUEST(xDRI2AuthenticateReq);
+    DrawablePtr pDraw;
+    int status;
+
+    if (!validDrawable(client, stuff->window, DixGetAttrAccess,
+                       &pDraw, &status))
+        return status;
+
+    if (DRI2XWaylandAuthenticate(client, pDraw->pScreen, stuff->magic)) {
+        IgnoreClient(client);
+        return Success;
+    }
+
+    /* BadAccess or BadDrawable */
+    DRI2SendAuthReply(client, status);
+    return Success;
+}
+
 static void
 DRI2InvalidateBuffersEvent(DrawablePtr pDraw, void *priv, XID id)
 {
@@ -551,7 +589,10 @@ ProcDRI2Dispatch(ClientPtr client)
     case X_DRI2Connect:
         return ProcDRI2Connect(client);
     case X_DRI2Authenticate:
-        return ProcDRI2Authenticate(client);
+        if (xorgWayland)
+            return ProcDRI2XWaylandAuthenticate(client);
+        else
+            return ProcDRI2Authenticate(client);
     case X_DRI2CreateDrawable:
         return ProcDRI2CreateDrawable(client);
     case X_DRI2DestroyDrawable:
diff --git a/hw/xfree86/xwayland/xwayland-drm.c b/hw/xfree86/xwayland/xwayland-drm.c
index c19eb84..5dd4af4 100644
--- a/hw/xfree86/xwayland/xwayland-drm.c
+++ b/hw/xfree86/xwayland/xwayland-drm.c
@@ -45,6 +45,7 @@
 
 #include "xwayland.h"
 #include "xwayland-private.h"
+#include "../dri2/dri2.h"
 
 static void
 drm_handle_device (void *data, struct wl_drm *drm, const char *device)
@@ -143,22 +144,52 @@ int xwl_screen_get_drm_fd(struct xwl_screen *xwl_screen)
     return xwl_screen->drm_fd;
 }
 
-int xwl_drm_authenticate(struct xwl_screen *xwl_screen,
-			    uint32_t magic)
+static DevPrivateKeyRec xwl_client_private_key;
+
+static void
+sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
 {
-    int ret;
+    ClientPtr client = data;
+    struct xwl_screen *xwl_screen;
+    int status;
+
+    xwl_screen =
+	dixLookupPrivate(&client->devPrivates, &xwl_client_private_key);
+
+    if (xwl_screen->authenticated)
+	status = Success;
+    else
+	status = BadAccess;
+
+    DRI2SendAuthReply(client, status);
 
     xwl_screen->authenticated = 0;
+    wl_callback_destroy(callback);
+}
 
-    if (xwl_screen->drm)
-	wl_drm_authenticate (xwl_screen->drm, magic);
+static const struct wl_callback_listener sync_listener = {
+    sync_callback
+};
 
-    ret = wl_display_roundtrip(xwl_screen->display);
-    if (ret == -1)
-	return BadAlloc;
-    if (!xwl_screen->authenticated)
+int xwl_drm_authenticate(ClientPtr client, struct xwl_screen *xwl_screen,
+			    uint32_t magic)
+{
+    struct wl_callback *callback;
+
+    if (!xwl_screen->drm)
+	return BadAccess;
+
+    if (!dixRegisterPrivateKey(&xwl_client_private_key, PRIVATE_CLIENT, 0))
 	return BadAlloc;
 
+    dixSetPrivate(&client->devPrivates, &xwl_client_private_key, xwl_screen);
+
+    xwl_screen->authenticated = 0;
+
+    wl_drm_authenticate (xwl_screen->drm, magic);
+    callback = wl_display_sync(xwl_screen->display);
+    wl_callback_add_listener(callback, &sync_listener, client);
+
     return Success;
 }
 
diff --git a/hw/xfree86/xwayland/xwayland.h b/hw/xfree86/xwayland/xwayland.h
index e536c42..f268366 100644
--- a/hw/xfree86/xwayland/xwayland.h
+++ b/hw/xfree86/xwayland/xwayland.h
@@ -69,7 +69,7 @@ extern _X_EXPORT void
 xwl_screen_post_damage(struct xwl_screen *xwl_screen);
 
 extern _X_EXPORT int
-xwl_drm_authenticate(struct xwl_screen *xwl_screen,
+xwl_drm_authenticate(ClientPtr client, struct xwl_screen *xwl_screen,
 		     uint32_t magic);
 
 extern _X_EXPORT int
-- 
1.7.9.5



More information about the wayland-devel mailing list