]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix quitting bug when buffers are frozen
authorPaul Eggert <eggert@cs.ucla.edu>
Wed, 1 Feb 2017 23:18:44 +0000 (15:18 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Wed, 1 Feb 2017 23:23:19 +0000 (15:23 -0800)
Problem noted by Eli Zaretskii in:
http://lists.gnu.org/archive/html/emacs-devel/2017-01/msg00721.html
This patch also fixes some other issues in that report.
* src/lisp.h (incr_rarely_quit): Remove.
All callers changed to use rarely_quit directly.
* src/search.c (freeze_buffer_relocation)
(thaw_buffer_relocation): New functions.
(looking_at_1, fast_looking_at, search_buffer):
Use them to fix bug when quitting when buffers are frozen.
* src/sysdep.c (emacs_intr_read): Rename from emacs_nointr_read.
All uses changed.

src/callproc.c
src/fns.c
src/indent.c
src/lisp.h
src/search.c
src/syntax.c
src/sysdep.c

index 710174c46b033cf9e08065777c8f263bd52c09f2..84324c48dcfbb6f4cb46319c58a6cc4bf8a3d6c4 100644 (file)
@@ -198,7 +198,10 @@ call_process_cleanup (Lisp_Object buffer)
     {
       kill (-synch_process_pid, SIGINT);
       message1 ("Waiting for process to die...(type C-g again to kill it instantly)");
+
+      /* This will quit on C-g.  */
       wait_for_termination (synch_process_pid, 0, 1);
+
       synch_process_pid = 0;
       message1 ("Waiting for process to die...done");
     }
index 41c0c5856b410814b7d372a891843b1afa74a7af..ac7c1f265a468b25d431f4fadce5a102c28239ef 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -1389,7 +1389,7 @@ The value is actually the tail of LIST whose car is ELT.  */)
     {
       if (! NILP (Fequal (elt, XCAR (tail))))
        return tail;
-      incr_rarely_quit (&quit_count);
+      rarely_quit (++quit_count);
     }
   CHECK_LIST_END (tail, list);
   return Qnil;
@@ -1406,7 +1406,7 @@ The value is actually the tail of LIST whose car is ELT.  */)
     {
       if (EQ (XCAR (tail), elt))
        return tail;
-      incr_rarely_quit (&quit_count);
+      rarely_quit (++quit_count);
     }
   CHECK_LIST_END (tail, list);
   return Qnil;
@@ -1427,7 +1427,7 @@ The value is actually the tail of LIST whose car is ELT.  */)
       Lisp_Object tem = XCAR (tail);
       if (FLOATP (tem) && internal_equal (elt, tem, 0, 0, Qnil))
        return tail;
-      incr_rarely_quit (&quit_count);
+      rarely_quit (++quit_count);
     }
   CHECK_LIST_END (tail, list);
   return Qnil;
@@ -1445,7 +1445,7 @@ Elements of LIST that are not conses are ignored.  */)
     {
       if (CONSP (XCAR (tail)) && EQ (XCAR (XCAR (tail)), key))
        return XCAR (tail);
-      incr_rarely_quit (&quit_count);
+      rarely_quit (++quit_count);
     }
   CHECK_LIST_END (tail, list);
   return Qnil;
@@ -1476,7 +1476,7 @@ The value is actually the first element of LIST whose car equals KEY.  */)
       if (CONSP (car)
          && (EQ (XCAR (car), key) || !NILP (Fequal (XCAR (car), key))))
        return car;
-      incr_rarely_quit (&quit_count);
+      rarely_quit (++quit_count);
     }
   CHECK_LIST_END (tail, list);
   return Qnil;
@@ -1509,7 +1509,7 @@ The value is actually the first element of LIST whose cdr is KEY.  */)
     {
       if (CONSP (XCAR (tail)) && EQ (XCDR (XCAR (tail)), key))
        return XCAR (tail);
-      incr_rarely_quit (&quit_count);
+      rarely_quit (++quit_count);
     }
   CHECK_LIST_END (tail, list);
   return Qnil;
@@ -1528,7 +1528,7 @@ The value is actually the first element of LIST whose cdr equals KEY.  */)
       if (CONSP (car)
          && (EQ (XCDR (car), key) || !NILP (Fequal (XCDR (car), key))))
        return car;
-      incr_rarely_quit (&quit_count);
+      rarely_quit (++quit_count);
     }
   CHECK_LIST_END (tail, list);
   return Qnil;
@@ -1684,7 +1684,7 @@ changing the value of a sequence `foo'.  */)
            }
          else
            prev = tail;
-         incr_rarely_quit (&quit_count);
+         rarely_quit (++quit_count);
        }
       CHECK_LIST_END (tail, seq);
     }
@@ -1712,7 +1712,7 @@ This function may destructively modify SEQ to produce the value.  */)
          next = XCDR (tail);
          Fsetcdr (tail, prev);
          prev = tail;
-         incr_rarely_quit (&quit_count);
+         rarely_quit (++quit_count);
        }
       CHECK_LIST_END (tail, seq);
       seq = prev;
@@ -1759,7 +1759,7 @@ See also the function `nreverse', which is used more often.  */)
       for (new = Qnil; CONSP (seq); seq = XCDR (seq))
        {
          new = Fcons (XCAR (seq), new);
-         incr_rarely_quit (&quit_count);
+         rarely_quit (++quit_count);
        }
       CHECK_LIST_END (seq, seq);
     }
@@ -2062,7 +2062,7 @@ The PLIST is modified by side effects.  */)
        }
 
       prev = tail;
-      incr_rarely_quit (&quit_count);
+      rarely_quit (++quit_count);
     }
   Lisp_Object newcell
     = Fcons (prop, Fcons (val, NILP (prev) ? plist : XCDR (XCDR (prev))));
@@ -2100,7 +2100,7 @@ one of the properties on the list.  */)
     {
       if (! NILP (Fequal (prop, XCAR (tail))))
        return XCAR (XCDR (tail));
-      incr_rarely_quit (&quit_count);
+      rarely_quit (++quit_count);
     }
 
   CHECK_LIST_END (tail, prop);
@@ -2130,7 +2130,7 @@ The PLIST is modified by side effects.  */)
        }
 
       prev = tail;
-      incr_rarely_quit (&quit_count);
+      rarely_quit (++quit_count);
     }
   Lisp_Object newcell = list2 (prop, val);
   if (NILP (prev))
@@ -2210,7 +2210,7 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props,
 
   unsigned short int quit_count = 0;
  tail_recurse:
-  incr_rarely_quit (&quit_count);
+  rarely_quit (++quit_count);
   if (EQ (o1, o2))
     return 1;
   if (XTYPE (o1) != XTYPE (o2))
@@ -2419,7 +2419,7 @@ usage: (nconc &rest LISTS)  */)
        {
          tail = tem;
          tem = XCDR (tail);
-         incr_rarely_quit (&quit_count);
+         rarely_quit (++quit_count);
        }
       while (CONSP (tem));
 
@@ -2848,7 +2848,7 @@ The value is actually the tail of PLIST whose car is PROP.  */)
     {
       plist = XCDR (plist);
       plist = CDR (plist);
-      incr_rarely_quit (&quit_count);
+      rarely_quit (++quit_count);
     }
   return plist;
 }
index aff14abfd20965f2eb97f4496ffa75528ce52259..f630ebb847c619c133f0debea2b7d4f87f66073f 100644 (file)
@@ -1215,7 +1215,7 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos,
 
   while (true)
     {
-      incr_rarely_quit (&quit_count);
+      rarely_quit (++quit_count);
 
       while (pos == next_boundary)
        {
@@ -1282,7 +1282,7 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos,
              pos_byte = CHAR_TO_BYTE (pos);
            }
 
-         incr_rarely_quit (&quit_count);
+         rarely_quit (++quit_count);
        }
 
       /* Handle right margin.  */
@@ -1605,7 +1605,7 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos,
                              pos = find_before_next_newline (pos, to, 1, &pos_byte);
                              if (pos < to)
                                INC_BOTH (pos, pos_byte);
-                             incr_rarely_quit (&quit_count);
+                             rarely_quit (++quit_count);
                            }
                          while (pos < to
                                 && indented_beyond_p (pos, pos_byte,
index 2d67e7edddb29357c0aefee0e7abd50cfc48b79b..1ac38164c27e3d580052c73d9f00a6f2ee50c44d 100644 (file)
@@ -3145,14 +3145,6 @@ rarely_quit (unsigned short int count)
   if (! (count & (QUIT_COUNT_HEURISTIC - 1)))
     maybe_quit ();
 }
-
-/* Increment *QUIT_COUNT and rarely quit.  */
-
-INLINE void
-incr_rarely_quit (unsigned short int *quit_count)
-{
-  rarely_quit (++*quit_count);
-}
 \f
 extern Lisp_Object Vascii_downcase_table;
 extern Lisp_Object Vascii_canon_table;
index 084adda097bf75aee00014c438b1a0ea4662808c..33cb02aa7af5361acba86f4008a068ea69f1ee6d 100644 (file)
@@ -99,6 +99,25 @@ matcher_overflow (void)
   error ("Stack overflow in regexp matcher");
 }
 
+static void
+freeze_buffer_relocation (void)
+{
+#ifdef REL_ALLOC
+  /* Prevent ralloc.c from relocating the current buffer while
+     searching it.  */
+  r_alloc_inhibit_buffer_relocation (1);
+  record_unwind_protect_int (r_alloc_inhibit_buffer_relocation, 0);
+#endif
+}
+
+static void
+thaw_buffer_relocation (void)
+{
+#ifdef REL_ALLOC
+  unbind_to (SPECPDL_INDEX () - 1, Qnil);
+#endif
+}
+
 /* Compile a regexp and signal a Lisp error if anything goes wrong.
    PATTERN is the pattern to compile.
    CP is the place to put the result.
@@ -300,19 +319,13 @@ looking_at_1 (Lisp_Object string, bool posix)
 
   re_match_object = Qnil;
 
-#ifdef REL_ALLOC
-  /* Prevent ralloc.c from relocating the current buffer while
-     searching it.  */
-  r_alloc_inhibit_buffer_relocation (1);
-#endif
+  freeze_buffer_relocation ();
   i = re_match_2 (bufp, (char *) p1, s1, (char *) p2, s2,
                  PT_BYTE - BEGV_BYTE,
                  (NILP (Vinhibit_changing_match_data)
                   ? &search_regs : NULL),
                  ZV_BYTE - BEGV_BYTE);
-#ifdef REL_ALLOC
-  r_alloc_inhibit_buffer_relocation (0);
-#endif
+  thaw_buffer_relocation ();
 
   if (i == -2)
     matcher_overflow ();
@@ -553,16 +566,10 @@ fast_looking_at (Lisp_Object regexp, ptrdiff_t pos, ptrdiff_t pos_byte,
     }
 
   buf = compile_pattern (regexp, 0, Qnil, 0, multibyte);
-#ifdef REL_ALLOC
-  /* Prevent ralloc.c from relocating the current buffer while
-     searching it.  */
-  r_alloc_inhibit_buffer_relocation (1);
-#endif
+  freeze_buffer_relocation ();
   len = re_match_2 (buf, (char *) p1, s1, (char *) p2, s2,
                    pos_byte, NULL, limit_byte);
-#ifdef REL_ALLOC
-  r_alloc_inhibit_buffer_relocation (0);
-#endif
+  thaw_buffer_relocation ();
 
   return len;
 }
@@ -1204,11 +1211,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
        }
       re_match_object = Qnil;
 
-#ifdef REL_ALLOC
-  /* Prevent ralloc.c from relocating the current buffer while
-     searching it.  */
-  r_alloc_inhibit_buffer_relocation (1);
-#endif
+      freeze_buffer_relocation ();
 
       while (n < 0)
        {
@@ -1250,9 +1253,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
            }
          else
            {
-#ifdef REL_ALLOC
-              r_alloc_inhibit_buffer_relocation (0);
-#endif
+             thaw_buffer_relocation ();
              return (n);
            }
          n++;
@@ -1295,17 +1296,13 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
            }
          else
            {
-#ifdef REL_ALLOC
-              r_alloc_inhibit_buffer_relocation (0);
-#endif
+             thaw_buffer_relocation ();
              return (0 - n);
            }
          n--;
          maybe_quit ();
        }
-#ifdef REL_ALLOC
-      r_alloc_inhibit_buffer_relocation (0);
-#endif
+      thaw_buffer_relocation ();
       return (pos);
     }
   else                         /* non-RE case */
index 06fe50b866bb3a1258f892702bf4cdf1a1e757e0..7aa43e6e5c77fbb954a0cb20392f9cec9670b876 100644 (file)
@@ -593,7 +593,6 @@ static ptrdiff_t
 find_defun_start (ptrdiff_t pos, ptrdiff_t pos_byte)
 {
   ptrdiff_t opoint = PT, opoint_byte = PT_BYTE;
-  unsigned short int quit_count = 0;
 
   /* Use previous finding, if it's valid and applies to this inquiry.  */
   if (current_buffer == find_start_buffer
@@ -636,7 +635,6 @@ find_defun_start (ptrdiff_t pos, ptrdiff_t pos_byte)
        }
       /* Move to beg of previous line.  */
       scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -2, 1);
-      incr_rarely_quit (&quit_count);
     }
 
   /* Record what we found, for the next try.  */
@@ -725,7 +723,7 @@ back_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop,
      that determines quote parity to the comment-end.  */
   while (from != stop)
     {
-      incr_rarely_quit (&quit_count);
+      rarely_quit (++quit_count);
 
       ptrdiff_t temp_byte;
       int prev_syntax;
@@ -954,7 +952,7 @@ back_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop,
                  defun_start_byte = CHAR_TO_BYTE (defun_start);
                }
            }
-         incr_rarely_quit (&quit_count);
+         rarely_quit (++quit_count);
        }
       while (defun_start < comment_end);
 
@@ -2386,7 +2384,7 @@ forw_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop,
          nesting++;
        }
 
-      incr_rarely_quit (&quit_count);
+      rarely_quit (++quit_count);
     }
   *charpos_ptr = from;
   *bytepos_ptr = from_byte;
@@ -2460,7 +2458,7 @@ between them, return t; otherwise return nil.  */)
              INC_BOTH (from, from_byte);
              UPDATE_SYNTAX_TABLE_FORWARD (from);
            }
-         incr_rarely_quit (&quit_count);
+         rarely_quit (++quit_count);
        }
       while (code == Swhitespace || (code == Sendcomment && c == '\n'));
 
@@ -2544,7 +2542,7 @@ between them, return t; otherwise return nil.  */)
                    }
                  else if (from == stop)
                    break;
-                 incr_rarely_quit (&quit_count);
+                 rarely_quit (++quit_count);
                }
              if (fence_found == 0)
                {
@@ -2592,7 +2590,7 @@ between them, return t; otherwise return nil.  */)
              return Qnil;
            }
 
-         incr_rarely_quit (&quit_count);
+         rarely_quit (++quit_count);
        }
 
       count1++;
@@ -2648,7 +2646,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
     {
       while (from < stop)
        {
-         incr_rarely_quit (&quit_count);
+         rarely_quit (++quit_count);
          bool comstart_first, prefix;
          int syntax, other_syntax;
          UPDATE_SYNTAX_TABLE_FORWARD (from);
@@ -2717,7 +2715,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
                      goto done;
                    }
                  INC_BOTH (from, from_byte);
-                 incr_rarely_quit (&quit_count);
+                 rarely_quit (++quit_count);
                }
              goto done;
 
@@ -2789,7 +2787,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
                  if (c_code == Scharquote || c_code == Sescape)
                    INC_BOTH (from, from_byte);
                  INC_BOTH (from, from_byte);
-                 incr_rarely_quit (&quit_count);
+                 rarely_quit (++quit_count);
                }
              INC_BOTH (from, from_byte);
              if (!depth && sexpflag) goto done;
@@ -2815,7 +2813,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
     {
       while (from > stop)
        {
-         incr_rarely_quit (&quit_count);
+         rarely_quit (++quit_count);
          DEC_BOTH (from, from_byte);
          UPDATE_SYNTAX_TABLE_BACKWARD (from);
          c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
@@ -2891,7 +2889,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
                      default: goto done2;
                      }
                  DEC_BOTH (from, from_byte);
-                 incr_rarely_quit (&quit_count);
+                 rarely_quit (++quit_count);
                }
              goto done2;
 
@@ -2954,7 +2952,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
                      if (syntax_multibyte (c, multibyte_symbol_p) == code)
                        break;
                    }
-                 incr_rarely_quit (&quit_count);
+                 rarely_quit (++quit_count);
                }
              if (code == Sstring_fence && !depth && sexpflag) goto done2;
              break;
@@ -2975,7 +2973,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
                              == Sstring))
                        break;
                    }
-                 incr_rarely_quit (&quit_count);
+                 rarely_quit (++quit_count);
                }
              if (!depth && sexpflag) goto done2;
              break;
@@ -3229,7 +3227,7 @@ do { prev_from = from;                            \
 
   while (from < end)
     {
-      incr_rarely_quit (&quit_count);
+      rarely_quit (++quit_count);
       INC_FROM;
 
       if ((from < end)
@@ -3286,7 +3284,7 @@ do { prev_from = from;                            \
                  goto symdone;
                }
              INC_FROM;
-             incr_rarely_quit (&quit_count);
+             rarely_quit (++quit_count);
            }
        symdone:
          curlevel->prev = curlevel->last;
@@ -3397,7 +3395,7 @@ do { prev_from = from;                            \
                    break;
                  }
                INC_FROM;
-               incr_rarely_quit (&quit_count);
+               rarely_quit (++quit_count);
              }
          }
        string_end:
index 4155c2057122fe6a942f9746ed3adc9eeddb4e57..91b2a5cb9435fcbc488b82441999c3fcfcff3c8c 100644 (file)
@@ -2508,12 +2508,12 @@ emacs_close (int fd)
 #endif
 
 /* Read from FD to a buffer BUF with size NBYTE.
-   If interrupted, either quit or retry the read.
-   Process any quits and pending signals immediately if INTERRUPTIBLE.
+   If interrupted, process any quits and pending signals immediately
+   if INTERRUPTIBLE, and then retry the read unless quitting.
    Return the number of bytes read, which might be less than NBYTE.
    On error, set errno to a value other than EINTR, and return -1.  */
 static ptrdiff_t
-emacs_nointr_read (int fd, void *buf, ptrdiff_t nbyte, bool interruptible)
+emacs_intr_read (int fd, void *buf, ptrdiff_t nbyte, bool interruptible)
 {
   ssize_t result;
 
@@ -2537,14 +2537,14 @@ emacs_nointr_read (int fd, void *buf, ptrdiff_t nbyte, bool interruptible)
 ptrdiff_t
 emacs_read (int fd, void *buf, ptrdiff_t nbyte)
 {
-  return emacs_nointr_read (fd, buf, nbyte, false);
+  return emacs_intr_read (fd, buf, nbyte, false);
 }
 
 /* Like emacs_read, but also process quits and pending signals.  */
 ptrdiff_t
 emacs_read_quit (int fd, void *buf, ptrdiff_t nbyte)
 {
-  return emacs_nointr_read (fd, buf, nbyte, true);
+  return emacs_intr_read (fd, buf, nbyte, true);
 }
 
 /* Write to FILEDES from a buffer BUF with size NBYTE, retrying if