changeset 83350:e7d5238afe52

Work around crashes in X session management after normal shutdown of X server. * src/xsmfns.c (x_session_close): New function. * src/xterm.h: Declare it. * src/xterm.c (XTread_socket): Don't call x_session_check_input for secondary displays. (x_term_init): Do not initialize X session management when the initial display was a tty frame. (x_delete_display): Close X session management when we close its display. git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-390
author Karoly Lorentey <lorentey@elte.hu>
date Thu, 04 Aug 2005 00:46:55 +0000
parents 3d2bd2e4c7b7
children e012279bbb3b
files README.multi-tty src/xsmfns.c src/xterm.c src/xterm.h
diffstat 4 files changed, 59 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/README.multi-tty	Fri Jul 22 03:24:10 2005 +0000
+++ b/README.multi-tty	Thu Aug 04 00:46:55 2005 +0000
@@ -501,6 +501,33 @@
    by changing the modelines or some other frame-local display element
    on the locked out displays.
 
+** The session management module is prone to crashes when the X
+   connection is closed and then later I try to connect to a new X
+   session:
+
+	#0  0xb7ebc806 in SmcGetIceConnection () from /usr/X11R6/lib/libSM.so.6
+	#1  0x080e6641 in x_session_check_input (bufp=0xbf86c9c0) at xsmfns.c:144
+	#2  0x080d3bbc in XTread_socket (device=0xa722ff8, expected=1, hold_quit=0xbf86ca90) at xterm.c:7037
+	#3  0x080fa404 in read_avail_input (expected=1) at keyboard.c:6696
+	#4  0x080fa4ca in handle_async_input () at keyboard.c:6900
+	#5  0x080d51fa in x_term_init (display_name=162628899, xrm_option=0x0, resource_name=0x857068c "emacs") at xterm.c:10622
+	#6  0x080d920e in x_display_info_for_name (name=162628899) at xfns.c:3975
+	#7  0x080d92f9 in check_x_display_info (object=1) at xfns.c:274
+	#8  0x080d97b8 in Fx_create_frame (parms=151221485) at xfns.c:3016
+	#9  0x0815bf72 in Ffuncall (nargs=2, args=0xbf86ceec) at eval.c:2851
+
+   I installed a workaround to prevent this.  The X session manager is
+   only contacted when the very first display in the Emacs session is
+   an X display.  Also, x_delete_display() on this display aborts
+   session management, and XTread_socket only calls
+   x_session_check_input when it is called for the display that the
+   session was opened on.  While this does not really fix the bug, it
+   makes it much less frequent, because session manager support will
+   not normally be enabled when Emacs can survive the shutdown of the
+   X server.
+
+   See if xsmfns.c should be updated.
+
 ** normal-erase-is-backspace-mode in simple.el needs to be updated for
    multi-tty (rep. by Dan Waber).
 
--- a/src/xsmfns.c	Fri Jul 22 03:24:10 2005 +0000
+++ b/src/xsmfns.c	Thu Aug 04 00:46:55 2005 +0000
@@ -516,6 +516,14 @@
     }
 }
 
+/* Ensure that the session manager is not contacted again. */
+
+void
+x_session_close ()
+{
+  ice_fd = -1;
+}
+
 
 DEFUN ("handle-save-session", Fhandle_save_session,
        Shandle_save_session, 1, 1, "e",
--- a/src/xterm.c	Fri Jul 22 03:24:10 2005 +0000
+++ b/src/xterm.c	Thu Aug 04 00:46:55 2005 +0000
@@ -7029,18 +7029,20 @@
 	}
 
 #ifdef HAVE_X_SM
-      {
-	struct input_event inev;
-	BLOCK_INPUT;
-	/* We don't need to EVENT_INIT (inev) here, as
-	   x_session_check_input copies an entire input_event.  */
-	if (x_session_check_input (&inev))
-	  {
-	    kbd_buffer_store_event_hold (&inev, hold_quit);
-	    count++;
-	  }
-	UNBLOCK_INPUT;
-      }
+      /* Only check session manager input for the primary display. */
+      if (device->id == 1 && x_session_have_connection ())
+        {
+          struct input_event inev;
+          BLOCK_INPUT;
+          /* We don't need to EVENT_INIT (inev) here, as
+             x_session_check_input copies an entire input_event.  */
+          if (x_session_check_input (&inev))
+            {
+              kbd_buffer_store_event_hold (&inev, hold_quit);
+              count++;
+            }
+          UNBLOCK_INPUT;
+        }
 #endif
 
 #ifndef USE_GTK
@@ -10614,8 +10616,10 @@
   }
 
 #ifdef HAVE_X_SM
-  /* Only do this for the first display.  */
-  if (x_initialized == 1)
+  /* Only do this for the very first display in the Emacs session.
+     Ignore X session management when Emacs was first started on a
+     tty.  */
+  if (device->id == 1)
     x_session_initialize (dpyinfo);
 #endif
 
@@ -10638,10 +10642,14 @@
   for (d = device_list; d; d = d->next_device)
     if (d->type == output_x_window && d->display_info.x == dpyinfo)
       {
+        /* Close X session management when we close its display. */
+        if (d->id == 1 && x_session_have_connection ())
+          x_session_close();
+
         delete_device (d);
         break;
       }
-    
+
   delete_keyboard_wait_descriptor (dpyinfo->connection);
 
   /* Discard this display from x_display_name_list and x_display_list.
--- a/src/xterm.h	Fri Jul 22 03:24:10 2005 +0000
+++ b/src/xterm.h	Thu Aug 04 00:46:55 2005 +0000
@@ -1089,6 +1089,7 @@
 extern void x_session_initialize P_ ((struct x_display_info *dpyinfo));
 extern int x_session_check_input P_ ((struct input_event *bufp));
 extern int x_session_have_connection P_ ((void));
+extern void x_session_close P_ ((void));
 #endif
 
 #define FONT_TYPE_FOR_UNIBYTE(font, ch) 0