help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Ctrl-C and try-catch


From: John W. Eaton
Subject: Ctrl-C and try-catch
Date: Fri, 20 Feb 2004 14:57:00 -0600

On 12-Dec-2003, Paul Kienzle <address@hidden> wrote:

| The following code prints 'no' if I hit control C or 'yes' if it
| runs to completion:
| 
|   octave> try; for i=1:100000, x=i+1; end; 'yes', catch, 'no', end;
|   ans = no
| 
| Is there any way to stop a try-catch from catching Ctrl-C?  Or detect
| if Ctrl-C is pressed so that I can throw it again in the interrupt?
| Or tell Ctrl-C to return to the top level, skipping all try-catch
| blocks?

How about the following change?  With it, I think the behavior for
interrupts in things like

  unwind_protect
    "foo"
    for i = 1:100000
      y = sin(i);
    endfor
    "bar"
  unwind_protect_cleanup
    try
      for j = 1:100000
        z = cos(j);
      endfor
    catch
      "baz"
    end_try_catch
  end_unwind_protect

is correct.

Thanks,

jwe


libcruft/ChangeLog:

2004-02-20  John W. Eaton  <address@hidden>

        * misc/quit.h (OCTAVE_QUIT): Set octave_interrupt_state to -1
        while we are handling interrupts.


src/ChangeLog:

2004-02-20  John W. Eaton  <address@hidden>

        * sighandlers.cc (sigfpe_handler, sigpipe_handler):
        Don't increment octave_interrupt_state if it is less than 0.
        (sigint_handler): If octave_interrupt_state is less than zero,
        reset it.

        * pt-except.cc (do_catch_code): Call OCTAVE_QUIT here so the catch
        code won't run if an interrupt is pending.  Don't run catch code
        if intterrupt_state is less than zero.


Index: libcruft/misc/quit.h
===================================================================
RCS file: /usr/local/cvsroot/octave/libcruft/misc/quit.h,v
retrieving revision 1.12
diff -u -r1.12 quit.h
--- libcruft/misc/quit.h        31 Oct 2003 03:07:05 -0000      1.12
+++ libcruft/misc/quit.h        20 Feb 2004 20:51:53 -0000
@@ -68,6 +68,10 @@
 
 extern sig_atomic_t octave_interrupt_immediately;
 
+// > 0: interrupt pending
+//   0: no interrupt pending
+// < 0: handling interrupt
+//
 extern sig_atomic_t octave_interrupt_state;
 
 extern sig_atomic_t octave_allocation_error;
@@ -79,9 +83,9 @@
 #define OCTAVE_QUIT \
   do \
     { \
-      if (octave_interrupt_state) \
+      if (octave_interrupt_state > 0) \
         { \
-          octave_interrupt_state = 0; \
+          octave_interrupt_state = -1; \
           octave_throw_interrupt_exception (); \
         } \
     } \
Index: src/pt-except.cc
===================================================================
RCS file: /usr/local/cvsroot/octave/src/pt-except.cc,v
retrieving revision 1.18
diff -u -r1.18 pt-except.cc
--- src/pt-except.cc    20 Jan 2004 23:04:46 -0000      1.18
+++ src/pt-except.cc    20 Feb 2004 20:52:03 -0000
@@ -57,7 +57,27 @@
 static void
 do_catch_code (void *ptr)
 {
-  if (octave_interrupt_immediately)
+  // Is it safe to call OCTAVE_QUIT here?  We are already running
+  // something on the unwind_protect stack, but the element for this
+  // action would have already been popped from the top of the stack,
+  // so we should not be attempting to run it again.
+
+  OCTAVE_QUIT;
+
+  // If we are interrupting immediately, or if an interrupt is in
+  // progress (octave_interrupt_state < 0), then we don't want to run
+  // the catch code (it should only run on errors, not interrupts).
+
+  // If octave_interrupt_state is positive, an interrupt is pending.
+  // The only way that could happen would be for the interrupt to
+  // come in after the OCTAVE_QUIT above and before the if statement
+  // below -- it's possible, but unlikely.  In any case, we should
+  // probably let the catch code throw the exception because we don't
+  // want to skip that and potentially run some other code.  For
+  // example, an error may have originally brought us here for some
+  // cleanup operation and we shouldn't skip that.
+
+  if (octave_interrupt_immediately || octave_interrupt_state < 0)
     return;
 
   tree_statement_list *list = static_cast<tree_statement_list *> (ptr);
Index: src/sighandlers.cc
===================================================================
RCS file: /usr/local/cvsroot/octave/src/sighandlers.cc,v
retrieving revision 1.80
diff -u -r1.80 sighandlers.cc
--- src/sighandlers.cc  20 Feb 2004 18:02:59 -0000      1.80
+++ src/sighandlers.cc  20 Feb 2004 20:52:03 -0000
@@ -237,7 +237,7 @@
   // XXX FIXME XXX -- will setting octave_interrupt_state really help
   // here?
 
-  if (can_interrupt)
+  if (can_interrupt && octave_interrupt_state >= 0)
     octave_interrupt_state++;
 
   SIGHANDLER_RETURN (0);
@@ -334,6 +334,13 @@
        octave_jump_to_enclosing_context ();
       else
        {
+         // If we are already cleaning up from a previous interrupt,
+         // take note of the fact that another interrupt signal has
+         // arrived.
+
+         if (octave_interrupt_state < 0)
+           octave_interrupt_state = 0;
+
          octave_interrupt_state++;
 
          if (interactive && octave_interrupt_state == 2)
@@ -363,7 +370,7 @@
   // XXX FIXME XXX -- will setting octave_interrupt_state really help
   // here?
 
-  if (pipe_handler_error_count  > 100)
+  if (pipe_handler_error_count  > 100 && octave_interrupt_state >= 0)
     octave_interrupt_state++;
 
   SIGHANDLER_RETURN (0);



-------------------------------------------------------------
Octave is freely available under the terms of the GNU GPL.

Octave's home on the web:  http://www.octave.org
How to fund new projects:  http://www.octave.org/funding.html
Subscription information:  http://www.octave.org/archive.html
-------------------------------------------------------------



reply via email to

[Prev in Thread] Current Thread [Next in Thread]