# HG changeset patch # User Karoly Lorentey # Date 1123116415 0 # Node ID e7d5238afe52aa8cc3dd1b1d871746a39f35b829 # Parent 3d2bd2e4c7b78d303929a30f653d87ac67b615aa 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 diff -r 3d2bd2e4c7b7 -r e7d5238afe52 README.multi-tty --- 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). diff -r 3d2bd2e4c7b7 -r e7d5238afe52 src/xsmfns.c --- 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", diff -r 3d2bd2e4c7b7 -r e7d5238afe52 src/xterm.c --- 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. diff -r 3d2bd2e4c7b7 -r e7d5238afe52 src/xterm.h --- 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