diff libinterp/corefcn/interpreter.cc @ 23087:9f406f0b36da

rework clean_up_and_exit (bug #50068) * quit.h, quit.cc (clean_up_and_exit): Deprecate. Simply exit. * interperter.h, interpreter.cc (safe_source_file): Return status. Simply return 1 if index or other execution exception occurs. Don't catch exit exception here. (Fquit): Throw exit exception instead of calling clean_up_and_exit. (execute_pkg_add): Don't catch exit exception here. (interpreter::cleanup): Rename from clean_up_and_exit. Perform cleanup options but don't exit. Don't call octave_link::process_events. (interpreter::~interpreter): Call cleanup. (interpreter::execute): Catch exit_exception but not execution exceptions when evaluating eval options or executing command line file. Return status instead of calling clean_up_and_exit. (interpreter::execute_eval_option_code): Catch exit exception but not interrupt exception here. (interpreter::execute_command_line_file): Return status. (interpreter::main_loop): If exit exception is caught, don't call clean_up_and_exit, but do call octave_link::exit. Return exit status if octave_link doesn't terminate the process. * octave.h, octave.cc (octave_main): Deprecate. Make application objects static so they persist after function returns. Warn if not starting an embedded application. (application::init): Warn if application is already initialized. (application::~application): Delete interpreter before setting instance to 0. * octave-link.h (octave_link::exit): New arg, process_events. If process_events is true, disable link and process pending events.
author John W. Eaton <jwe@octave.org>
date Tue, 24 Jan 2017 18:00:05 -0500
parents ef4d915df748
children 0fed4c678795
line wrap: on
line diff
--- a/libinterp/corefcn/interpreter.cc	Mon Jan 23 14:30:35 2017 -0500
+++ b/libinterp/corefcn/interpreter.cc	Tue Jan 24 18:00:05 2017 -0500
@@ -249,7 +249,7 @@
   // unwind_protect stack, clear the OCTAVE_LOCAL_BUFFER allocations,
   // etc. before exiting.
 
-  clean_up_and_exit (exit_status);
+  throw octave::exit_exception (exit_status);
 
   return ovl ();
 }
@@ -352,7 +352,7 @@
 // commands from a file before we have entered the main loop in
 // toplev.cc.
 
-static void
+static int
 safe_source_file (const std::string& file_name,
                   const std::string& context = "",
                   bool verbose = false, bool require_file = true,
@@ -368,23 +368,25 @@
 
       std::cerr << "error: index exception in " << file_name << ": "
                 << e.message () << std::endl;
-    }
-  catch (const octave::exit_exception& ex)
-    {
-      recover_from_exception ();
 
-      clean_up_and_exit (ex.exit_status (), ex.safe_to_return ());
+      return 1;
     }
   catch (const octave::interrupt_exception&)
     {
       recover_from_exception ();
+
+      return 1;
     }
   catch (const octave::execution_exception&)
     {
       recover_from_exception ();
 
       std::cerr << "error: execution exception in " << file_name << std::endl;
+
+      return 1;
     }
+
+  return 0;
 }
 
 static void
@@ -403,12 +405,6 @@
       std::cerr << "error: index exception in " << file_name << ": "
                 << e.message () << std::endl;
     }
-  catch (const octave::exit_exception& ex)
-    {
-      recover_from_exception ();
-
-      clean_up_and_exit (ex.exit_status (), ex.safe_to_return ());
-    }
   catch (const octave::interrupt_exception&)
     {
       recover_from_exception ();
@@ -643,6 +639,8 @@
 
   interpreter::~interpreter (void)
   {
+    cleanup ();
+
     current_evaluator = 0;
 
     delete m_evaluator;
@@ -671,24 +669,24 @@
 
     if (! code_to_eval.empty ())
       {
-        int parse_status = 0;
+        int exit_status = 0;
 
         try
           {
-            parse_status = execute_eval_option_code (code_to_eval);
+            exit_status = execute_eval_option_code (code_to_eval);
           }
-        catch (const octave::execution_exception&)
+        catch (const octave::exit_exception& ex)
           {
             recover_from_exception ();
 
-            parse_status = 1;
+            return ex.exit_status ();
           }
 
         if (! options.persist ())
           {
             m_quitting_gracefully = true;
 
-            clean_up_and_exit (parse_status);
+            return exit_status;
           }
       }
 
@@ -708,13 +706,13 @@
 
             m_app_context->intern_argv (script_args);
 
-            execute_command_line_file (script_args[0]);
+            exit_status = execute_command_line_file (script_args[0]);
           }
-        catch (const octave::execution_exception&)
+        catch (const octave::exit_exception& ex)
           {
             recover_from_exception ();
 
-            exit_status = 1;
+            return ex.exit_status ();
           }
 
         // Restore full set of args.
@@ -724,7 +722,7 @@
           {
             m_quitting_gracefully = true;
 
-            clean_up_and_exit (exit_status);
+            return exit_status;
           }
       }
 
@@ -756,8 +754,6 @@
 
     m_quitting_gracefully = true;
 
-    clean_up_and_exit (retval, true);
-
     return retval;
   }
 
@@ -787,27 +783,23 @@
       {
         eval_string (code, false, parse_status, 0);
       }
-    catch (const octave::exit_exception& ex)
+    catch (const octave::interrupt_exception&)
       {
         recover_from_exception ();
 
-        clean_up_and_exit (ex.exit_status (), ex.safe_to_return ());
-      }
-    catch (const octave::interrupt_exception&)
-      {
-        recover_from_exception ();
+        return 1;
       }
     catch (const octave::execution_exception&)
       {
         recover_from_exception ();
 
-        parse_status = 1;
+        return 1;
       }
 
     return parse_status;
   }
 
-  void interpreter::execute_command_line_file (const std::string& fname)
+  int interpreter::execute_command_line_file (const std::string& fname)
   {
     octave::unwind_protect frame;
 
@@ -841,7 +833,7 @@
     bool verbose = false;
     bool require_file = true;
 
-    safe_source_file (fname, context, verbose, require_file, "octave");
+    return safe_source_file (fname, context, verbose, require_file, "octave");
   }
 
   int interpreter::main_loop (void)
@@ -916,7 +908,11 @@
           {
             recover_from_exception ();
 
-            clean_up_and_exit (ex.exit_status (), ex.safe_to_return ());
+            // If we are connected to a gui, allow it to manage the exit
+            // process.
+            octave_link::exit (ex.exit_status ());
+
+            return ex.exit_status ();
           }
         catch (const octave::interrupt_exception&)
           {
@@ -977,7 +973,7 @@
     return retval;
   }
 
-  void interpreter::clean_up_and_exit (int status, bool safe_to_return)
+  void interpreter::cleanup (void)
   {
     static bool deja_vu = false;
 
@@ -1000,11 +996,6 @@
       {
         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.
@@ -1060,31 +1051,5 @@
 
         OCTAVE_SAFE_CALL (octave::chunk_buffer::clear, ());
       }
-
-    if (octave_link::exit (status))
-      {
-        if (safe_to_return)
-          return;
-        else
-          {
-            // What should we do here?  We might be called from some
-            // location other than the end of octave::interpreter::execute
-            // 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.  Hang here forever so we never return.
-
-            while (true)
-              {
-                octave_sleep (1);
-              }
-          }
-      }
-    else
-      {
-        if (octave_exit)
-          (*octave_exit) (status);
-      }
   }
 }