diff options
author | Jon TURNEY <jon.turney@dronecode.org.uk> | 2010-04-05 13:57:24 +0100 |
---|---|---|
committer | Jon TURNEY <jon.turney@dronecode.org.uk> | 2012-01-26 14:10:24 +0000 |
commit | 95b1391fe3d3192abdfbad4140513b2112cfa02a (patch) | |
tree | d9094de40bbffd960c73c7ec370dd37eb207b31a /hw/xwin/winmultiwindowwm.c | |
parent | 0659437f5ec0e3f646373394f5f9c5461e2170f3 (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>
Diffstat (limited to 'hw/xwin/winmultiwindowwm.c')
-rw-r--r-- | hw/xwin/winmultiwindowwm.c | 54 |
1 files changed, 36 insertions, 18 deletions
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; } |