XQuartz: xpbproxy: Cleanup xpbproxy threading

Confine xpbproxy to a single thread
Runs inside its own CFRunLoop

Signed-off-by: Jeremy Huddleston <jeremyhu@freedesktop.org>
This commit is contained in:
Jeremy Huddleston 2010-03-20 03:28:57 -07:00 committed by Jeremy Huddleston
parent 9c9c3a85b0
commit d16bc8a3cd
5 changed files with 84 additions and 103 deletions

View File

@ -52,7 +52,7 @@
#include <Xplugin.h> #include <Xplugin.h>
// pbproxy/pbproxy.h // pbproxy/pbproxy.h
extern BOOL xpbproxy_init (void); extern int xpbproxy_run (void);
#define DEFAULTS_FILE X11LIBDIR"/X11/xserver/Xquartz.plist" #define DEFAULTS_FILE X11LIBDIR"/X11/xserver/Xquartz.plist"
@ -908,6 +908,26 @@ environment the next time you start X11?", @"Startup xinitrc dialog");
[X11App prefs_synchronize]; [X11App prefs_synchronize];
} }
static inline 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 *xpbproxy_x_thread(void *args) {
xpbproxy_run();
fprintf(stderr, "xpbproxy thread is terminating unexpectedly.\n");
return NULL;
}
void X11ApplicationMain (int argc, char **argv, char **envp) { void X11ApplicationMain (int argc, char **argv, char **envp) {
NSAutoreleasePool *pool; NSAutoreleasePool *pool;
@ -962,8 +982,7 @@ void X11ApplicationMain (int argc, char **argv, char **envp) {
*/ */
check_xinitrc(); check_xinitrc();
if(!xpbproxy_init()) create_thread(xpbproxy_x_thread, NULL);
fprintf(stderr, "Error initializing xpbproxy\n");
#if XQUARTZ_SPARKLE #if XQUARTZ_SPARKLE
[[X11App controller] setup_sparkle]; [[X11App controller] setup_sparkle];

View File

@ -84,16 +84,10 @@ int main (int argc, const char *argv[]) {
app_prefs_domain_cfstr = CFStringCreateWithCString(NULL, app_prefs_domain, kCFStringEncodingUTF8); app_prefs_domain_cfstr = CFStringCreateWithCString(NULL, app_prefs_domain, kCFStringEncodingUTF8);
if(!xpbproxy_init())
return EXIT_FAILURE;
signal (SIGINT, signal_handler); signal (SIGINT, signal_handler);
signal (SIGTERM, signal_handler); signal (SIGTERM, signal_handler);
signal (SIGHUP, signal_handler); signal (SIGHUP, signal_handler);
signal (SIGPIPE, SIG_IGN); signal (SIGPIPE, SIG_IGN);
[NSApplication sharedApplication]; return xpbproxy_run();
[NSApp run];
return EXIT_SUCCESS;
} }

View File

@ -82,20 +82,7 @@ static int x_error_handler (Display *dpy, XErrorEvent *errevent) {
return 0; return 0;
} }
static inline pthread_t create_thread(void *func, void *arg) { int xpbproxy_run (void) {
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 *xpbproxy_x_thread(void *args) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
size_t i; size_t i;
@ -118,7 +105,7 @@ static void *xpbproxy_x_thread(void *args) {
if (xpbproxy_dpy == NULL) { if (xpbproxy_dpy == NULL) {
fprintf (stderr, "xpbproxy: can't open default display\n"); fprintf (stderr, "xpbproxy: can't open default display\n");
[pool release]; [pool release];
return NULL; return EXIT_FAILURE;
} }
XSetIOErrorHandler (x_io_error_handler); XSetIOErrorHandler (x_io_error_handler);
@ -128,7 +115,7 @@ static void *xpbproxy_x_thread(void *args) {
&xpbproxy_apple_wm_error_base)) { &xpbproxy_apple_wm_error_base)) {
fprintf (stderr, "xpbproxy: can't open AppleWM server extension\n"); fprintf (stderr, "xpbproxy: can't open AppleWM server extension\n");
[pool release]; [pool release];
return NULL; return EXIT_FAILURE;
} }
xpbproxy_have_xfixes = XFixesQueryExtension(xpbproxy_dpy, &xpbproxy_xfixes_event_base, &xpbproxy_xfixes_error_base); xpbproxy_have_xfixes = XFixesQueryExtension(xpbproxy_dpy, &xpbproxy_xfixes_event_base, &xpbproxy_xfixes_error_base);
@ -140,18 +127,14 @@ static void *xpbproxy_x_thread(void *args) {
if(!xpbproxy_input_register()) { if(!xpbproxy_input_register()) {
[pool release]; [pool release];
return NULL; return EXIT_FAILURE;
} }
[pool release]; [pool release];
xpbproxy_input_loop(); CFRunLoopRun();
return NULL;
}
BOOL xpbproxy_init (void) { return EXIT_SUCCESS;
create_thread(xpbproxy_x_thread, NULL);
return TRUE;
} }
id xpbproxy_selection_object (void) { id xpbproxy_selection_object (void) {

View File

@ -67,7 +67,7 @@ extern void xpbproxy_set_is_active (BOOL state);
extern BOOL xpbproxy_get_is_active (void); extern BOOL xpbproxy_get_is_active (void);
extern id xpbproxy_selection_object (void); extern id xpbproxy_selection_object (void);
extern Time xpbproxy_current_timestamp (void); extern Time xpbproxy_current_timestamp (void);
extern BOOL xpbproxy_init (void); extern int xpbproxy_run (void);
extern Display *xpbproxy_dpy; extern Display *xpbproxy_dpy;
extern int xpbproxy_apple_wm_event_base, xpbproxy_apple_wm_error_base; extern int xpbproxy_apple_wm_event_base, xpbproxy_apple_wm_error_base;
@ -76,7 +76,6 @@ extern BOOL xpbproxy_have_xfixes;
/* from x-input.m */ /* from x-input.m */
extern BOOL xpbproxy_input_register (void); extern BOOL xpbproxy_input_register (void);
extern void xpbproxy_input_loop();
#ifdef DEBUG #ifdef DEBUG
/* BEWARE: this can cause a string memory leak, according to the leaks program. */ /* BEWARE: this can cause a string memory leak, according to the leaks program. */

View File

@ -39,17 +39,12 @@
#include <unistd.h> #include <unistd.h>
#include <pthread.h>
static CFRunLoopSourceRef xpbproxy_dpy_source; static CFRunLoopSourceRef xpbproxy_dpy_source;
#ifdef STANDALONE_XPBPROXY #ifdef STANDALONE_XPBPROXY
BOOL xpbproxy_prefs_reload = NO; BOOL xpbproxy_prefs_reload = NO;
#endif #endif
static pthread_mutex_t xpbproxy_dpy_rdy_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t xpbproxy_dpy_rdy_cond = PTHREAD_COND_INITIALIZER;
/* Timestamp when the X server last told us it's active */ /* Timestamp when the X server last told us it's active */
static Time last_activation_time; static Time last_activation_time;
@ -88,58 +83,51 @@ static void x_event_apple_wm_notify(XAppleWMNotifyEvent *e) {
} }
} }
void xpbproxy_input_loop() { static void xpbproxy_process_xevents(void) {
pthread_mutex_lock(&xpbproxy_dpy_rdy_lock); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
while(true) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if(pool == nil) { if(pool == nil) {
fprintf(stderr, "unable to allocate/init auto release pool!\n"); fprintf(stderr, "unable to allocate/init auto release pool!\n");
break; return;
}
while (XPending(xpbproxy_dpy) != 0) {
XEvent e;
pthread_mutex_unlock(&xpbproxy_dpy_rdy_lock);
XNextEvent (xpbproxy_dpy, &e);
switch (e.type) {
case SelectionClear:
if([xpbproxy_selection_object() is_active])
[xpbproxy_selection_object () clear_event:&e.xselectionclear];
break;
case SelectionRequest:
[xpbproxy_selection_object () request_event:&e.xselectionrequest];
break;
case SelectionNotify:
[xpbproxy_selection_object () notify_event:&e.xselection];
break;
case PropertyNotify:
[xpbproxy_selection_object () property_event:&e.xproperty];
break;
default:
if(e.type >= xpbproxy_apple_wm_event_base &&
e.type < xpbproxy_apple_wm_event_base + AppleWMNumberEvents) {
x_event_apple_wm_notify((XAppleWMNotifyEvent *) &e);
} else if(e.type == xpbproxy_xfixes_event_base + XFixesSelectionNotify) {
[xpbproxy_selection_object() xfixes_selection_notify:(XFixesSelectionNotifyEvent *)&e];
}
break;
}
XFlush(xpbproxy_dpy);
pthread_mutex_lock(&xpbproxy_dpy_rdy_lock);
}
[pool release];
pthread_cond_wait(&xpbproxy_dpy_rdy_cond, &xpbproxy_dpy_rdy_lock);
} }
while (XPending(xpbproxy_dpy) != 0) {
XEvent e;
XNextEvent (xpbproxy_dpy, &e);
switch (e.type) {
case SelectionClear:
if([xpbproxy_selection_object() is_active])
[xpbproxy_selection_object () clear_event:&e.xselectionclear];
break;
case SelectionRequest:
[xpbproxy_selection_object () request_event:&e.xselectionrequest];
break;
case SelectionNotify:
[xpbproxy_selection_object () notify_event:&e.xselection];
break;
case PropertyNotify:
[xpbproxy_selection_object () property_event:&e.xproperty];
break;
default:
if(e.type >= xpbproxy_apple_wm_event_base &&
e.type < xpbproxy_apple_wm_event_base + AppleWMNumberEvents) {
x_event_apple_wm_notify((XAppleWMNotifyEvent *) &e);
} else if(e.type == xpbproxy_xfixes_event_base + XFixesSelectionNotify) {
[xpbproxy_selection_object() xfixes_selection_notify:(XFixesSelectionNotifyEvent *)&e];
}
break;
}
XFlush(xpbproxy_dpy);
}
[pool release];
} }
static BOOL add_input_socket (int sock, CFOptionFlags callback_types, static BOOL add_input_socket (int sock, CFOptionFlags callback_types,
@ -161,7 +149,7 @@ static BOOL add_input_socket (int sock, CFOptionFlags callback_types,
if (*cf_source == NULL) if (*cf_source == NULL)
return FALSE; return FALSE;
CFRunLoopAddSource (CFRunLoopGetMain (), CFRunLoopAddSource (CFRunLoopGetCurrent (),
*cf_source, kCFRunLoopDefaultMode); *cf_source, kCFRunLoopDefaultMode);
return TRUE; return TRUE;
} }
@ -176,9 +164,7 @@ static void x_input_callback (CFSocketRef sock, CFSocketCallBackType type,
} }
#endif #endif
pthread_mutex_lock(&xpbproxy_dpy_rdy_lock); xpbproxy_process_xevents();
pthread_cond_broadcast(&xpbproxy_dpy_rdy_cond);
pthread_mutex_unlock(&xpbproxy_dpy_rdy_lock);
} }
BOOL xpbproxy_input_register(void) { BOOL xpbproxy_input_register(void) {