diff options
author | Jon TURNEY <jon.turney@dronecode.org.uk> | 2010-02-18 21:16:15 -0600 |
---|---|---|
committer | Jon TURNEY <jon.turney@dronecode.org.uk> | 2011-09-01 15:50:37 +0100 |
commit | 723df5c7b92456e8505544dba053c859c7ef4ca8 (patch) | |
tree | c4182033d11827049b41e1201391a4942a13bb76 | |
parent | 16f03a1c9eb009c9ce419355dca0fa1a6ae7f6fd (diff) |
Cygwin/X: Cause the X server to terminate if clipboard or WM internal client threads exit due to an error
Calling FatalError from an internal client thread is a no-no, so these
failures are silent at the moment (in the sense that no pop-up occurs to
tell the user that we are terminating or why).
Really we should either improve the way we try to avoid the internal
clipboard client getting killed or perhaps restart it after an interval.
Avoiding getting killed by the XDM is horribly heuristic at the moment,
as we basically try to guess about what the XDM is doing, so this is
always going to be fragile. (Should just check that we can't actually
intercept the close request for the client)
Restarting the clipboard client thread is complicated by the fact that
at the moment the clipboard thread exits on server regeneration and is
restarted by hooks installed by InitInput())
(So we either need to make arrangements not restart when server is restarting,
or only start once and properly re-cache atoms on server regeneration)
Also, I'm just noticing I should be using pthread_kill() to ensure the
signal is delivered to the thread which is running the main dispatch loop
so that will exit the select() it may be blocked in and notice that
DE_TERMINATE is set.
Also: http://xkcd.com/292/
Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
Signed-off-by: Yaakov Selkowitz <yselkowitz@users.sourceforge.net>
-rw-r--r-- | hw/xwin/winclipboardthread.c | 31 | ||||
-rw-r--r-- | hw/xwin/winmultiwindowwm.c | 22 |
2 files changed, 47 insertions, 6 deletions
diff --git a/hw/xwin/winclipboardthread.c b/hw/xwin/winclipboardthread.c index 41eeba0d4..faa844511 100644 --- a/hw/xwin/winclipboardthread.c +++ b/hw/xwin/winclipboardthread.c @@ -76,6 +76,9 @@ winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr); static int winClipboardIOErrorHandler (Display *pDisplay); +static void +winClipboardThreadExit(void *arg); + /* * Main thread function */ @@ -101,6 +104,8 @@ winClipboardProc (void *pvNotUsed) char szDisplay[512]; int iSelectError; + pthread_cleanup_push(&winClipboardThreadExit, NULL); + ErrorF ("winClipboardProc - Hello\n"); ++clipboardRestarts; @@ -140,9 +145,9 @@ winClipboardProc (void *pvNotUsed) } else if (iReturn == WIN_JMP_ERROR_IO) { - /* TODO: Cleanup the Win32 window and free any allocated memory */ - ErrorF ("winClipboardProc - setjmp returned for IO Error Handler.\n"); - pthread_exit (NULL); + /* TODO: cleanup and free any allocated memory */ + ErrorF("winClipboardProc - setjmp returned for IO Error Handler\n"); + goto winClipboardProc_Done; } /* Use our generated cookie for authentication */ @@ -196,7 +201,7 @@ winClipboardProc (void *pvNotUsed) goto winClipboardProc_Done; } - /* Save the display in the screen privates */ + /* Save the display in a global used by the wndproc */ g_pClipboardDisplay = pDisplay; ErrorF ("winClipboardProc - XOpenDisplay () returned and " @@ -291,7 +296,10 @@ winClipboardProc (void *pvNotUsed) /* Pre-flush Windows messages */ if (!winClipboardFlushWindowsMessageQueue (hwnd)) - return 0; + { + ErrorF ("winClipboardProc - winClipboardFlushWindowsMessageQueue failed\n"); + pthread_exit (NULL); + } /* Signal that the clipboard client has started */ g_fClipboardStarted = TRUE; @@ -471,6 +479,8 @@ winClipboardProc_Done: kill(getpid(), SIGTERM); } + pthread_cleanup_pop(0); + return NULL; } @@ -512,3 +522,14 @@ winClipboardIOErrorHandler (Display *pDisplay) return 0; } + +/* + * winClipboardThreadExit - Thread exit handler + */ + +static void +winClipboardThreadExit(void *arg) +{ + /* clipboard thread has exited, stop server as well */ + kill(getpid(), SIGTERM); +} diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c index 67a58a076..b156a0f5a 100644 --- a/hw/xwin/winmultiwindowwm.c +++ b/hw/xwin/winmultiwindowwm.c @@ -179,6 +179,9 @@ winMultiWindowXMsgProcErrorHandler (Display *pDisplay, XErrorEvent *pErr); static int winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay); +static void +winMultiWindowThreadExit(void *arg); + static int winRedirectErrorHandler (Display *pDisplay, XErrorEvent *pErr); @@ -626,6 +629,8 @@ winMultiWindowWMProc (void *pArg) { WMProcArgPtr pProcArg = (WMProcArgPtr)pArg; WMInfoPtr pWMInfo = pProcArg->pWMInfo; + + pthread_cleanup_push(&winMultiWindowThreadExit, NULL); /* Initialize the Window Manager */ winInitMultiWindowWM (pWMInfo, pProcArg); @@ -838,6 +843,9 @@ winMultiWindowWMProc (void *pArg) #if CYGMULTIWINDOW_DEBUG ErrorF("-winMultiWindowWMProc ()\n"); #endif + + pthread_cleanup_pop(0); + return NULL; } @@ -860,6 +868,8 @@ winMultiWindowXMsgProc (void *pArg) int iReturn; XIconSize *xis; + pthread_cleanup_push(&winMultiWindowThreadExit, NULL); + ErrorF ("winMultiWindowXMsgProc - Hello\n"); /* Check that argument pointer is not invalid */ @@ -1176,7 +1186,7 @@ winMultiWindowXMsgProc (void *pArg) } XCloseDisplay (pProcArg->pDisplay); - pthread_exit (NULL); + pthread_cleanup_pop(0); return NULL; } @@ -1502,6 +1512,16 @@ winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay) return 0; } +/* + * winMultiWindowThreadExit - Thread exit handler + */ + +static void +winMultiWindowThreadExit(void *arg) +{ + /* multiwindow client thread has exited, stop server as well */ + kill(getpid(), SIGTERM); +} /* * Catch RedirectError to detect other window manager running |