XQuartz: Cleaned up startup and thread creation a tad.
(cherry picked from commitc861fe00e1
) (cherry picked from commitef1c520537
)
This commit is contained in:
parent
4a811c665a
commit
90c4fd7a49
16
dix/main.c
16
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();
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user