summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon TURNEY <jon.turney@dronecode.org.uk>2010-02-18 21:16:15 -0600
committerJon TURNEY <jon.turney@dronecode.org.uk>2011-09-01 15:50:37 +0100
commit723df5c7b92456e8505544dba053c859c7ef4ca8 (patch)
treec4182033d11827049b41e1201391a4942a13bb76
parent16f03a1c9eb009c9ce419355dca0fa1a6ae7f6fd (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.c31
-rw-r--r--hw/xwin/winmultiwindowwm.c22
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