XQuartz: Cleaned up startup and thread creation a tad.

(cherry picked from commit c861fe00e1)
(cherry picked from commit ef1c520537)
This commit is contained in:
Jeremy Huddleston 2008-04-26 19:21:05 -07:00
parent 4a811c665a
commit 90c4fd7a49
10 changed files with 95 additions and 98 deletions

View File

@ -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();

View File

@ -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;

View File

@ -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 */

View File

@ -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 */

View File

@ -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);
}

View File

@ -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);

View File

@ -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))

View File

@ -37,8 +37,11 @@
#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"
@ -51,46 +54,60 @@
#include <assert.h>
#endif
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" )) {
@ -99,16 +116,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. */
/* 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);
_InitHLTB();
X11ControllerMain(argc, (const char **)argv, server_thread, NULL);
if (!SERVER_THREAD_ID) {
ErrorF("can't create secondary thread\n");
exit (1);
}
QuartzMoveToForeground();
X11ControllerMain(argc, (const char **)argv);
exit(0);
}

View File

@ -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";
}
}

View File

@ -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);
#define threadAssert(tid) _threadAssert(tid, __FILE__, __FUNCTION__, __LINE__)
/* Get a string that identifies our thread nicely */
const char *threadSafetyID(pthread_t tid);
#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()