From 0d3cb44e53d7be86f6ef16c25c4f246b8655962a Mon Sep 17 00:00:00 2001
From: marha <marha@users.sourceforge.net>
Date: Fri, 3 Sep 2010 08:31:21 +0000
Subject: Make sure the process also closes when the multiwindow client thread
 closes

---
 xorg-server/hw/xwin/winmultiwindowwm.c | 76 +++++++++++++++++++++++++---------
 1 file changed, 57 insertions(+), 19 deletions(-)

(limited to 'xorg-server/hw/xwin')

diff --git a/xorg-server/hw/xwin/winmultiwindowwm.c b/xorg-server/hw/xwin/winmultiwindowwm.c
index 913f01bac..d6a2b2c88 100644
--- a/xorg-server/hw/xwin/winmultiwindowwm.c
+++ b/xorg-server/hw/xwin/winmultiwindowwm.c
@@ -180,6 +180,9 @@ winMultiWindowXMsgProcErrorHandler (Display *pDisplay, XErrorEvent *pErr);
 static int
 winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay);
 
+static void
+winMultiWindowThreadExit(void *arg);
+
 static int
 winRedirectErrorHandler (Display *pDisplay, XErrorEvent *pErr);
 
@@ -200,7 +203,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;
@@ -571,6 +578,8 @@ winMultiWindowWMProc (void *pArg)
 {
   WMProcArgPtr		pProcArg = (WMProcArgPtr)pArg;
   WMInfoPtr		pWMInfo = pProcArg->pWMInfo;
+
+  pthread_cleanup_push(&winMultiWindowThreadExit, NULL);
   
   /* Initialize the Window Manager */
   winInitMultiWindowWM (pWMInfo, pProcArg);
@@ -755,6 +764,9 @@ winMultiWindowWMProc (void *pArg)
   free (pProcArg);
   
   winDebug("-winMultiWindowWMProc ()\n");
+
+  pthread_cleanup_pop(0);
+
   return NULL;
 }
 
@@ -777,6 +789,8 @@ winMultiWindowXMsgProc (void *pArg)
   int			iReturn;
   XIconSize		*xis;
 
+  pthread_cleanup_push(&winMultiWindowThreadExit, NULL);
+
   winDebug ("winMultiWindowXMsgProc - Hello\n");
 
   /* Check that argument pointer is not invalid */
@@ -811,9 +825,14 @@ winMultiWindowXMsgProc (void *pArg)
 
   winDebug ("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)
@@ -829,10 +848,6 @@ winMultiWindowXMsgProc (void *pArg)
       pthread_exit (NULL);
     }
 
-  /* Install our error handler */
-  XSetErrorHandler (winMultiWindowXMsgProcErrorHandler);
-  XSetIOErrorHandler (winMultiWindowXMsgProcIOErrorHandler);
-
   /* Setup the display connection string x */
   winGetDisplayName(pszDisplay, (int)pProcArg->dwScreen);
 
@@ -1085,7 +1100,7 @@ winMultiWindowXMsgProc (void *pArg)
     }
 
   XCloseDisplay (pProcArg->pDisplay);
-  pthread_exit (NULL);
+  pthread_cleanup_pop(0);
   return NULL;
 }
 
@@ -1208,9 +1223,14 @@ winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
 
   winDebug ("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)
@@ -1226,10 +1246,6 @@ winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
       pthread_exit (NULL);
     }
 
-  /* Install our error handler */
-  XSetErrorHandler (winMultiWindowWMErrorHandler);
-  XSetIOErrorHandler (winMultiWindowWMIOErrorHandler);
-
   /* Setup the display connection string x */
   winGetDisplayName(pszDisplay, (int)pProcArg->dwScreen);
 
@@ -1361,12 +1377,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;
 }
 
@@ -1410,12 +1432,28 @@ 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;
 }
 
+/*
+ * winMultiWindowThreadExit - Thread exit handler
+ */
+
+static void
+winMultiWindowThreadExit(void *arg)
+{
+  /* multiwindow client thread has exited, stop server as well */
+  TerminateProcess(GetCurrentProcess(),1);
+}
 
 /*
  * Catch RedirectError to detect other window manager running
-- 
cgit v1.2.3