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>
This commit is contained in:
parent
0659437f5e
commit
95b1391fe3
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user