From fbf74c158ea81ff6349f68760f8861c1c497c989 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Tue, 31 Jan 2017 07:46:10 -0800 Subject: Revert two accidental commits This reverts commit f3c77d11af65f3b319b1784b4c3cf08c51aa7997. This reverts commit 3c941b900007c9e79c00af0f21d88154f6d8af1a. --- src/fns.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/fns.c') diff --git a/src/fns.c b/src/fns.c index 9eabc1414f4..136a2198c2c 100644 --- a/src/fns.c +++ b/src/fns.c @@ -5120,10 +5120,6 @@ On some platforms, file selection dialogs are also enabled if this is non-nil. */); use_dialog_box = 1; - DEFVAR_LISP("watch-object", Vwatch_object, - doc: /* Symbol to watch. */); - Vwatch_object = Qnil; - DEFVAR_BOOL ("use-file-dialog", use_file_dialog, doc: /* Non-nil means mouse commands use a file dialog to ask for files. This applies to commands from menus and tool bar buttons even when -- cgit v1.2.1 From 33be50037c2b4cdb002538534e9915c6bad253b7 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 1 Feb 2017 15:18:43 -0800 Subject: Remove immediate_quit. The old code that sets and clears immediate_quit was ineffective except when Emacs is running in terminal mode, and has problematic race conditions anyway, so remove it. This will introduce some hangs when Emacs runs in terminal mode, and these hangs should be fixed in followup patches. * src/keyboard.c (immediate_quit): Remove. All uses removed. --- src/fns.c | 42 ++++++++---------------------------------- 1 file changed, 8 insertions(+), 34 deletions(-) (limited to 'src/fns.c') diff --git a/src/fns.c b/src/fns.c index 136a2198c2c..444339c5259 100644 --- a/src/fns.c +++ b/src/fns.c @@ -1361,18 +1361,15 @@ DEFUN ("nthcdr", Fnthcdr, Snthcdr, 2, 2, 0, CHECK_NUMBER (n); EMACS_INT num = XINT (n); Lisp_Object tail = list; - immediate_quit = true; for (EMACS_INT i = 0; i < num; i++) { if (! CONSP (tail)) { - immediate_quit = false; CHECK_LIST_END (tail, list); return Qnil; } tail = XCDR (tail); } - immediate_quit = false; return tail; } @@ -1419,17 +1416,12 @@ DEFUN ("memq", Fmemq, Smemq, 2, 2, 0, The value is actually the tail of LIST whose car is ELT. */) (Lisp_Object elt, Lisp_Object list) { - immediate_quit = true; Lisp_Object tail; for (tail = list; CONSP (tail); tail = XCDR (tail)) { if (EQ (XCAR (tail), elt)) - { - immediate_quit = false; - return tail; - } + return tail; } - immediate_quit = false; CHECK_LIST_END (tail, list); return Qnil; } @@ -1442,18 +1434,13 @@ The value is actually the tail of LIST whose car is ELT. */) if (!FLOATP (elt)) return Fmemq (elt, list); - immediate_quit = true; Lisp_Object tail; for (tail = list; CONSP (tail); tail = XCDR (tail)) { Lisp_Object tem = XCAR (tail); if (FLOATP (tem) && internal_equal (elt, tem, 0, 0, Qnil)) - { - immediate_quit = false; - return tail; - } + return tail; } - immediate_quit = false; CHECK_LIST_END (tail, list); return Qnil; } @@ -1464,15 +1451,12 @@ The value is actually the first element of LIST whose car is KEY. Elements of LIST that are not conses are ignored. */) (Lisp_Object key, Lisp_Object list) { - immediate_quit = true; Lisp_Object tail; for (tail = list; CONSP (tail); tail = XCDR (tail)) - if (CONSP (XCAR (tail)) && EQ (XCAR (XCAR (tail)), key)) - { - immediate_quit = false; + { + if (CONSP (XCAR (tail)) && EQ (XCAR (XCAR (tail)), key)) return XCAR (tail); - } - immediate_quit = false; + } CHECK_LIST_END (tail, list); return Qnil; } @@ -1529,15 +1513,12 @@ DEFUN ("rassq", Frassq, Srassq, 2, 2, 0, The value is actually the first element of LIST whose cdr is KEY. */) (Lisp_Object key, Lisp_Object list) { - immediate_quit = true; Lisp_Object tail; for (tail = list; CONSP (tail); tail = XCDR (tail)) - if (CONSP (XCAR (tail)) && EQ (XCDR (XCAR (tail)), key)) - { - immediate_quit = false; + { + if (CONSP (XCAR (tail)) && EQ (XCDR (XCAR (tail)), key)) return XCAR (tail); - } - immediate_quit = false; + } CHECK_LIST_END (tail, list); return Qnil; } @@ -2077,21 +2058,18 @@ use `(setq x (plist-put x prop val))' to be sure to use the new value. The PLIST is modified by side effects. */) (Lisp_Object plist, Lisp_Object prop, Lisp_Object val) { - immediate_quit = true; Lisp_Object prev = Qnil; for (Lisp_Object tail = plist; CONSP (tail) && CONSP (XCDR (tail)); tail = XCDR (XCDR (tail))) { if (EQ (prop, XCAR (tail))) { - immediate_quit = false; Fsetcar (XCDR (tail), val); return plist; } prev = tail; } - immediate_quit = false; Lisp_Object newcell = Fcons (prop, Fcons (val, NILP (prev) ? plist : XCDR (XCDR (prev)))); if (NILP (prev)) @@ -2442,7 +2420,6 @@ usage: (nconc &rest LISTS) */) CHECK_CONS (tem); - immediate_quit = true; Lisp_Object tail; do { @@ -2451,7 +2428,6 @@ usage: (nconc &rest LISTS) */) } while (CONSP (tem)); - immediate_quit = false; rarely_quit (&quit_count); tem = args[argnum + 1]; @@ -2874,13 +2850,11 @@ property and a property with the value nil. The value is actually the tail of PLIST whose car is PROP. */) (Lisp_Object plist, Lisp_Object prop) { - immediate_quit = true; while (CONSP (plist) && !EQ (XCAR (plist), prop)) { plist = XCDR (plist); plist = CDR (plist); } - immediate_quit = false; return plist; } -- cgit v1.2.1 From b01ac672be1277833964d2d53f6dd26560c70343 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 1 Feb 2017 15:18:44 -0800 Subject: Revamp quitting and fix infloops This fixes some infinite loops that cannot be quitted out of, e.g., (defun foo () (nth most-positive-fixnum '#1=(1 . #1#))) when byte-compiled and when run under X. See: http://lists.gnu.org/archive/html/emacs-devel/2017-01/msg00577.html This also attempts to keep the performance improvements I recently added, as much as possible under the constraint that the infloops must be caught. In some cases this fixes infloop bugs recently introduced when I removed immediate_quit. * src/alloc.c (Fmake_list): Use rarely_quit, not maybe_quit, for speed in the usual case. * src/bytecode.c (exec_byte_code): * src/editfns.c (Fcompare_buffer_substrings): * src/fns.c (Fnthcdr): * src/syntax.c (scan_words, skip_chars, skip_syntaxes) (Fbackward_prefix_chars): Use rarely_quit so that users can C-g out of long loops. * src/callproc.c (call_process_cleanup, call_process): * src/fileio.c (read_non_regular, Finsert_file_contents): * src/indent.c (compute_motion): * src/syntax.c (scan_words, Fforward_comment): Remove now-unnecessary maybe_quit calls. * src/callproc.c (call_process): * src/doc.c (get_doc_string, Fsnarf_documentation): * src/fileio.c (Fcopy_file, read_non_regular, Finsert_file_contents): * src/lread.c (safe_to_load_version): * src/sysdep.c (system_process_attributes) [GNU_LINUX]: Use emacs_read_quit instead of emacs_read in places where C-g handling is safe. * src/eval.c (maybe_quit): Move comment here from lisp.h. * src/fileio.c (Fcopy_file, e_write): Use emacs_write_quit instead of emacs_write_sig in places where C-g handling is safe. * src/filelock.c (create_lock_file): Use emacs_write, not plain write, as emacs_write no longer has a problem. (read_lock_data): Use emacs_read, not read, as emacs_read no longer has a problem. * src/fns.c (rarely_quit): Move to lisp.h and rename to incr_rarely_quit. All uses changed.. * src/fns.c (Fmemq, Fmemql, Fassq, Frassq, Fplist_put, Fplist_member): * src/indent.c (compute_motion): * src/syntax.c (find_defun_start, back_comment, forw_comment) (Fforward_comment, scan_lists, scan_sexps_forward): Use incr_rarely_quit so that users can C-g out of long loops. * src/fns.c (Fnconc): Move incr_rarely_quit call to within inner loop, so that it catches C-g there too. * src/keyboard.c (tty_read_avail_input): Remove commented-out and now-obsolete code dealing with interrupts. * src/lisp.h (rarely_quit, incr_rarely_quit): New functions, the latter moved here from fns.c and renamed from rarely_quit. (emacs_read_quit, emacs_write_quit): New decls. * src/search.c (find_newline, search_buffer, find_newline1): Add maybe_quit to catch C-g. * src/sysdep.c (get_child_status): Always invoke maybe_quit if interruptible, so that the caller need not bother. (emacs_nointr_read, emacs_read_quit, emacs_write_quit): New functions. (emacs_read): Rewrite in terms of emacs_nointr_read. Do not handle C-g or signals; that is now for emacs_read_quit. (emacs_full_write): Replace PROCESS_SIGNALS two-way arg with INTERRUPTIBLE three-way arg. All uses changed. --- src/fns.c | 53 ++++++++++++++++++++++++----------------------------- 1 file changed, 24 insertions(+), 29 deletions(-) (limited to 'src/fns.c') diff --git a/src/fns.c b/src/fns.c index 444339c5259..41c0c5856b4 100644 --- a/src/fns.c +++ b/src/fns.c @@ -84,22 +84,6 @@ See Info node `(elisp)Random Numbers' for more details. */) return make_number (val); } -/* Heuristic on how many iterations of a tight loop can be safely done - before it's time to do a quit. This must be a power of 2. It - is nice but not necessary for it to equal USHRT_MAX + 1. */ -enum { QUIT_COUNT_HEURISTIC = 1 << 16 }; - -/* Process a quit, but do it only rarely, for efficiency. "Rarely" - means once per QUIT_COUNT_HEURISTIC or per USHRT_MAX + 1 times, - whichever is smaller. Use *QUIT_COUNT to count this. */ - -static void -rarely_quit (unsigned short int *quit_count) -{ - if (! (++*quit_count & (QUIT_COUNT_HEURISTIC - 1))) - maybe_quit (); -} - /* Random data-structure functions. */ DEFUN ("length", Flength, Slength, 1, 1, 0, @@ -1359,9 +1343,8 @@ DEFUN ("nthcdr", Fnthcdr, Snthcdr, 2, 2, 0, (Lisp_Object n, Lisp_Object list) { CHECK_NUMBER (n); - EMACS_INT num = XINT (n); Lisp_Object tail = list; - for (EMACS_INT i = 0; i < num; i++) + for (EMACS_INT num = XINT (n); 0 < num; num--) { if (! CONSP (tail)) { @@ -1369,6 +1352,7 @@ DEFUN ("nthcdr", Fnthcdr, Snthcdr, 2, 2, 0, return Qnil; } tail = XCDR (tail); + rarely_quit (num); } return tail; } @@ -1405,7 +1389,7 @@ The value is actually the tail of LIST whose car is ELT. */) { if (! NILP (Fequal (elt, XCAR (tail)))) return tail; - rarely_quit (&quit_count); + incr_rarely_quit (&quit_count); } CHECK_LIST_END (tail, list); return Qnil; @@ -1416,11 +1400,13 @@ DEFUN ("memq", Fmemq, Smemq, 2, 2, 0, The value is actually the tail of LIST whose car is ELT. */) (Lisp_Object elt, Lisp_Object list) { + unsigned short int quit_count = 0; Lisp_Object tail; for (tail = list; CONSP (tail); tail = XCDR (tail)) { if (EQ (XCAR (tail), elt)) return tail; + incr_rarely_quit (&quit_count); } CHECK_LIST_END (tail, list); return Qnil; @@ -1434,12 +1420,14 @@ The value is actually the tail of LIST whose car is ELT. */) if (!FLOATP (elt)) return Fmemq (elt, list); + unsigned short int quit_count = 0; Lisp_Object tail; for (tail = list; CONSP (tail); tail = XCDR (tail)) { Lisp_Object tem = XCAR (tail); if (FLOATP (tem) && internal_equal (elt, tem, 0, 0, Qnil)) return tail; + incr_rarely_quit (&quit_count); } CHECK_LIST_END (tail, list); return Qnil; @@ -1451,11 +1439,13 @@ The value is actually the first element of LIST whose car is KEY. Elements of LIST that are not conses are ignored. */) (Lisp_Object key, Lisp_Object list) { + unsigned short int quit_count = 0; Lisp_Object tail; for (tail = list; CONSP (tail); tail = XCDR (tail)) { if (CONSP (XCAR (tail)) && EQ (XCAR (XCAR (tail)), key)) return XCAR (tail); + incr_rarely_quit (&quit_count); } CHECK_LIST_END (tail, list); return Qnil; @@ -1486,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; - rarely_quit (&quit_count); + incr_rarely_quit (&quit_count); } CHECK_LIST_END (tail, list); return Qnil; @@ -1513,11 +1503,13 @@ DEFUN ("rassq", Frassq, Srassq, 2, 2, 0, The value is actually the first element of LIST whose cdr is KEY. */) (Lisp_Object key, Lisp_Object list) { + unsigned short int quit_count = 0; Lisp_Object tail; for (tail = list; CONSP (tail); tail = XCDR (tail)) { if (CONSP (XCAR (tail)) && EQ (XCDR (XCAR (tail)), key)) return XCAR (tail); + incr_rarely_quit (&quit_count); } CHECK_LIST_END (tail, list); return Qnil; @@ -1536,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; - rarely_quit (&quit_count); + incr_rarely_quit (&quit_count); } CHECK_LIST_END (tail, list); return Qnil; @@ -1692,7 +1684,7 @@ changing the value of a sequence `foo'. */) } else prev = tail; - rarely_quit (&quit_count); + incr_rarely_quit (&quit_count); } CHECK_LIST_END (tail, seq); } @@ -1717,10 +1709,10 @@ This function may destructively modify SEQ to produce the value. */) for (prev = Qnil, tail = seq; CONSP (tail); tail = next) { - rarely_quit (&quit_count); next = XCDR (tail); Fsetcdr (tail, prev); prev = tail; + incr_rarely_quit (&quit_count); } CHECK_LIST_END (tail, seq); seq = prev; @@ -1766,8 +1758,8 @@ See also the function `nreverse', which is used more often. */) unsigned short int quit_count = 0; for (new = Qnil; CONSP (seq); seq = XCDR (seq)) { - rarely_quit (&quit_count); new = Fcons (XCAR (seq), new); + incr_rarely_quit (&quit_count); } CHECK_LIST_END (seq, seq); } @@ -2058,6 +2050,7 @@ use `(setq x (plist-put x prop val))' to be sure to use the new value. The PLIST is modified by side effects. */) (Lisp_Object plist, Lisp_Object prop, Lisp_Object val) { + unsigned short int quit_count = 0; Lisp_Object prev = Qnil; for (Lisp_Object tail = plist; CONSP (tail) && CONSP (XCDR (tail)); tail = XCDR (XCDR (tail))) @@ -2069,6 +2062,7 @@ The PLIST is modified by side effects. */) } prev = tail; + incr_rarely_quit (&quit_count); } Lisp_Object newcell = Fcons (prop, Fcons (val, NILP (prev) ? plist : XCDR (XCDR (prev)))); @@ -2106,7 +2100,7 @@ one of the properties on the list. */) { if (! NILP (Fequal (prop, XCAR (tail)))) return XCAR (XCDR (tail)); - rarely_quit (&quit_count); + incr_rarely_quit (&quit_count); } CHECK_LIST_END (tail, prop); @@ -2136,7 +2130,7 @@ The PLIST is modified by side effects. */) } prev = tail; - rarely_quit (&quit_count); + incr_rarely_quit (&quit_count); } Lisp_Object newcell = list2 (prop, val); if (NILP (prev)) @@ -2216,7 +2210,7 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props, unsigned short int quit_count = 0; tail_recurse: - rarely_quit (&quit_count); + incr_rarely_quit (&quit_count); if (EQ (o1, o2)) return 1; if (XTYPE (o1) != XTYPE (o2)) @@ -2425,11 +2419,10 @@ usage: (nconc &rest LISTS) */) { tail = tem; tem = XCDR (tail); + incr_rarely_quit (&quit_count); } while (CONSP (tem)); - rarely_quit (&quit_count); - tem = args[argnum + 1]; Fsetcdr (tail, tem); if (NILP (tem)) @@ -2850,10 +2843,12 @@ property and a property with the value nil. The value is actually the tail of PLIST whose car is PROP. */) (Lisp_Object plist, Lisp_Object prop) { + unsigned short int quit_count = 0; while (CONSP (plist) && !EQ (XCAR (plist), prop)) { plist = XCDR (plist); plist = CDR (plist); + incr_rarely_quit (&quit_count); } return plist; } -- cgit v1.2.1 From b4c9f9120d8b0da0593f2fbde69b40374f56451d Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 1 Feb 2017 15:18:44 -0800 Subject: Fix quitting bug when buffers are frozen 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/fns.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'src/fns.c') diff --git a/src/fns.c b/src/fns.c index 41c0c5856b4..ac7c1f265a4 100644 --- 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; } -- cgit v1.2.1