From f09e917e1856d0775bc5df1a69cce16b477decbd Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Wed, 16 Feb 2011 05:20:13 +0000 Subject: [PATCH] fix case where we could have x fatal stuff happen during shutdown or we try use x on shutdown when x io fatal conditions have happened. x_fatal flag around for that now too. tested. seems to now be happy and not cause aborts on shutdown when x has gone. SVN revision: 57075 --- src/bin/e.h | 2 ++ src/bin/e_alert.c | 11 +++++++---- src/bin/e_desklock.c | 3 ++- src/bin/e_main.c | 27 ++++++++++++++++++++++----- src/bin/e_menu.c | 13 ++++++++----- src/bin/e_module.c | 25 ++++++++++++++++--------- src/bin/e_shelf.c | 1 + 7 files changed, 58 insertions(+), 24 deletions(-) diff --git a/src/bin/e.h b/src/bin/e.h index 2b1c5f286..222d0a57b 100644 --- a/src/bin/e.h +++ b/src/bin/e.h @@ -231,6 +231,8 @@ extern EAPI int evil; extern EAPI int starting; extern EAPI int stopping; +extern EAPI Eina_Bool x_fatal; + extern EAPI unsigned long e_alert_composite_win; #endif diff --git a/src/bin/e_alert.c b/src/bin/e_alert.c index df5b765cc..a19abe07e 100644 --- a/src/bin/e_alert.c +++ b/src/bin/e_alert.c @@ -76,10 +76,13 @@ e_alert_init(const char *disp) EINTERN int e_alert_shutdown(void) { - XDestroyWindow(dd, win); - XFreeGC(dd, gc); - XFreeFont(dd, fs); - XCloseDisplay(dd); + if (!x_fatal) + { + XDestroyWindow(dd, win); + XFreeGC(dd, gc); + XFreeFont(dd, fs); + XCloseDisplay(dd); + } title = NULL; str1 = NULL; str2 = NULL; diff --git a/src/bin/e_desklock.c b/src/bin/e_desklock.c index fe9cfdccd..283e4eea9 100644 --- a/src/bin/e_desklock.c +++ b/src/bin/e_desklock.c @@ -109,7 +109,8 @@ e_desklock_init(void) EINTERN int e_desklock_shutdown(void) { - e_desklock_hide(); + if (!x_fatal) + e_desklock_hide(); if (e_config->desklock_background) e_filereg_deregister(e_config->desklock_background); diff --git a/src/bin/e_main.c b/src/bin/e_main.c index 59bf945cb..1e0344040 100644 --- a/src/bin/e_main.c +++ b/src/bin/e_main.c @@ -9,6 +9,7 @@ #endif #include +#include /* * i need to make more use of these when i'm baffled as to when something is @@ -59,6 +60,7 @@ my_free_hook(void *p, const void *caller) */ EAPI int e_precache_end = 0; +EAPI Eina_Bool x_fatal = EINA_FALSE; static int really_know = 0; @@ -94,6 +96,9 @@ static int _e_main_level = 0; static int _e_cacheburst = 0; static Eina_Bool locked = EINA_FALSE; +static jmp_buf x_fatal_buf; +static Eina_Bool inloop = EINA_FALSE; + static Eina_List *_e_main_idler_before_list = NULL; static Ecore_Idle_Enterer *_e_main_idle_enterer_before = NULL; @@ -1155,11 +1160,17 @@ main(int argc, char **argv) ecore_timer_add(5.0, stdbg, NULL); #endif - ecore_main_loop_begin(); - - e_canvas_idle_flush(); + inloop = EINA_TRUE; + if (!setjmp(x_fatal_buf)) + ecore_main_loop_begin(); + else + printf("FATAL: X died. Connection gone. abbreviated shutdown\n"); + inloop = EINA_FALSE; + stopping = 1; + if (!x_fatal) e_canvas_idle_flush(); + /* ask all modules to save their config and then shutdown */ /* NB: no need to do this as config shutdown will flush any saves */ /* and all changed config was already saved before */ @@ -1249,6 +1260,7 @@ _e_main_shutdown(int errorcode) static int _e_main_x_shutdown(void) { + if (x_fatal) return 1; /* ecore_x_ungrab(); */ ecore_x_focus_reset(); ecore_x_events_allow_all(); @@ -1561,8 +1573,13 @@ static void _e_main_cb_x_fatal(void *data __UNUSED__) { e_error_message_show("Lost X connection."); - e_sys_action_do(E_SYS_EXIT, NULL); -// ecore_main_loop_quit(); + ecore_main_loop_quit(); + // x is foobared - best to get the hell out of the mainloop + if (!x_fatal) + { + x_fatal = EINA_TRUE; + if (inloop) longjmp(x_fatal_buf, -99); + } } static Eina_Bool diff --git a/src/bin/e_menu.c b/src/bin/e_menu.c index 8624858d1..00083b8dd 100644 --- a/src/bin/e_menu.c +++ b/src/bin/e_menu.c @@ -176,12 +176,15 @@ e_menu_shutdown(void) E_FN_DEL(ecore_event_handler_del, _e_menu_mouse_wheel_handler); E_FN_DEL(ecore_event_handler_del, _e_menu_window_shape_handler); - EINA_LIST_FREE(_e_active_menus, m) + if (!x_fatal) { - m->active = 0; - _e_menu_unrealize(m); - m->in_active_list = 0; - e_object_unref(E_OBJECT(m)); + EINA_LIST_FREE(_e_active_menus, m) + { + m->active = 0; + _e_menu_unrealize(m); + m->in_active_list = 0; + e_object_unref(E_OBJECT(m)); + } } _e_active_menus = NULL; if (_e_menu_categories) diff --git a/src/bin/e_module.c b/src/bin/e_module.c index d46153ecb..6c39f9d8a 100644 --- a/src/bin/e_module.c +++ b/src/bin/e_module.c @@ -45,16 +45,23 @@ e_module_shutdown(void) #endif /* do not use EINA_LIST_FREE! e_object_del modifies list */ - while (_e_modules) + if (x_fatal) { - m = _e_modules->data; - if ((m) && (m->enabled) && !(m->error)) - { - m->func.save(m); - m->func.shutdown(m); - m->enabled = 0; - } - e_object_del(E_OBJECT(m)); + e_module_save_all(); + } + else + { + while (_e_modules) + { + m = _e_modules->data; + if ((m) && (m->enabled) && !(m->error)) + { + m->func.save(m); + m->func.shutdown(m); + m->enabled = 0; + } + e_object_del(E_OBJECT(m)); + } } return 1; diff --git a/src/bin/e_shelf.c b/src/bin/e_shelf.c index 659542ad6..08a195592 100644 --- a/src/bin/e_shelf.c +++ b/src/bin/e_shelf.c @@ -42,6 +42,7 @@ e_shelf_init(void) EINTERN int e_shelf_shutdown(void) { + if (x_fatal) return 1; while (shelves) { E_Shelf *es;