summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon TURNEY <jon.turney@dronecode.org.uk>2010-04-05 13:57:24 +0100
committerJon TURNEY <jon.turney@dronecode.org.uk>2012-01-26 14:10:24 +0000
commit95b1391fe3d3192abdfbad4140513b2112cfa02a (patch)
treed9094de40bbffd960c73c7ec370dd37eb207b31a
parent0659437f5ec0e3f646373394f5f9c5461e2170f3 (diff)
hw/xwin: Chain IOError handlers to avoid longjmp across threads
Avoid crashes on shutdown due to the undefined behaviour of calling longjmp() on the result of setjmp() from a different thread, by chaining IOError handlers and only jumping back up to the frame for this thread Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk> Reviewed-by: Colin Harrison <colin.harrison@virgin.net>
-rw-r--r--hw/xwin/winclipboardthread.c23
-rw-r--r--hw/xwin/winmultiwindowwm.c54
2 files changed, 52 insertions, 25 deletions
diff --git a/hw/xwin/winclipboardthread.c b/hw/xwin/winclipboardthread.c
index 890a15bc3..bc4bc3059 100644
--- a/hw/xwin/winclipboardthread.c
+++ b/hw/xwin/winclipboardthread.c
@@ -63,6 +63,8 @@ extern Window g_iClipboardWindow;
static jmp_buf g_jmpEntry;
static int clipboardRestarts = 0;
+static XIOErrorHandler g_winClipboardOldIOErrorHandler;
+static pthread_t g_winClipboardProcThread;
Bool g_fUnicodeSupport = FALSE;
Bool g_fUseUnicode = FALSE;
@@ -128,6 +130,11 @@ winClipboardProc (void *pvNotUsed)
ErrorF ("winClipboardProc - Warning: Locale not supported by X.\n");
}
+ /* Set error handler */
+ XSetErrorHandler (winClipboardErrorHandler);
+ g_winClipboardProcThread = pthread_self();
+ g_winClipboardOldIOErrorHandler = XSetIOErrorHandler (winClipboardIOErrorHandler);
+
/* Set jump point for Error exits */
iReturn = setjmp (g_jmpEntry);
@@ -150,10 +157,6 @@ winClipboardProc (void *pvNotUsed)
/* Use our generated cookie for authentication */
winSetAuthorization();
- /* Set error handler */
- XSetErrorHandler (winClipboardErrorHandler);
- XSetIOErrorHandler (winClipboardIOErrorHandler);
-
/* Initialize retry count */
iRetries = 0;
@@ -511,8 +514,14 @@ winClipboardIOErrorHandler (Display *pDisplay)
{
ErrorF ("winClipboardIOErrorHandler!\n\n");
- /* Restart at the main entry point */
- longjmp (g_jmpEntry, WIN_JMP_ERROR_IO);
-
+ if (pthread_equal(pthread_self(),g_winClipboardProcThread))
+ {
+ /* Restart at the main entry point */
+ longjmp (g_jmpEntry, WIN_JMP_ERROR_IO);
+ }
+
+ if (g_winClipboardOldIOErrorHandler)
+ g_winClipboardOldIOErrorHandler(pDisplay);
+
return 0;
}
diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 7c4056388..c82ffa5f9 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -204,7 +204,11 @@ winUpdateWindowPosition (HWND hWnd, Bool reshape, HWND *zstyle);
*/
static jmp_buf g_jmpWMEntry;
+static XIOErrorHandler g_winMultiWindowWMOldIOErrorHandler;
+static pthread_t g_winMultiWindowWMThread;
static jmp_buf g_jmpXMsgProcEntry;
+static XIOErrorHandler g_winMultiWindowXMsgProcOldIOErrorHandler;
+static pthread_t g_winMultiWindowXMsgProcThread;
static Bool g_shutdown = FALSE;
static Bool redirectError = FALSE;
static Bool g_fAnotherWMRunning = FALSE;
@@ -901,9 +905,14 @@ winMultiWindowXMsgProc (void *pArg)
ErrorF ("winMultiWindowXMsgProc - pthread_mutex_unlock () returned.\n");
+ /* Install our error handler */
+ XSetErrorHandler (winMultiWindowXMsgProcErrorHandler);
+ g_winMultiWindowXMsgProcThread = pthread_self();
+ g_winMultiWindowXMsgProcOldIOErrorHandler = XSetIOErrorHandler (winMultiWindowXMsgProcIOErrorHandler);
+
/* Set jump point for IO Error exits */
iReturn = setjmp (g_jmpXMsgProcEntry);
-
+
/* Check if we should continue operations */
if (iReturn != WIN_JMP_ERROR_IO
&& iReturn != WIN_JMP_OKAY)
@@ -919,10 +928,6 @@ winMultiWindowXMsgProc (void *pArg)
pthread_exit (NULL);
}
- /* Install our error handler */
- XSetErrorHandler (winMultiWindowXMsgProcErrorHandler);
- XSetIOErrorHandler (winMultiWindowXMsgProcIOErrorHandler);
-
/* Setup the display connection string x */
snprintf (pszDisplay,
512, "127.0.0.1:%s.%d", display, (int)pProcArg->dwScreen);
@@ -1310,9 +1315,14 @@ winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
ErrorF ("winInitMultiWindowWM - pthread_mutex_unlock () returned.\n");
+ /* Install our error handler */
+ XSetErrorHandler (winMultiWindowWMErrorHandler);
+ g_winMultiWindowWMThread = pthread_self();
+ g_winMultiWindowWMOldIOErrorHandler = XSetIOErrorHandler (winMultiWindowWMIOErrorHandler);
+
/* Set jump point for IO Error exits */
iReturn = setjmp (g_jmpWMEntry);
-
+
/* Check if we should continue operations */
if (iReturn != WIN_JMP_ERROR_IO
&& iReturn != WIN_JMP_OKAY)
@@ -1328,10 +1338,6 @@ winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
pthread_exit (NULL);
}
- /* Install our error handler */
- XSetErrorHandler (winMultiWindowWMErrorHandler);
- XSetIOErrorHandler (winMultiWindowWMIOErrorHandler);
-
/* Setup the display connection string x */
snprintf (pszDisplay,
512,
@@ -1458,12 +1464,18 @@ winMultiWindowWMIOErrorHandler (Display *pDisplay)
{
ErrorF ("winMultiWindowWMIOErrorHandler!\n\n");
- if (g_shutdown)
- pthread_exit(NULL);
+ if (pthread_equal(pthread_self(),g_winMultiWindowWMThread))
+ {
+ if (g_shutdown)
+ pthread_exit(NULL);
+
+ /* Restart at the main entry point */
+ longjmp (g_jmpWMEntry, WIN_JMP_ERROR_IO);
+ }
+
+ if (g_winMultiWindowWMOldIOErrorHandler)
+ g_winMultiWindowWMOldIOErrorHandler(pDisplay);
- /* Restart at the main entry point */
- longjmp (g_jmpWMEntry, WIN_JMP_ERROR_IO);
-
return 0;
}
@@ -1498,9 +1510,15 @@ winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay)
{
ErrorF ("winMultiWindowXMsgProcIOErrorHandler!\n\n");
- /* Restart at the main entry point */
- longjmp (g_jmpXMsgProcEntry, WIN_JMP_ERROR_IO);
-
+ if (pthread_equal(pthread_self(),g_winMultiWindowXMsgProcThread))
+ {
+ /* Restart at the main entry point */
+ longjmp (g_jmpXMsgProcEntry, WIN_JMP_ERROR_IO);
+ }
+
+ if (g_winMultiWindowXMsgProcOldIOErrorHandler)
+ g_winMultiWindowXMsgProcOldIOErrorHandler(pDisplay);
+
return 0;
}