]> git.eshelyaron.com Git - emacs.git/commitdiff
itree: Try and detect non-local exits during itree iterations
authorStefan Monnier <monnier@iro.umontreal.ca>
Fri, 7 Oct 2022 23:15:07 +0000 (19:15 -0400)
committerStefan Monnier <monnier@iro.umontreal.ca>
Fri, 7 Oct 2022 23:15:07 +0000 (19:15 -0400)
* src/itree.c (itree_busy_p): New function.
* src/eval.c (signal_or_quit): Use it.
* src/itree.h (itree_busy_p): Declare it.

src/eval.c
src/itree.c
src/itree.h

index 7da1d8fb98998da451ae3128055375667ae2ae64..37c25c79148b08aa88d8272cac81b246cacc9d4b 100644 (file)
@@ -1711,6 +1711,7 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
   Lisp_Object clause = Qnil;
   struct handler *h;
 
+  eassert (!itree_busy_p ());
   if (gc_in_progress || waiting_for_input)
     emacs_abort ();
 
index d955c57539046df9224dd6a1a9ca8e8bbfb8ebe3..de16af5b0c2ff686c708613171e7eb850b3ad32c 100644 (file)
@@ -725,6 +725,12 @@ interval_tree_validate (struct interval_tree *tree, struct interval_node *node)
   return node;
 }
 
+bool
+itree_busy_p (void)
+{
+  return (iter && iter->running);
+}
+
 /* Start a generator iterating all intervals in [BEGIN,END) in the
    given ORDER. Only one iterator per tree can be running at any
    time.
index 9e40b87cc4f9a0f03b3841a9b70603b499b96561..7fdc9c07c935bf9465f40128bd0b89fe68a9dfcf 100644 (file)
@@ -129,6 +129,7 @@ void interval_tree_iter_finish (struct interval_generator *);
 struct interval_node *interval_generator_next (struct interval_generator *);
 void interval_tree_insert_gap (struct interval_tree *, ptrdiff_t, ptrdiff_t);
 void interval_tree_delete_gap (struct interval_tree *, ptrdiff_t, ptrdiff_t);
+bool itree_busy_p (void);
 
 /* Iterate over the intervals between BEG and END in the tree T.
    N will hold successive nodes.  ORDER can be one of : `ASCENDING`,
@@ -148,9 +149,7 @@ void interval_tree_delete_gap (struct interval_tree *, ptrdiff_t, ptrdiff_t);
      be able to run ELisp code (or GC for that matter).
    - If you need to exit the loop early, you *have* to call `ITREE_ABORT`
      just before exiting (e.g. with `break` or `return`).
-   - Non-local exits are not supported within the body of the loop,
-     unless the caller makes sure `ITREE_ABORT` is called via some
-     kind of unwind_protect.
+   - Non-local exits are not supported within the body of the loop.
    - Don't modify the tree during the iteration.
  */
 #define ITREE_FOREACH(n, t, beg, end, order)                        \