xserver: Branch 'master'

Jeremy Huddleston jeremyhu at kemper.freedesktop.org
Sat Apr 26 19:21:12 PDT 2008


 dix/main.c                  |   16 +------
 hw/xquartz/X11Application.h |    2 
 hw/xquartz/X11Application.m |   29 ++-----------
 hw/xquartz/X11Controller.h  |    2 
 hw/xquartz/X11Controller.m  |    4 -
 hw/xquartz/darwinEvents.c   |    9 ----
 hw/xquartz/quartz.c         |    5 --
 hw/xquartz/quartzStartup.c  |   95 ++++++++++++++++++++++++++------------------
 hw/xquartz/threadSafety.c   |   16 ++++++-
 hw/xquartz/threadSafety.h   |   17 ++++---
 10 files changed, 96 insertions(+), 99 deletions(-)

New commits:
commit ef1c52053755fa14b4ca98b22c506f73f5f4a4b7
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Sat Apr 26 19:21:05 2008 -0700

    XQuartz: Cleaned up startup and thread creation a tad.
    (cherry picked from commit c861fe00e112b21ee0156d09a6cd5281642a1dcc)

diff --git a/dix/main.c b/dix/main.c
index 6d9dd33..fbd6413 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -237,12 +237,11 @@ static int indexForScanlinePad[ 65 ] = {
 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
 #endif
 
-#ifdef __APPLE__
-void DarwinHandleGUI(int argc, char **argv, char **envp);
+#ifdef XQUARTZ
+int dix_main(int argc, char *argv[], char *envp[])
+#else
+int main(int argc, char *argv[], char *envp[])
 #endif
-
-int
-main(int argc, char *argv[], char *envp[])
 {
     int		i, j, k, error;
     char	*xauthfile;
@@ -256,13 +255,6 @@ main(int argc, char *argv[], char *envp[])
     PrinterInitGlobals();
 #endif
 
-#ifdef XQUARTZ
-    /* Quartz support on Mac OS X requires that the Cocoa event loop be in
-     * the main thread. This allows the X server main to be called again
-     * from another thread. */
-    DarwinHandleGUI(argc, argv, envp);
-#endif
-
     CheckUserParameters(argc, argv, envp);
 
     CheckUserAuthorization();
diff --git a/hw/xquartz/X11Application.h b/hw/xquartz/X11Application.h
index 47c605c..3869df9 100644
--- a/hw/xquartz/X11Application.h
+++ b/hw/xquartz/X11Application.h
@@ -71,7 +71,7 @@ void X11ApplicationSetCanQuit (int state);
 void X11ApplicationServerReady (void);
 void X11ApplicationShowHideMenubar (int state);
 
-void X11ApplicationMain(int argc, const char **argv, void (*server_thread) (void *), void *server_arg);
+void X11ApplicationMain(int argc, const char **argv);
 
 extern int X11EnableKeyEquivalents;
 extern int quartzHasRoot, quartzEnableRootless;
diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m
index eefa45f..7680437 100644
--- a/hw/xquartz/X11Application.m
+++ b/hw/xquartz/X11Application.m
@@ -35,6 +35,7 @@
 
 #include "quartzForeground.h"
 #include "quartzCommon.h"
+
 #import "X11Application.h"
 
 # include "darwin.h"
@@ -45,7 +46,9 @@
 # include "micmap.h"
 #include <mach/mach.h>
 #include <unistd.h>
+
 #include <pthread.h>
+extern pthread_cond_t server_can_start_cond;
 
 #define DEFAULTS_FILE "/usr/X11/lib/X11/xserver/Xquartz.plist"
 
@@ -732,19 +735,6 @@ void X11ApplicationShowHideMenubar (int state) {
     [n release];
 }
 
-static pthread_t create_thread (void *func, void *arg) {
-    pthread_attr_t attr;
-    pthread_t tid;
-	
-    pthread_attr_init (&attr);
-    pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);
-    pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
-    pthread_create (&tid, &attr, func, arg);
-    pthread_attr_destroy (&attr);
-	
-    return tid;
-}
-
 static void check_xinitrc (void) {
     char *tem, buf[1024];
     NSString *msg;
@@ -786,7 +776,7 @@ environment?", @"Startup xinitrc dialog");
     [X11App prefs_synchronize];
 }
 
-void X11ApplicationMain (int argc, const char **argv, void (*server_thread) (void *), void *server_arg) {
+void X11ApplicationMain (int argc, const char **argv) {
     NSAutoreleasePool *pool;
 
 #ifdef DEBUG
@@ -812,16 +802,9 @@ void X11ApplicationMain (int argc, const char **argv, void (*server_thread) (voi
     /* Calculate the height of the menubar so we can avoid it. */
     aquaMenuBarHeight = NSHeight([[NSScreen mainScreen] frame]) -
     NSMaxY([[NSScreen mainScreen] visibleFrame]);
-  
-    APPKIT_THREAD = pthread_self();
-    SERVER_THREAD = create_thread (server_thread, server_arg);
-
-    if (!SERVER_THREAD) {
-        ErrorF("can't create secondary thread\n");
-        exit (1);
-    }
 
-    QuartzMoveToForeground();
+    /* Tell the server thread that it can proceed */
+    pthread_cond_broadcast(&server_can_start_cond);
 
     [NSApp run];
     /* not reached */
diff --git a/hw/xquartz/X11Controller.h b/hw/xquartz/X11Controller.h
index c5994bd..d33752e 100644
--- a/hw/xquartz/X11Controller.h
+++ b/hw/xquartz/X11Controller.h
@@ -100,6 +100,6 @@
 
 #endif /* __OBJC__ */
 
-void X11ControllerMain(int argc, const char **argv, void (*server_thread) (void *), void *server_arg);
+void X11ControllerMain(int argc, const char **argv);
 
 #endif /* X11CONTROLLER_H */
diff --git a/hw/xquartz/X11Controller.m b/hw/xquartz/X11Controller.m
index 8dfe4b3..01470e5 100644
--- a/hw/xquartz/X11Controller.m
+++ b/hw/xquartz/X11Controller.m
@@ -756,6 +756,6 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row
 
 @end
 
-void X11ControllerMain(int argc, const char **argv, void (*server_thread) (void *), void *server_arg) {
-    X11ApplicationMain (argc, argv, server_thread, server_arg);
+void X11ControllerMain(int argc, const char **argv) {
+    X11ApplicationMain (argc, argv);
 }
diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c
index 0643e53..86e7704 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -78,7 +78,8 @@ static int old_flags = 0;  // last known modifier state
 
 xEvent *darwinEvents = NULL;
 
-pthread_mutex_t mieqEnqueue_mutex;
+pthread_mutex_t mieqEnqueue_mutex = PTHREAD_MUTEX_INITIALIZER;
+
 static inline void mieqEnqueue_lock(void) {
     int err;
     if((err = pthread_mutex_lock(&mieqEnqueue_mutex))) {
@@ -303,17 +304,11 @@ static void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, in
 }
 
 Bool DarwinEQInit(DevicePtr pKbd, DevicePtr pPtr) { 
-    int err;
-
     if (!darwinEvents)
         darwinEvents = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum());
     if (!darwinEvents)
         FatalError("Couldn't allocate event buffer\n");
 
-    if((err = pthread_mutex_init(&mieqEnqueue_mutex, NULL))) {
-        FatalError("Couldn't allocate mieqEnqueue mutex: %d.\n", err);
-    }
-    
     mieqInit();
     mieqSetHandler(kXquartzReloadKeymap, DarwinKeyboardReloadHandler);
     mieqSetHandler(kXquartzActivate, DarwinEventHandler);
diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c
index 2cba5df..0635b48 100644
--- a/hw/xquartz/quartz.c
+++ b/hw/xquartz/quartz.c
@@ -39,7 +39,6 @@
 #include "quartz.h"
 #include "darwin.h"
 #include "darwinEvents.h"
-#include "quartzAudio.h"
 #include "pseudoramiX.h"
 #define _APPLEWM_SERVER_
 #include "applewmExt.h"
@@ -156,10 +155,6 @@ void QuartzInitOutput(
     int argc,
     char **argv )
 {
-    if (serverGeneration == 1) {
-        QuartzAudioInit();
-    }
-
     if (!RegisterBlockAndWakeupHandlers(QuartzBlockHandler,
                                         QuartzWakeupHandler,
                                         NULL))
diff --git a/hw/xquartz/quartzStartup.c b/hw/xquartz/quartzStartup.c
index 233e6e6..34eaf8a 100644
--- a/hw/xquartz/quartzStartup.c
+++ b/hw/xquartz/quartzStartup.c
@@ -37,54 +37,71 @@
 #include <unistd.h>
 #include <CoreFoundation/CoreFoundation.h>
 #include "quartzCommon.h"
+#include "quartzForeground.h"
 #include "X11Controller.h"
 #include "darwin.h"
+#include "darwinEvents.h"
+#include "quartzAudio.h"
 #include "quartz.h"
 #include "opaque.h"
 #include "micmap.h"
 
 #include <assert.h>
 
-char **envpGlobal;      // argcGlobal and argvGlobal
-                        // are from dix/globals.c
+#include <pthread.h>
 
-int main(int argc, char **argv, char **envp);
-void _InitHLTB(void);
-void DarwinHandleGUI(int argc, char **argv, char **envp);
+int dix_main(int argc, char **argv, char **envp);
+
+struct arg {
+    int argc;
+    char **argv;
+    char **envp;
+};
+
+pthread_cond_t server_can_start_cond = PTHREAD_COND_INITIALIZER;
 
 static void server_thread (void *arg) {
-  exit (main (argcGlobal, argvGlobal, envpGlobal));
+    struct arg *args = (struct arg *)arg;
+
+    /* Wait to be told we can continue */
+    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+    pthread_mutex_lock(&mutex);
+    pthread_cond_wait(&server_can_start_cond, &mutex);
+    pthread_mutex_unlock(&mutex);
+    pthread_mutex_destroy(&mutex);
+
+    exit (dix_main(args->argc, args->argv, args->envp));
 }
 
-/*
- * DarwinHandleGUI
- *  This function is called first from main(). The first time
- *  it is called we start the Mac OS X front end. The front end
- *  will call main() again from another thread to run the X
- *  server. On the second call this function loads the user
- *  preferences set by the Mac OS X front end.
- */
-void DarwinHandleGUI(int argc, char **argv, char **envp) {
-    static Bool been_here = FALSE;
+static pthread_t create_thread (void *func, void *arg) {
+    pthread_attr_t attr;
+    pthread_t tid;
+	
+    pthread_attr_init (&attr);
+    pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);
+    pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
+    pthread_create (&tid, &attr, func, arg);
+    pthread_attr_destroy (&attr);
+	
+    return tid;
+}
+
+int main(int argc, char **argv, char **envp) {
     int         i;
     int         fd[2];
 
-    if (been_here) {
-        return;
-    }
-    been_here = TRUE;
-    
+    /* Store the args to pass to dix_main() */
+    struct arg  args;
+    args.argc = argc;
+    args.argv = argv;
+    args.envp = envp;
+
     // Make a pipe to pass events
     assert( pipe(fd) == 0 );
     darwinEventReadFD = fd[0];
     darwinEventWriteFD = fd[1];
     fcntl(darwinEventReadFD, F_SETFL, O_NONBLOCK);
 
-    // Store command line arguments to pass back to main()
-    argcGlobal = argc;
-    argvGlobal = argv;
-    envpGlobal = envp;
-
     for (i = 1; i < argc; i++) {
         // Display version info without starting Mac OS X UI if requested
         if (!strcmp( argv[i], "-showconfig" ) || !strcmp( argv[i], "-version" )) {
@@ -93,16 +110,20 @@ void DarwinHandleGUI(int argc, char **argv, char **envp) {
         }
     }
 
-    /* Initially I ran the X server on the main thread, and received
-       events on the second thread. But now we may be using Carbon,
-       that needs to run on the main thread. (Otherwise, when it's
-       prebound, it will initialize itself on the wrong thread)
-       
-       grr.. but doing that means that if the X thread gets scheduled
-       before the main thread when we're _not_ prebound, things fail,
-       so initialize by hand. */
-
-    _InitHLTB();    
-    X11ControllerMain(argc, (const char **)argv, server_thread, NULL);
+    /* Create the audio mutex */
+    QuartzAudioInit();
+    
+    pthread_cond_init(&server_can_start_cond, NULL); 
+    
+    APPKIT_THREAD_ID = pthread_self();
+    SERVER_THREAD_ID = create_thread(server_thread, &args);
+
+    if (!SERVER_THREAD_ID) {
+        ErrorF("can't create secondary thread\n");
+        exit (1);
+    }
+
+    QuartzMoveToForeground();
+    X11ControllerMain(argc, (const char **)argv);
     exit(0);
 }
diff --git a/hw/xquartz/threadSafety.c b/hw/xquartz/threadSafety.c
index 7835de6..b5a4ecf 100644
--- a/hw/xquartz/threadSafety.c
+++ b/hw/xquartz/threadSafety.c
@@ -33,8 +33,8 @@
 
 #include <execinfo.h>
 
-pthread_t SERVER_THREAD;
-pthread_t APPKIT_THREAD;
+pthread_t APPKIT_THREAD_ID;
+pthread_t SERVER_THREAD_ID;
 
 void spewCallStack(void) {
     void* callstack[128];
@@ -48,7 +48,7 @@ void spewCallStack(void) {
     free(strs);
 }
 
-void _threadAssert(pthread_t tid, const char *file, const char *fun, int line) {
+void _threadSafetyAssert(pthread_t tid, const char *file, const char *fun, int line) {
     if(pthread_equal(pthread_self(), tid))
         return;
     
@@ -58,3 +58,13 @@ void _threadAssert(pthread_t tid, const char *file, const char *fun, int line) {
            file, fun, line);
     spewCallStack();
 }
+
+const char *threadSafetyID(pthread_t tid) {
+    if(pthread_equal(tid, APPKIT_THREAD_ID)) {
+        return "Appkit Thread";
+    } else if(pthread_equal(tid, SERVER_THREAD_ID)) {
+        return "Xserver Thread";
+    } else {        
+        return "Unknown Thread";
+    }
+}
diff --git a/hw/xquartz/threadSafety.h b/hw/xquartz/threadSafety.h
index ed2ad9f..7b00910 100644
--- a/hw/xquartz/threadSafety.h
+++ b/hw/xquartz/threadSafety.h
@@ -31,22 +31,23 @@
 
 #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")
+extern pthread_t APPKIT_THREAD_ID;
+extern pthread_t SERVER_THREAD_ID;
 
 /* Dump the call stack */
 void spewCallStack(void);
 
 /* Print message to ErrorF if we're in the wrong thread */
-void _threadAssert(pthread_t tid, const char *file, const char *fun, int line);
+void _threadSafetyAssert(pthread_t tid, const char *file, const char *fun, int line);
+
+/* Get a string that identifies our thread nicely */
+const char *threadSafetyID(pthread_t tid);
 
-#define threadAssert(tid) _threadAssert(tid, __FILE__, __FUNCTION__, __LINE__)
+#define threadSafetyAssert(tid) _threadSafetyAssert(tid, __FILE__, __FUNCTION__, __LINE__)
 
 #ifdef DEBUG_THREADS
-#define TA_SERVER() threadAssert(SERVER_THREAD)
-#define TA_APPKIT() threadAssert(APPKIT_THREAD)
+#define TA_APPKIT() threadSafetyAssert(APPKIT_THREAD_ID)
+#define TA_SERVER() threadSafetyAssert(SERVER_THREAD_ID)
 #else
 #define TA_SERVER() 
 #define TA_APPKIT() 


More information about the xorg-commit mailing list