diff options
author | Jeremy Huddleston <jeremyhu@freedesktop.org> | 2009-01-02 10:58:40 -0800 |
---|---|---|
committer | Jeremy Huddleston <jeremyhu@freedesktop.org> | 2009-01-02 11:02:36 -0800 |
commit | adbfd49da2453b58a9e13b09c62e0611ea1c3f77 (patch) | |
tree | 6f36bab61fa8b3514223ada9dd9c292673894cb7 | |
parent | 0676a580fcc05d54049269028a34358935a4101c (diff) |
XQuartz: pbproxy: Push dpy init and CFRunLoop hook setup into the pbproxy thread to avoid possible deadlock
(cherry picked from commit 49e59d32b88e4fad070f230b5efaa261b47f78db)
-rw-r--r-- | hw/xquartz/pbproxy/main.m | 29 | ||||
-rw-r--r-- | hw/xquartz/pbproxy/pbproxy.h | 1 | ||||
-rw-r--r-- | hw/xquartz/pbproxy/x-input.m | 21 |
3 files changed, 27 insertions, 24 deletions
diff --git a/hw/xquartz/pbproxy/main.m b/hw/xquartz/pbproxy/main.m index 247ff7475..5bc518243 100644 --- a/hw/xquartz/pbproxy/main.m +++ b/hw/xquartz/pbproxy/main.m @@ -65,13 +65,26 @@ static int x_io_error_handler (Display *dpy) { } static int x_error_handler (Display *dpy, XErrorEvent *errevent) { return 0; } -BOOL xpbproxy_init (void) { +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) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; size_t i; for(i=0, xpbproxy_dpy=NULL; !xpbproxy_dpy && i<5; i++) { xpbproxy_dpy = XOpenDisplay(NULL); @@ -86,39 +99,45 @@ BOOL xpbproxy_init (void) { sleep(1); } if (xpbproxy_dpy == NULL) { fprintf (stderr, "xpbproxy: can't open default display\n"); [pool release]; - return FALSE; + return NULL; } XSetIOErrorHandler (x_io_error_handler); XSetErrorHandler (x_error_handler); if (!XAppleWMQueryExtension (xpbproxy_dpy, &xpbproxy_apple_wm_event_base, &xpbproxy_apple_wm_error_base)) { fprintf (stderr, "xpbproxy: can't open AppleWM server extension\n"); [pool release]; - return FALSE; + return NULL; } xpbproxy_have_xfixes = XFixesQueryExtension(xpbproxy_dpy, &xpbproxy_xfixes_event_base, &xpbproxy_xfixes_error_base); XAppleWMSelectInput (xpbproxy_dpy, AppleWMActivationNotifyMask | AppleWMPasteboardNotifyMask); _selection_object = [[x_selection alloc] init]; if(!xpbproxy_input_register()) { [pool release]; - return FALSE; + return NULL; } [pool release]; - + + xpbproxy_input_loop(); + return NULL; +} + +BOOL xpbproxy_init (void) { + create_thread(xpbproxy_x_thread, NULL); return TRUE; } id xpbproxy_selection_object (void) { return _selection_object; } diff --git a/hw/xquartz/pbproxy/pbproxy.h b/hw/xquartz/pbproxy/pbproxy.h index d24d08bfd..a6798efea 100644 --- a/hw/xquartz/pbproxy/pbproxy.h +++ b/hw/xquartz/pbproxy/pbproxy.h @@ -73,12 +73,13 @@ extern Display *xpbproxy_dpy; extern int xpbproxy_apple_wm_event_base, xpbproxy_apple_wm_error_base; extern int xpbproxy_xfixes_event_base, xpbproxy_xfixes_error_base; extern BOOL xpbproxy_have_xfixes; /* from x-input.m */ extern BOOL xpbproxy_input_register (void); +extern void xpbproxy_input_loop(); #ifdef DEBUG /* BEWARE: this can cause a string memory leak, according to the leaks program. */ # define DB(msg, args...) debug_printf("%s:%s:%d " msg, __FILE__, __FUNCTION__, __LINE__, ##args) #else # define DB(msg, args...) do {} while (0) diff --git a/hw/xquartz/pbproxy/x-input.m b/hw/xquartz/pbproxy/x-input.m index acd01af8c..6ba30c610 100644 --- a/hw/xquartz/pbproxy/x-input.m +++ b/hw/xquartz/pbproxy/x-input.m @@ -47,25 +47,12 @@ static CFRunLoopSourceRef xpbproxy_dpy_source; BOOL xpbproxy_prefs_reload = NO; #endif static pthread_mutex_t xpbproxy_dpy_rdy_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t xpbproxy_dpy_rdy_cond = PTHREAD_COND_INITIALIZER; -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; -} - /* Timestamp when the X server last told us it's active */ static Time last_activation_time; static void x_event_apple_wm_notify(XAppleWMNotifyEvent *e) { int type = e->type - xpbproxy_apple_wm_event_base; int kind = e->kind; @@ -98,13 +85,13 @@ static void x_event_apple_wm_notify(XAppleWMNotifyEvent *e) { [xpbproxy_selection_object() x_copy:e->time]; } break; } } -static void *xpbproxy_input_thread(void *args) { +void xpbproxy_input_loop() { pthread_mutex_lock(&xpbproxy_dpy_rdy_lock); while(true) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; if(pool == nil) { fprintf(stderr, "unable to allocate/init auto release pool!\n"); @@ -150,14 +137,12 @@ static void *xpbproxy_input_thread(void *args) { } [pool release]; pthread_cond_wait(&xpbproxy_dpy_rdy_cond, &xpbproxy_dpy_rdy_lock); } - - return NULL; } static BOOL add_input_socket (int sock, CFOptionFlags callback_types, CFSocketCallBack callback, const CFSocketContext *ctx, CFRunLoopSourceRef *cf_source) { CFSocketRef cf_sock; @@ -173,13 +158,13 @@ static BOOL add_input_socket (int sock, CFOptionFlags callback_types, cf_sock, 0); CFRelease (cf_sock); if (*cf_source == NULL) return FALSE; - CFRunLoopAddSource (CFRunLoopGetCurrent (), + CFRunLoopAddSource (CFRunLoopGetMain (), *cf_source, kCFRunLoopDefaultMode); return TRUE; } static void x_input_callback (CFSocketRef sock, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) { @@ -194,11 +179,9 @@ static void x_input_callback (CFSocketRef sock, CFSocketCallBackType type, pthread_mutex_lock(&xpbproxy_dpy_rdy_lock); pthread_cond_broadcast(&xpbproxy_dpy_rdy_cond); pthread_mutex_unlock(&xpbproxy_dpy_rdy_lock); } BOOL xpbproxy_input_register(void) { - create_thread(xpbproxy_input_thread, NULL); - return add_input_socket(ConnectionNumber(xpbproxy_dpy), kCFSocketReadCallBack, x_input_callback, NULL, &xpbproxy_dpy_source); } |