[Xquartz-changes] xserver: Branch 'master' - 3 commits

Jeremy Huddleston jeremyhu at freedesktop.org
Sat Apr 23 17:37:31 PDT 2011


Rebased ref, commits from common ancestor:
commit 13f028919ab9e0fcdc859c0c13f1f9315d279a3c
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Sat Apr 23 12:55:39 2011 -0700

    XQuartz: xpr: Use a serial queue rather than pthread mutexes for window_hash
    
    Additionally removes some dead code and fixes double-locking in
    xprIsX11Window.  xprIsX11Window doesn't need to do any locking because
    those resources are protected by the called functions themselves.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>
    Reviewed-by: Daniel A. Steffen <dsteffen at apple.com>

diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m
index e56bf0c..ddfa7f3 100644
--- a/hw/xquartz/X11Application.m
+++ b/hw/xquartz/X11Application.m
@@ -237,8 +237,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) {
                 
                 if ([self isActive]) {
                     [self deactivate];
-                    if (!_x_active && quartzProcs->IsX11Window([e window],
-                                                               [e windowNumber]))
+                    if (!_x_active && quartzProcs->IsX11Window([e windowNumber]))
                         [self activateX:YES];
                 }
             }
diff --git a/hw/xquartz/quartz.h b/hw/xquartz/quartz.h
index 67a7919..0a9c47a 100644
--- a/hw/xquartz/quartz.h
+++ b/hw/xquartz/quartz.h
@@ -70,7 +70,7 @@ typedef void (*UpdateScreenProc)(ScreenPtr pScreen);
 /*
  * Rootless helper functions
  */
-typedef Bool (*IsX11WindowProc)(void *nsWindow, int windowNumber);
+typedef Bool (*IsX11WindowProc)(int windowNumber);
 typedef void (*HideWindowsProc)(Bool hide);
 
 /*
diff --git a/hw/xquartz/xpr/xpr.h b/hw/xquartz/xpr/xpr.h
index af1a90c..ebd89de 100644
--- a/hw/xquartz/xpr/xpr.h
+++ b/hw/xquartz/xpr/xpr.h
@@ -38,7 +38,7 @@ Bool QuartzModeBundleInit(void);
 void AppleDRIExtensionInit(void);
 void xprAppleWMInit(void);
 Bool xprInit(ScreenPtr pScreen);
-Bool xprIsX11Window(void *nsWindow, int windowNumber);
+Bool xprIsX11Window(int windowNumber);
 WindowPtr xprGetXWindow(xp_window_id wid);
 
 void xprHideWindows(Bool hide);
diff --git a/hw/xquartz/xpr/xprFrame.c b/hw/xquartz/xpr/xprFrame.c
index f0e9a89..066cc0f 100644
--- a/hw/xquartz/xpr/xprFrame.c
+++ b/hw/xquartz/xpr/xprFrame.c
@@ -43,7 +43,11 @@
 #include "windowstr.h"
 #include "quartz.h"
 
+#ifdef HAVE_LIBDISPATCH
+#include <dispatch/dispatch.h>
+#else
 #include <pthread.h>
+#endif
 
 #define DEFINE_ATOM_HELPER(func,atom_name)                      \
 static Atom func (void) {                                       \
@@ -61,10 +65,12 @@ DEFINE_ATOM_HELPER(xa_native_window_id, "_NATIVE_WINDOW_ID")
 /* Maps xp_window_id -> RootlessWindowRec */
 static x_hash_table *window_hash;
 
-/* Need to guard window_hash since xprGetXWindowFromAppKit and xprIsX11Window
- * can be called from any thread.
- */
+/* Need to guard window_hash since xprIsX11Window can be called from any thread. */
+#ifdef HAVE_LIBDISPATCH
+static dispatch_queue_t window_hash_serial_q;
+#else
 static pthread_mutex_t window_hash_mutex;
+#endif
 
 /* Prototypes for static functions */
 static Bool xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
@@ -181,9 +187,15 @@ xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
         return FALSE;
     }
 
+#ifdef HAVE_LIBDISPATCH
+    dispatch_async(window_hash_serial_q, ^{
+        x_hash_table_insert(window_hash, pFrame->wid, pFrame);
+    });
+#else
     pthread_mutex_lock(&window_hash_mutex);
     x_hash_table_insert(window_hash, pFrame->wid, pFrame);
     pthread_mutex_unlock(&window_hash_mutex);
+#endif
 
     xprSetNativeProperty(pFrame);
 
@@ -199,9 +211,15 @@ xprDestroyFrame(RootlessFrameID wid)
 {
     xp_error err;
 
+#ifdef HAVE_LIBDISPATCH
+    dispatch_async(window_hash_serial_q, ^{
+        x_hash_table_remove(window_hash, wid);
+    });
+#else
     pthread_mutex_lock(&window_hash_mutex);
     x_hash_table_remove(window_hash, wid);
     pthread_mutex_unlock(&window_hash_mutex);
+#endif
 
     err = xp_destroy_window(x_cvt_vptr_to_uint(wid));
     if (err != Success)
@@ -253,6 +271,9 @@ xprResizeFrame(RootlessFrameID wid, ScreenPtr pScreen,
 static void xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid) {
     xp_window_changes wc;
     unsigned int mask = XP_STACKING;
+#ifdef HAVE_LIBDISPATCH
+    __block
+#endif
     RootlessWindowRec *winRec;
 
     /* Stack frame below nextWid it if it exists, or raise
@@ -266,8 +287,16 @@ static void xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid) {
         wc.sibling = x_cvt_vptr_to_uint(nextWid);
     }
 
+#ifdef HAVE_LIBDISPATCH
+    dispatch_sync(window_hash_serial_q, ^{
+        winRec = x_hash_table_lookup(window_hash, wid, NULL);
+    });
+#else
+    pthread_mutex_lock(&window_hash_mutex);
     winRec = x_hash_table_lookup(window_hash, wid, NULL);
-
+    pthread_mutex_unlock(&window_hash_mutex);
+#endif
+    
     if(winRec) {
         if(XQuartzIsRootless)
             wc.window_level = normal_window_levels[winRec->level];
@@ -447,8 +476,12 @@ xprInit(ScreenPtr pScreen)
     rootless_CopyWindow_threshold = xp_scroll_area_threshold;
 
     assert((window_hash = x_hash_table_new(NULL, NULL, NULL, NULL)));
+#ifdef HAVE_LIBDISPATCH
+    assert((window_hash_serial_q = dispatch_queue_create(LAUNCHD_ID_PREFIX".X11.xpr_window_hash", NULL)));
+#else
     assert(0 == pthread_mutex_init(&window_hash_mutex, NULL));
-
+#endif
+    
     return TRUE;
 }
 
@@ -460,60 +493,36 @@ xprInit(ScreenPtr pScreen)
 WindowPtr
 xprGetXWindow(xp_window_id wid)
 {
+#ifdef HAVE_LIBDISPATCH
+    RootlessWindowRec *winRec __block;
+    dispatch_sync(window_hash_serial_q, ^{
+        winRec = x_hash_table_lookup(window_hash, x_cvt_uint_to_vptr(wid), NULL);
+    });
+#else
     RootlessWindowRec *winRec;
-
-    winRec = x_hash_table_lookup(window_hash, x_cvt_uint_to_vptr(wid), NULL);
-
-    return winRec != NULL ? winRec->win : NULL;
-}
-
-#ifdef UNUSED_CODE
-/*
- * Given the id of a physical window, try to find the top-level (or root)
- * X window that it represents.
- */
-WindowPtr
-xprGetXWindowFromAppKit(int windowNumber)
-{
-    RootlessWindowRec *winRec;
-    Bool ret;
-    xp_window_id wid;
-
     pthread_mutex_lock(&window_hash_mutex);
-
-    if (xp_lookup_native_window(windowNumber, &wid))
-        ret = xprGetXWindow(wid) != NULL;
-    else
-        ret = FALSE;
-
-    pthread_mutex_unlock(&window_hash_mutex);
-
-    if (!ret) return NULL;
     winRec = x_hash_table_lookup(window_hash, x_cvt_uint_to_vptr(wid), NULL);
+    pthread_mutex_unlock(&window_hash_mutex);
+#endif
 
     return winRec != NULL ? winRec->win : NULL;
 }
-#endif
 
 /*
  * The windowNumber is an AppKit window number. Returns TRUE if xpr is
  * displaying a window with that number.
  */
 Bool
-xprIsX11Window(void *nsWindow, int windowNumber)
+xprIsX11Window(int windowNumber)
 {
     Bool ret;
     xp_window_id wid;
 
-    pthread_mutex_lock(&window_hash_mutex);
-
     if (xp_lookup_native_window(windowNumber, &wid))
         ret = xprGetXWindow(wid) != NULL;
     else
         ret = FALSE;
 
-    pthread_mutex_unlock(&window_hash_mutex);
-
     return ret;
 }
 
commit a0227127927e7a40239b7c3438db2ec175141889
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Sat Apr 23 12:11:39 2011 -0700

    XQuartz: xpr: Initialize window_hash in xprInit
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/xpr/xprFrame.c b/hw/xquartz/xpr/xprFrame.c
index efb3737..f0e9a89 100644
--- a/hw/xquartz/xpr/xprFrame.c
+++ b/hw/xquartz/xpr/xprFrame.c
@@ -1,7 +1,7 @@
 /*
  * Xplugin rootless implementation frame functions
  *
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2011 Apple Computer, Inc. All rights reserved.
  * Copyright (c) 2003 Torrey T. Lyons. All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -35,7 +35,6 @@
 #include "rootlessCommon.h"
 #include <Xplugin.h>
 #include "x-hash.h"
-#include "x-list.h"
 #include "applewmExt.h"
 
 #include "propertyst.h"
@@ -61,6 +60,10 @@ DEFINE_ATOM_HELPER(xa_native_window_id, "_NATIVE_WINDOW_ID")
 
 /* Maps xp_window_id -> RootlessWindowRec */
 static x_hash_table *window_hash;
+
+/* Need to guard window_hash since xprGetXWindowFromAppKit and xprIsX11Window
+ * can be called from any thread.
+ */
 static pthread_mutex_t window_hash_mutex;
 
 /* Prototypes for static functions */
@@ -178,12 +181,6 @@ xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
         return FALSE;
     }
 
-    if (window_hash == NULL)
-    {
-        window_hash = x_hash_table_new(NULL, NULL, NULL, NULL);
-        pthread_mutex_init(&window_hash_mutex, NULL);
-    }
-
     pthread_mutex_lock(&window_hash_mutex);
     x_hash_table_insert(window_hash, pFrame->wid, pFrame);
     pthread_mutex_unlock(&window_hash_mutex);
@@ -256,6 +253,7 @@ xprResizeFrame(RootlessFrameID wid, ScreenPtr pScreen,
 static void xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid) {
     xp_window_changes wc;
     unsigned int mask = XP_STACKING;
+    RootlessWindowRec *winRec;
 
     /* Stack frame below nextWid it if it exists, or raise
        frame above everything otherwise. */
@@ -268,18 +266,16 @@ static void xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid) {
         wc.sibling = x_cvt_vptr_to_uint(nextWid);
     }
 
-    if(window_hash) {
-        RootlessWindowRec *winRec = x_hash_table_lookup(window_hash, wid, NULL);
-
-        if(winRec) {
-            if(XQuartzIsRootless)
-                wc.window_level = normal_window_levels[winRec->level];
-            else if(XQuartzShieldingWindowLevel)
-                wc.window_level = XQuartzShieldingWindowLevel + 1;
-            else
-                wc.window_level = rooted_window_levels[winRec->level];
-            mask |= XP_WINDOW_LEVEL;
-        }
+    winRec = x_hash_table_lookup(window_hash, wid, NULL);
+
+    if(winRec) {
+        if(XQuartzIsRootless)
+            wc.window_level = normal_window_levels[winRec->level];
+        else if(XQuartzShieldingWindowLevel)
+            wc.window_level = XQuartzShieldingWindowLevel + 1;
+        else
+            wc.window_level = rooted_window_levels[winRec->level];
+        mask |= XP_WINDOW_LEVEL;
     }
 
     xprConfigureWindow(x_cvt_vptr_to_uint(wid), mask, &wc);
@@ -450,6 +446,9 @@ xprInit(ScreenPtr pScreen)
     rootless_CopyBytes_threshold = xp_copy_bytes_threshold;
     rootless_CopyWindow_threshold = xp_scroll_area_threshold;
 
+    assert((window_hash = x_hash_table_new(NULL, NULL, NULL, NULL)));
+    assert(0 == pthread_mutex_init(&window_hash_mutex, NULL));
+
     return TRUE;
 }
 
@@ -463,9 +462,6 @@ xprGetXWindow(xp_window_id wid)
 {
     RootlessWindowRec *winRec;
 
-    if (window_hash == NULL)
-        return NULL;
-
     winRec = x_hash_table_lookup(window_hash, x_cvt_uint_to_vptr(wid), NULL);
 
     return winRec != NULL ? winRec->win : NULL;
@@ -483,11 +479,6 @@ xprGetXWindowFromAppKit(int windowNumber)
     Bool ret;
     xp_window_id wid;
 
-    if (window_hash == NULL)
-        return FALSE;
-
-    /* need to lock, since this function can be called by any thread */
-
     pthread_mutex_lock(&window_hash_mutex);
 
     if (xp_lookup_native_window(windowNumber, &wid))
@@ -514,11 +505,6 @@ xprIsX11Window(void *nsWindow, int windowNumber)
     Bool ret;
     xp_window_id wid;
 
-    if (window_hash == NULL)
-        return FALSE;
-
-    /* need to lock, since this function can be called by any thread */
-
     pthread_mutex_lock(&window_hash_mutex);
 
     if (xp_lookup_native_window(windowNumber, &wid))
commit c4fad6f4b0d99c0472d9bf2f7a9faf40389dcce7
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Sat Apr 23 11:55:49 2011 -0700

    XQuartz: Use a lighter spinlock instead of a pthread_mutex_t in QuartzScreenSaver
    
    Currently, we only end up here through a call to QuartzShowFullscreen, and
    this is always on the same thread.  Future changes (such as further
    incorporating libdispatch) may allow this to change, but contention will
    remain minimal since the call is infrequent and it is short held.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>
    Reviewed-by: Daniel A. Steffen <dsteffen at apple.com>

diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c
index 4b72a89..0e71d36 100644
--- a/hw/xquartz/quartz.c
+++ b/hw/xquartz/quartz.c
@@ -62,7 +62,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <IOKit/pwr_mgt/IOPMLib.h>
-#include <pthread.h>
+#include <libkern/OSAtomic.h>
 #include <signal.h>
 
 #include <rootlessCommon.h>
@@ -279,10 +279,10 @@ static void pokeActivityCallback(CFRunLoopTimerRef timer, void *info) {
 static void QuartzScreenSaver(int state) {
     static CFRunLoopTimerRef pokeActivityTimer = NULL;
     static CFRunLoopTimerContext pokeActivityContext = { 0, NULL, NULL, NULL, NULL };
-    static pthread_mutex_t pokeActivityMutex = PTHREAD_MUTEX_INITIALIZER;
+    static OSSpinLock pokeActivitySpinLock = OS_SPINLOCK_INIT;
+
+    OSSpinLockLock(&pokeActivitySpinLock);
 
-    pthread_mutex_lock(&pokeActivityMutex);
-    
     if(state) {
         if(pokeActivityTimer == NULL)
             goto QuartzScreenSaverEnd;
@@ -303,7 +303,7 @@ static void QuartzScreenSaver(int state) {
         CFRunLoopAddTimer(CFRunLoopGetMain(), pokeActivityTimer, kCFRunLoopCommonModes);
     }
 QuartzScreenSaverEnd:
-    pthread_mutex_unlock(&pokeActivityMutex);
+    OSSpinLockUnlock(&pokeActivitySpinLock);
 }
 
 void QuartzShowFullscreen(int state) {


More information about the Xquartz-changes mailing list