XQuartz: Added framework for asserting which thread we're in.

This commit is contained in:
Jeremy Huddleston 2008-04-17 13:12:56 -07:00
parent a56aca1a6b
commit 00beb98251
5 changed files with 115 additions and 6 deletions

View File

@ -34,7 +34,8 @@ libXquartz_la_SOURCES = \
quartzForeground.c \
quartzKeyboard.c \
quartzPasteboard.c \
quartzStartup.c
quartzStartup.c \
threadSafety.c
EXTRA_DIST = \
X11Application.h \
@ -50,4 +51,5 @@ EXTRA_DIST = \
quartzCommon.h \
quartzForeground.h \
quartzKeyboard.h \
quartzPasteboard.h
quartzPasteboard.h \
threadSafety.h

View File

@ -742,7 +742,7 @@ void X11ApplicationShowHideMenubar (int state) {
[n release];
}
static void * create_thread (void *func, void *arg) {
static pthread_t create_thread (void *func, void *arg) {
pthread_attr_t attr;
pthread_t tid;
@ -752,7 +752,7 @@ static void * create_thread (void *func, void *arg) {
pthread_create (&tid, &attr, func, arg);
pthread_attr_destroy (&attr);
return (void *) tid;
return tid;
}
static void check_xinitrc (void) {
@ -823,7 +823,10 @@ void X11ApplicationMain (int argc, const char **argv, void (*server_thread) (voi
aquaMenuBarHeight = NSHeight([[NSScreen mainScreen] frame]) -
NSMaxY([[NSScreen mainScreen] visibleFrame]);
if (!create_thread (server_thread, server_arg)) {
APPKIT_THREAD = pthread_self();
SERVER_THREAD = create_thread (server_thread, server_arg);
if (!SERVER_THREAD) {
ErrorF("can't create secondary thread\n");
exit (1);
}

View File

@ -34,6 +34,8 @@
#include <X11/extensions/XKB.h>
#include <assert.h>
#include "threadSafety.h"
typedef struct {
void *framebuffer;
int x;
@ -123,7 +125,7 @@ void DarwinSendDDXEvent(int type, int argc, ...);
#ifdef ENABLE_DEBUG_LOG
extern FILE *debug_log_fp;
#define DEBUG_LOG_NAME "x11-debug.txt"
#define DEBUG_LOG(msg, args...) if (debug_log_fp) fprintf(debug_log_fp, "%x:%s:%s:%d " msg, pthread_self(), __FILE__, __FUNCTION__, __LINE__, ##args ); fflush(debug_log_fp);
#define DEBUG_LOG(msg, args...) if (debug_log_fp) fprintf(debug_log_fp, "%s:%s:%s:%d " msg, threadSafetyID(pthread_self()), __FILE__, __FUNCTION__, __LINE__, ##args ); fflush(debug_log_fp);
#else
#define DEBUG_LOG(msg, args...)
#endif

59
hw/xquartz/threadSafety.c Normal file
View File

@ -0,0 +1,59 @@
/*
* Copyright (C) 2008 Apple, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name(s) of the above copyright
* holders shall not be used in advertising or otherwise to promote the sale,
* use or other dealings in this Software without prior written authorization.
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include "threadSafety.h"
#include "os.h"
#include <execinfo.h>
pthread_t SERVER_THREAD;
pthread_t APPKIT_THREAD;
static void spewCallStack(void) {
void* callstack[128];
int i, frames = backtrace(callstack, 128);
char** strs = backtrace_symbols(callstack, frames);
for (i = 0; i < frames; ++i) {
ErrorF("%s\n", strs[i]);
}
free(strs);
}
void threadAssert(pthread_t tid) {
if(pthread_equal(pthread_self(), tid))
return;
/* NOOOO! */
ErrorF("Thread Assertion Failed: self=%s, expected=%s\n",
threadSafetyID(pthread_self()), threadSafetyID(tid));
spewCallStack();
}

43
hw/xquartz/threadSafety.h Normal file
View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2008 Apple, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name(s) of the above copyright
* holders shall not be used in advertising or otherwise to promote the sale,
* use or other dealings in this Software without prior written authorization.
*/
#ifndef _XQ_THREAD_SAFETY_H_
#define _XQ_THREAD_SAFETY_H_
#include <pthread.h>
extern pthread_t SERVER_THREAD;
extern pthread_t APPKIT_THREAD;
#define threadSafetyID(tid) (pthread_equal((tid), SERVER_THREAD) ? "X Server Thread" : "Appkit Thread")
/* Print message to ErrorF if we're in the wrong thread */
void threadAssert(pthread_t tid);
#define TA_SERVER() threadAssert(SERVER_THREAD)
#define TA_APPKIT() threadAssert(APPKIT_THREAD)
#endif _XQ_THREAD_SAFETY_H_