Mercurial > octave
diff libinterp/interpfcn/toplev.cc @ 16485:8b783661e03f
improve exit sequence for GUI
* octave-link.h, octave-link.cc (octave_link::accepting_events):
Delete variable and all uses.
(octave_link::link_enabled): New data member.
(octave_link::octave_link): Don't set octave_exit. Initialize
link_enabled.
(octave_link::do_exit): Delete definition. Now pure virtual.
Return bool.
(octave_link::exit): Call instance->do_exit.
(octave_link::enabled): New function.
(ocave_link::process_events): New arg, disable. Optionally disable
event processing.
Use octave_link::enabled instead of instance_ok everywhere except for
octave_link::exit.
(octave_link::cleanup_instance): Delete.
* octave-qt-link.h, octave-qt-link.cc
(octave_qt_link::octave_qt_link): Accept thread as argument.
Don't connect main_thread::finished signal.
(octave_qt_link::~octave_qt_link): Don't delete main_thread.
(octave_qt_link::do_exit): Emit exit_signal and return true.
(octave_qt_link::exit_signal: New signal.
(octave_qt_link::void octave_thread_finished_signal): Delete.
* main-window.h, main-window.cc (main_window::_octave_main_thread):
New member variable.
(main_window::main_window): Initialize _octave_main_thread and
_octave_qt_link to 0.
(main_window::~main_window): Don't call octave_link::connect_link.
Delete _octave_main_thread.
(main_window::exit): Accept exit status as argument and call
QApplication::exit instead of quit.
(main_window::construct): Don't connect qApp::aboutToQuit to
main_window::prepare_to_exit.
(main_window::construct_octave_qt_link): Create _octave_main_thread
and pass to _octave_qt_link. Don't connect
_octave_qt_link::octave_thread_finished to main_window::exit.
Connect _octave_qt_link::exit_signal to main_window::exit.
* toplev.h, toplev.cc (main_loop): If quitting_gracefully, just return
exit status instead of calling clean_up_and_exit.
(do_octave_atexit): Now static. Call octave_link::process_events with
disable arg set to true.
(octave_atexit_functions): Now static.
(clean_up_and_exit): New argument, safe_to_return.
Call octave_link::exit and possibly return or wait for
octave_link::exit to terminate the process.
* octave.cc (octave_execute_interpreter): Don't alter return value
from main_loop. Pass safe_to_return = true to clean_up_and_exit.
Return retval instead of 0.
(octave_initialize_interpreter): Don't call atexit.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 09 Apr 2013 23:08:24 -0400 |
parents | fb27f1e08297 |
children |
line wrap: on
line diff
--- a/libinterp/interpfcn/toplev.cc Tue Apr 09 23:08:21 2013 -0400 +++ b/libinterp/interpfcn/toplev.cc Tue Apr 09 23:08:24 2013 -0400 @@ -57,6 +57,7 @@ #include "graphics.h" #include "input.h" #include "lex.h" +#include "octave-link.h" #include "oct-conf.h" #include "oct-conf-features.h" #include "oct-hist.h" @@ -614,10 +615,7 @@ recover_from_exception (); octave_stdout << "\n"; if (quitting_gracefully) - { - clean_up_and_exit (exit_status); - break; // If user has overriden the exit func. - } + return exit_status; } catch (octave_execution_exception) { @@ -641,13 +639,120 @@ // Fix up things before exiting. +static std::list<std::string> octave_atexit_functions; + +static void +do_octave_atexit (void) +{ + static bool deja_vu = false; + + OCTAVE_SAFE_CALL (remove_input_event_hook_functions, ()); + + while (! octave_atexit_functions.empty ()) + { + std::string fcn = octave_atexit_functions.front (); + + octave_atexit_functions.pop_front (); + + OCTAVE_SAFE_CALL (reset_error_handler, ()); + + OCTAVE_SAFE_CALL (feval, (fcn, octave_value_list (), 0)); + + OCTAVE_SAFE_CALL (flush_octave_stdout, ()); + } + + if (! deja_vu) + { + deja_vu = true; + + // Process pending events and disasble octave_link event + // processing with this call. + + octave_link::process_events (true); + + // Do this explicitly so that destructors for mex file objects + // are called, so that functions registered with mexAtExit are + // called. + OCTAVE_SAFE_CALL (clear_mex_functions, ()); + + OCTAVE_SAFE_CALL (command_editor::restore_terminal_state, ()); + + // FIXME -- is this needed? Can it cause any trouble? + OCTAVE_SAFE_CALL (raw_mode, (0)); + + OCTAVE_SAFE_CALL (octave_history_write_timestamp, ()); + + if (! command_history::ignoring_entries ()) + OCTAVE_SAFE_CALL (command_history::clean_up_and_save, ()); + + OCTAVE_SAFE_CALL (gh_manager::close_all_figures, ()); + + OCTAVE_SAFE_CALL (gtk_manager::unload_all_toolkits, ()); + + OCTAVE_SAFE_CALL (close_files, ()); + + OCTAVE_SAFE_CALL (cleanup_tmp_files, ()); + + OCTAVE_SAFE_CALL (symbol_table::cleanup, ()); + + OCTAVE_SAFE_CALL (sysdep_cleanup, ()); + + OCTAVE_SAFE_CALL (flush_octave_stdout, ()); + + if (! quitting_gracefully && (interactive || forced_interactive)) + { + octave_stdout << "\n"; + + // Yes, we want this to be separate from the call to + // flush_octave_stdout above. + + OCTAVE_SAFE_CALL (flush_octave_stdout, ()); + } + + // Don't call singleton_cleanup_list::cleanup until we have the + // problems with registering/unregistering types worked out. For + // example, uncomment the following line, then use the make_int + // function from the examples directory to create an integer + // object and then exit Octave. Octave should crash with a + // segfault when cleaning up the typinfo singleton. We need some + // way to force new octave_value_X types that are created in + // .oct files to be unregistered when the .oct file shared library + // is unloaded. + // + // OCTAVE_SAFE_CALL (singleton_cleanup_list::cleanup, ()); + + OCTAVE_SAFE_CALL (octave_chunk_buffer::clear, ()); + } +} + void -clean_up_and_exit (int retval) +clean_up_and_exit (int retval, bool safe_to_return) { do_octave_atexit (); - if (octave_exit) - (*octave_exit) (retval == EOF ? 0 : retval); + if (octave_link::exit (retval)) + { + if (safe_to_return) + return; + else + { + // What should we do here? We might be called from some + // location other than the end of octave_execute_interpreter, + // so it might not be safe to return. + + // We have nothing else to do at this point, and the + // octave_link::exit function is supposed to take care of + // exiting for us. Assume that job won't take more than a + // day... + + gnulib::sleep (86400); + } + } + else + { + if (octave_exit) + (*octave_exit) (retval == EOF ? 0 : retval); + } } DEFUN (quit, args, , @@ -992,89 +1097,6 @@ %!error system (1, 2, 3) */ -// FIXME -- this should really be static, but that causes -// problems on some systems. -std::list<std::string> octave_atexit_functions; - -void -do_octave_atexit (void) -{ - static bool deja_vu = false; - - OCTAVE_SAFE_CALL (remove_input_event_hook_functions, ()); - - while (! octave_atexit_functions.empty ()) - { - std::string fcn = octave_atexit_functions.front (); - - octave_atexit_functions.pop_front (); - - OCTAVE_SAFE_CALL (reset_error_handler, ()); - - OCTAVE_SAFE_CALL (feval, (fcn, octave_value_list (), 0)); - - OCTAVE_SAFE_CALL (flush_octave_stdout, ()); - } - - if (! deja_vu) - { - deja_vu = true; - - // Do this explicitly so that destructors for mex file objects - // are called, so that functions registered with mexAtExit are - // called. - OCTAVE_SAFE_CALL (clear_mex_functions, ()); - - OCTAVE_SAFE_CALL (command_editor::restore_terminal_state, ()); - - // FIXME -- is this needed? Can it cause any trouble? - OCTAVE_SAFE_CALL (raw_mode, (0)); - - OCTAVE_SAFE_CALL (octave_history_write_timestamp, ()); - - if (! command_history::ignoring_entries ()) - OCTAVE_SAFE_CALL (command_history::clean_up_and_save, ()); - - OCTAVE_SAFE_CALL (gh_manager::close_all_figures, ()); - - OCTAVE_SAFE_CALL (gtk_manager::unload_all_toolkits, ()); - - OCTAVE_SAFE_CALL (close_files, ()); - - OCTAVE_SAFE_CALL (cleanup_tmp_files, ()); - - OCTAVE_SAFE_CALL (symbol_table::cleanup, ()); - - OCTAVE_SAFE_CALL (sysdep_cleanup, ()); - - OCTAVE_SAFE_CALL (flush_octave_stdout, ()); - - if (! quitting_gracefully && (interactive || forced_interactive)) - { - octave_stdout << "\n"; - - // Yes, we want this to be separate from the call to - // flush_octave_stdout above. - - OCTAVE_SAFE_CALL (flush_octave_stdout, ()); - } - - // Don't call singleton_cleanup_list::cleanup until we have the - // problems with registering/unregistering types worked out. For - // example, uncomment the following line, then use the make_int - // function from the examples directory to create an integer - // object and then exit Octave. Octave should crash with a - // segfault when cleaning up the typinfo singleton. We need some - // way to force new octave_value_X types that are created in - // .oct files to be unregistered when the .oct file shared library - // is unloaded. - // - // OCTAVE_SAFE_CALL (singleton_cleanup_list::cleanup, ()); - - OCTAVE_SAFE_CALL (octave_chunk_buffer::clear, ()); - } -} - void octave_add_atexit_function (const std::string& fname) {