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@apple.com>
Reviewed-by: Daniel A. Steffen <dsteffen@apple.com>
This commit is contained in:
Jeremy Huddleston 2011-04-23 12:55:39 -07:00
parent bac34a54f7
commit 9244a3a24f
4 changed files with 50 additions and 42 deletions

View File

@ -236,8 +236,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) {
if ([self isActive]) { if ([self isActive]) {
[self deactivate]; [self deactivate];
if (!_x_active && quartzProcs->IsX11Window([e window], if (!_x_active && quartzProcs->IsX11Window([e windowNumber]))
[e windowNumber]))
[self activateX:YES]; [self activateX:YES];
} }
} }

View File

@ -70,7 +70,7 @@ typedef void (*UpdateScreenProc)(ScreenPtr pScreen);
/* /*
* Rootless helper functions * Rootless helper functions
*/ */
typedef Bool (*IsX11WindowProc)(void *nsWindow, int windowNumber); typedef Bool (*IsX11WindowProc)(int windowNumber);
typedef void (*HideWindowsProc)(Bool hide); typedef void (*HideWindowsProc)(Bool hide);
/* /*

View File

@ -38,7 +38,7 @@ Bool QuartzModeBundleInit(void);
void AppleDRIExtensionInit(void); void AppleDRIExtensionInit(void);
void xprAppleWMInit(void); void xprAppleWMInit(void);
Bool xprInit(ScreenPtr pScreen); Bool xprInit(ScreenPtr pScreen);
Bool xprIsX11Window(void *nsWindow, int windowNumber); Bool xprIsX11Window(int windowNumber);
WindowPtr xprGetXWindow(xp_window_id wid); WindowPtr xprGetXWindow(xp_window_id wid);
void xprHideWindows(Bool hide); void xprHideWindows(Bool hide);

View File

@ -43,7 +43,11 @@
#include "windowstr.h" #include "windowstr.h"
#include "quartz.h" #include "quartz.h"
#ifdef HAVE_LIBDISPATCH
#include <dispatch/dispatch.h>
#else
#include <pthread.h> #include <pthread.h>
#endif
#define DEFINE_ATOM_HELPER(func,atom_name) \ #define DEFINE_ATOM_HELPER(func,atom_name) \
static Atom func (void) { \ static Atom func (void) { \
@ -61,10 +65,12 @@ DEFINE_ATOM_HELPER(xa_native_window_id, "_NATIVE_WINDOW_ID")
/* Maps xp_window_id -> RootlessWindowRec */ /* Maps xp_window_id -> RootlessWindowRec */
static x_hash_table *window_hash; static x_hash_table *window_hash;
/* Need to guard window_hash since xprGetXWindowFromAppKit and xprIsX11Window /* Need to guard window_hash since xprIsX11Window can be called from any thread. */
* 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; static pthread_mutex_t window_hash_mutex;
#endif
/* Prototypes for static functions */ /* Prototypes for static functions */
static Bool xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen, static Bool xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
@ -181,9 +187,15 @@ xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
return FALSE; 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); pthread_mutex_lock(&window_hash_mutex);
x_hash_table_insert(window_hash, pFrame->wid, pFrame); x_hash_table_insert(window_hash, pFrame->wid, pFrame);
pthread_mutex_unlock(&window_hash_mutex); pthread_mutex_unlock(&window_hash_mutex);
#endif
xprSetNativeProperty(pFrame); xprSetNativeProperty(pFrame);
@ -199,9 +211,15 @@ xprDestroyFrame(RootlessFrameID wid)
{ {
xp_error err; 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); pthread_mutex_lock(&window_hash_mutex);
x_hash_table_remove(window_hash, wid); x_hash_table_remove(window_hash, wid);
pthread_mutex_unlock(&window_hash_mutex); pthread_mutex_unlock(&window_hash_mutex);
#endif
err = xp_destroy_window(x_cvt_vptr_to_uint(wid)); err = xp_destroy_window(x_cvt_vptr_to_uint(wid));
if (err != Success) if (err != Success)
@ -253,6 +271,9 @@ xprResizeFrame(RootlessFrameID wid, ScreenPtr pScreen,
static void xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid) { static void xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid) {
xp_window_changes wc; xp_window_changes wc;
unsigned int mask = XP_STACKING; unsigned int mask = XP_STACKING;
#ifdef HAVE_LIBDISPATCH
__block
#endif
RootlessWindowRec *winRec; RootlessWindowRec *winRec;
/* Stack frame below nextWid it if it exists, or raise /* Stack frame below nextWid it if it exists, or raise
@ -266,7 +287,15 @@ static void xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid) {
wc.sibling = x_cvt_vptr_to_uint(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); 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(winRec) {
if(XQuartzIsRootless) if(XQuartzIsRootless)
@ -447,7 +476,11 @@ xprInit(ScreenPtr pScreen)
rootless_CopyWindow_threshold = xp_scroll_area_threshold; rootless_CopyWindow_threshold = xp_scroll_area_threshold;
assert((window_hash = x_hash_table_new(NULL, NULL, NULL, NULL))); 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)); assert(0 == pthread_mutex_init(&window_hash_mutex, NULL));
#endif
return TRUE; return TRUE;
} }
@ -460,60 +493,36 @@ xprInit(ScreenPtr pScreen)
WindowPtr WindowPtr
xprGetXWindow(xp_window_id wid) xprGetXWindow(xp_window_id wid)
{ {
RootlessWindowRec *winRec; #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); winRec = x_hash_table_lookup(window_hash, x_cvt_uint_to_vptr(wid), NULL);
});
return winRec != NULL ? winRec->win : NULL; #else
}
#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; RootlessWindowRec *winRec;
Bool ret;
xp_window_id wid;
pthread_mutex_lock(&window_hash_mutex); 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); 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; return winRec != NULL ? winRec->win : NULL;
} }
#endif
/* /*
* The windowNumber is an AppKit window number. Returns TRUE if xpr is * The windowNumber is an AppKit window number. Returns TRUE if xpr is
* displaying a window with that number. * displaying a window with that number.
*/ */
Bool Bool
xprIsX11Window(void *nsWindow, int windowNumber) xprIsX11Window(int windowNumber)
{ {
Bool ret; Bool ret;
xp_window_id wid; xp_window_id wid;
pthread_mutex_lock(&window_hash_mutex);
if (xp_lookup_native_window(windowNumber, &wid)) if (xp_lookup_native_window(windowNumber, &wid))
ret = xprGetXWindow(wid) != NULL; ret = xprGetXWindow(wid) != NULL;
else else
ret = FALSE; ret = FALSE;
pthread_mutex_unlock(&window_hash_mutex);
return ret; return ret;
} }