[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Catch arbitrary signal and throw it later in C
From: |
Po Lu |
Subject: |
Re: Catch arbitrary signal and throw it later in C |
Date: |
Thu, 13 Apr 2023 16:22:47 +0800 |
User-agent: |
Gnus/5.13 (Gnus v5.13) |
Yuan Fu <casouri@gmail.com> writes:
> unwind-protect (and its internal C counterpart) pushes the cleanup
> form onto specpdl. Supposingly that form is later eval’ed? I want to
> run some C code which obviously it doesn’t support. I need to
> understand how this whole unwinding thing work before I can maybe
> modify or write something that does what I want. Hopefully some one
> can enlighten me :-)
Typically, you do this:
specpdl_ref count;
struct localcontext context;
count = SPECPDL_INDEX ();
record_unwind_protect_ptr (cleanup_func, &context);
/* Code which may signal. */
unbind_to (count, Qnil);
where cleanup_func is:
void
cleanup_func (void *arg)
Once a signal happens between the `record_unwind_protect_ptr', and
`unbind_to', `cleanup_func' will be called with `&context' as an
argument. This happens before any longjmp, so it is safe to use
references to variables with automatic storage duration within unwind
protects you record.
Note that `record_unwind_protect_ptr' itself may also signal if the
specpdl is full, calling the unwind function in the process.
If your cleanup function needs arguments that aren't pointers, you can
also use `record_unwind_protect_int', `record_unwind_protect', or
`record_unwind_protect_void'.
Saving a signal, only to throw it again later, is not something we do in
Emacs. I suggest you make your cleanup code work as described above.