emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] /srv/bzr/emacs/trunk r106602: Don't call Lisp in signal ha


From: Andreas Schwab
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r106602: Don't call Lisp in signal handler
Date: Sun, 04 Dec 2011 10:26:30 +0100
User-agent: Bazaar (2.3.1)

------------------------------------------------------------
revno: 106602
committer: Andreas Schwab <address@hidden>
branch nick: emacs
timestamp: Sun 2011-12-04 10:26:30 +0100
message:
  Don't call Lisp in signal handler
  
  * emacs.c (Qkill_emacs): Define.
  (syms_of_emacs): Initialize it.
  * keyboard.c (interrupt_signal): Don't call Fkill_emacs here, set
  Qquit_flag to `kill-emacs' instead.
  (quit_throw_to_read_char): Add parameter `from_signal'.  All
  callers changed.  Call Fkill_emacs if requested and safe.
  * lisp.h (QUIT): Call Fkill_emacs if requested.
modified:
  src/ChangeLog
  src/emacs.c
  src/keyboard.c
  src/lisp.h
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2011-12-03 19:15:20 +0000
+++ b/src/ChangeLog     2011-12-04 09:26:30 +0000
@@ -1,3 +1,13 @@
+2011-12-04  Andreas Schwab  <address@hidden>
+
+       * emacs.c (Qkill_emacs): Define.
+       (syms_of_emacs): Initialize it.
+       * keyboard.c (interrupt_signal): Don't call Fkill_emacs here, set
+       Qquit_flag to `kill-emacs' instead.
+       (quit_throw_to_read_char): Add parameter `from_signal'.  All
+       callers changed.  Call Fkill_emacs if requested and safe.
+       * lisp.h (QUIT): Call Fkill_emacs if requested.
+
 2011-12-03  Jan Djärv  <address@hidden>
 
        * widget.c (update_wm_hints): Return if wmshell is null.

=== modified file 'src/emacs.c'
--- a/src/emacs.c       2011-11-14 23:59:56 +0000
+++ b/src/emacs.c       2011-12-04 09:26:30 +0000
@@ -154,6 +154,8 @@
 
 Lisp_Object Qrisky_local_variable;
 
+Lisp_Object Qkill_emacs;
+
 /* If non-zero, Emacs should not attempt to use a window-specific code,
    but instead should use the virtual terminal under which it was started.  */
 int inhibit_window_system;
@@ -2394,6 +2396,7 @@
 {
   DEFSYM (Qfile_name_handler_alist, "file-name-handler-alist");
   DEFSYM (Qrisky_local_variable, "risky-local-variable");
+  DEFSYM (Qkill_emacs, "kill-emacs");
 
 #ifndef CANNOT_DUMP
   defsubr (&Sdump_emacs);

=== modified file 'src/keyboard.c'
--- a/src/keyboard.c    2011-12-04 08:02:42 +0000
+++ b/src/keyboard.c    2011-12-04 09:26:30 +0000
@@ -464,7 +464,7 @@
 static Lisp_Object (Fcommand_execute) (Lisp_Object, Lisp_Object, Lisp_Object,
                                       Lisp_Object);
 static void handle_interrupt (void);
-static void quit_throw_to_read_char (void) NO_RETURN;
+static void quit_throw_to_read_char (int) NO_RETURN;
 static void timer_start_idle (void);
 static void timer_stop_idle (void);
 static void timer_resume_idle (void);
@@ -653,7 +653,7 @@
   echo_kboard = current_kboard;
 
   if (waiting_for_input && !NILP (Vquit_flag))
-    quit_throw_to_read_char ();
+    quit_throw_to_read_char (0);
 }
 
 /* Turn off echoing, for the start of a new command.  */
@@ -3817,7 +3817,7 @@
       /* If the quit flag is set, then read_char will return
         quit_char, so that counts as "available input."  */
       if (!NILP (Vquit_flag))
-       quit_throw_to_read_char ();
+       quit_throw_to_read_char (0);
 
       /* One way or another, wait until input is available; then, if
         interrupt handlers have not read it, read it now.  */
@@ -10824,7 +10824,7 @@
   /* If handle_interrupt was called before and buffered a C-g,
      make it run again now, to avoid timing error.  */
   if (!NILP (Vquit_flag))
-    quit_throw_to_read_char ();
+    quit_throw_to_read_char (0);
 }
 
 void
@@ -10839,7 +10839,7 @@
 
    If we have a frame on the controlling tty, we assume that the
    SIGINT was generated by C-g, so we call handle_interrupt.
-   Otherwise, the handler kills Emacs.  */
+   Otherwise, tell QUIT to kill Emacs.  */
 
 static void
 interrupt_signal (int signalnum)       /* If we don't have an argument, some */
@@ -10856,12 +10856,10 @@
   if (!terminal)
     {
       /* If there are no frames there, let's pretend that we are a
-         well-behaving UN*X program and quit.  We cannot do that while
-         GC is in progress, though.  */
-      if (!gc_in_progress && !waiting_for_input)
-       Fkill_emacs (Qnil);
-      else
-       Vquit_flag = Qt;
+         well-behaving UN*X program and quit.  We must not call Lisp
+         in a signal handler, so tell QUIT to exit when it is
+         safe.  */
+      Vquit_flag = Qkill_emacs;
     }
   else
     {
@@ -11010,15 +11008,20 @@
          separate event loop thread like W32.  */
 #ifndef HAVE_NS
   if (waiting_for_input && !echoing)
-      quit_throw_to_read_char ();
+      quit_throw_to_read_char (1);
 #endif
 }
 
 /* Handle a C-g by making read_char return C-g.  */
 
 static void
-quit_throw_to_read_char (void)
+quit_throw_to_read_char (int from_signal)
 {
+  /* When not called from a signal handler it is safe to call
+     Lisp.  */
+  if (!from_signal && EQ (Vquit_flag, Qkill_emacs))
+    Fkill_emacs (Qnil);
+
   sigfree ();
   /* Prevent another signal from doing this before we finish.  */
   clear_waiting_for_input ();

=== modified file 'src/lisp.h'
--- a/src/lisp.h        2011-11-28 08:20:58 +0000
+++ b/src/lisp.h        2011-12-04 09:26:30 +0000
@@ -2128,7 +2128,10 @@
    Exception: if you set immediate_quit to nonzero,
    then the handler that responds to the C-g does the quit itself.
    This is a good thing to do around a loop that has no side effects
-   and (in particular) cannot call arbitrary Lisp code.  */
+   and (in particular) cannot call arbitrary Lisp code.
+
+   If quit-flag is set to `kill-emacs' the SIGINT handler has received
+   a request to exit Emacs when it is safe to do.  */
 
 #ifdef SYNC_INPUT
 extern void process_pending_signals (void);
@@ -2146,6 +2149,8 @@
       {                                                        \
         Lisp_Object flag = Vquit_flag;                 \
        Vquit_flag = Qnil;                              \
+       if (EQ (flag, Qkill_emacs))                     \
+         Fkill_emacs (Qnil);                           \
        if (EQ (Vthrow_on_input, flag))                 \
          Fthrow (Vthrow_on_input, Qt);                 \
        Fsignal (Qquit, Qnil);                          \
@@ -3291,6 +3296,7 @@
 #ifdef FLOAT_CATCH_SIGILL
 extern void fatal_error_signal (int);
 #endif
+extern Lisp_Object Qkill_emacs;
 EXFUN (Fkill_emacs, 1) NO_RETURN;
 #if HAVE_SETLOCALE
 void fixup_locale (void);


reply via email to

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