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 jmp_buf g_jmpEntry;
|
||||||
static int clipboardRestarts = 0;
|
static int clipboardRestarts = 0;
|
||||||
|
static XIOErrorHandler g_winClipboardOldIOErrorHandler;
|
||||||
|
static pthread_t g_winClipboardProcThread;
|
||||||
|
|
||||||
Bool g_fUnicodeSupport = FALSE;
|
Bool g_fUnicodeSupport = FALSE;
|
||||||
Bool g_fUseUnicode = FALSE;
|
Bool g_fUseUnicode = FALSE;
|
||||||
|
@ -128,6 +130,11 @@ winClipboardProc (void *pvNotUsed)
|
||||||
ErrorF ("winClipboardProc - Warning: Locale not supported by X.\n");
|
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 */
|
/* Set jump point for Error exits */
|
||||||
iReturn = setjmp (g_jmpEntry);
|
iReturn = setjmp (g_jmpEntry);
|
||||||
|
|
||||||
|
@ -150,10 +157,6 @@ winClipboardProc (void *pvNotUsed)
|
||||||
/* Use our generated cookie for authentication */
|
/* Use our generated cookie for authentication */
|
||||||
winSetAuthorization();
|
winSetAuthorization();
|
||||||
|
|
||||||
/* Set error handler */
|
|
||||||
XSetErrorHandler (winClipboardErrorHandler);
|
|
||||||
XSetIOErrorHandler (winClipboardIOErrorHandler);
|
|
||||||
|
|
||||||
/* Initialize retry count */
|
/* Initialize retry count */
|
||||||
iRetries = 0;
|
iRetries = 0;
|
||||||
|
|
||||||
|
@ -511,8 +514,14 @@ winClipboardIOErrorHandler (Display *pDisplay)
|
||||||
{
|
{
|
||||||
ErrorF ("winClipboardIOErrorHandler!\n\n");
|
ErrorF ("winClipboardIOErrorHandler!\n\n");
|
||||||
|
|
||||||
|
if (pthread_equal(pthread_self(),g_winClipboardProcThread))
|
||||||
|
{
|
||||||
/* Restart at the main entry point */
|
/* Restart at the main entry point */
|
||||||
longjmp (g_jmpEntry, WIN_JMP_ERROR_IO);
|
longjmp (g_jmpEntry, WIN_JMP_ERROR_IO);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_winClipboardOldIOErrorHandler)
|
||||||
|
g_winClipboardOldIOErrorHandler(pDisplay);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,7 +204,11 @@ winUpdateWindowPosition (HWND hWnd, Bool reshape, HWND *zstyle);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static jmp_buf g_jmpWMEntry;
|
static jmp_buf g_jmpWMEntry;
|
||||||
|
static XIOErrorHandler g_winMultiWindowWMOldIOErrorHandler;
|
||||||
|
static pthread_t g_winMultiWindowWMThread;
|
||||||
static jmp_buf g_jmpXMsgProcEntry;
|
static jmp_buf g_jmpXMsgProcEntry;
|
||||||
|
static XIOErrorHandler g_winMultiWindowXMsgProcOldIOErrorHandler;
|
||||||
|
static pthread_t g_winMultiWindowXMsgProcThread;
|
||||||
static Bool g_shutdown = FALSE;
|
static Bool g_shutdown = FALSE;
|
||||||
static Bool redirectError = FALSE;
|
static Bool redirectError = FALSE;
|
||||||
static Bool g_fAnotherWMRunning = FALSE;
|
static Bool g_fAnotherWMRunning = FALSE;
|
||||||
|
@ -901,6 +905,11 @@ winMultiWindowXMsgProc (void *pArg)
|
||||||
|
|
||||||
ErrorF ("winMultiWindowXMsgProc - pthread_mutex_unlock () returned.\n");
|
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 */
|
/* Set jump point for IO Error exits */
|
||||||
iReturn = setjmp (g_jmpXMsgProcEntry);
|
iReturn = setjmp (g_jmpXMsgProcEntry);
|
||||||
|
|
||||||
|
@ -919,10 +928,6 @@ winMultiWindowXMsgProc (void *pArg)
|
||||||
pthread_exit (NULL);
|
pthread_exit (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Install our error handler */
|
|
||||||
XSetErrorHandler (winMultiWindowXMsgProcErrorHandler);
|
|
||||||
XSetIOErrorHandler (winMultiWindowXMsgProcIOErrorHandler);
|
|
||||||
|
|
||||||
/* Setup the display connection string x */
|
/* Setup the display connection string x */
|
||||||
snprintf (pszDisplay,
|
snprintf (pszDisplay,
|
||||||
512, "127.0.0.1:%s.%d", display, (int)pProcArg->dwScreen);
|
512, "127.0.0.1:%s.%d", display, (int)pProcArg->dwScreen);
|
||||||
|
@ -1310,6 +1315,11 @@ winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
|
||||||
|
|
||||||
ErrorF ("winInitMultiWindowWM - pthread_mutex_unlock () returned.\n");
|
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 */
|
/* Set jump point for IO Error exits */
|
||||||
iReturn = setjmp (g_jmpWMEntry);
|
iReturn = setjmp (g_jmpWMEntry);
|
||||||
|
|
||||||
|
@ -1328,10 +1338,6 @@ winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
|
||||||
pthread_exit (NULL);
|
pthread_exit (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Install our error handler */
|
|
||||||
XSetErrorHandler (winMultiWindowWMErrorHandler);
|
|
||||||
XSetIOErrorHandler (winMultiWindowWMIOErrorHandler);
|
|
||||||
|
|
||||||
/* Setup the display connection string x */
|
/* Setup the display connection string x */
|
||||||
snprintf (pszDisplay,
|
snprintf (pszDisplay,
|
||||||
512,
|
512,
|
||||||
|
@ -1458,11 +1464,17 @@ winMultiWindowWMIOErrorHandler (Display *pDisplay)
|
||||||
{
|
{
|
||||||
ErrorF ("winMultiWindowWMIOErrorHandler!\n\n");
|
ErrorF ("winMultiWindowWMIOErrorHandler!\n\n");
|
||||||
|
|
||||||
|
if (pthread_equal(pthread_self(),g_winMultiWindowWMThread))
|
||||||
|
{
|
||||||
if (g_shutdown)
|
if (g_shutdown)
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
|
|
||||||
/* Restart at the main entry point */
|
/* Restart at the main entry point */
|
||||||
longjmp (g_jmpWMEntry, WIN_JMP_ERROR_IO);
|
longjmp (g_jmpWMEntry, WIN_JMP_ERROR_IO);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_winMultiWindowWMOldIOErrorHandler)
|
||||||
|
g_winMultiWindowWMOldIOErrorHandler(pDisplay);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1498,8 +1510,14 @@ winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay)
|
||||||
{
|
{
|
||||||
ErrorF ("winMultiWindowXMsgProcIOErrorHandler!\n\n");
|
ErrorF ("winMultiWindowXMsgProcIOErrorHandler!\n\n");
|
||||||
|
|
||||||
|
if (pthread_equal(pthread_self(),g_winMultiWindowXMsgProcThread))
|
||||||
|
{
|
||||||
/* Restart at the main entry point */
|
/* Restart at the main entry point */
|
||||||
longjmp (g_jmpXMsgProcEntry, WIN_JMP_ERROR_IO);
|
longjmp (g_jmpXMsgProcEntry, WIN_JMP_ERROR_IO);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_winMultiWindowXMsgProcOldIOErrorHandler)
|
||||||
|
g_winMultiWindowXMsgProcOldIOErrorHandler(pDisplay);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue