[Ecls-list] Making an external signal handler play nice with embedded ECL
Juan Jose Garcia-Ripoll
juanjose.garciaripoll at googlemail.com
Mon Feb 28 08:33:40 UTC 2011
What about the code below? It has not been tested and might not be the
optimal way, but it fixes various problems:
* ecl_disable/enable_interrupts do not nest properly and thus can only be
used around very small pieces of code, typically foreign C functions.
* for prolongued interrupts disabling, use the special variable
ext:*interrupts-enabled*. This does not cause the use of mprotect() and just
queues signals. It has to be matched by an interrupt check, which is what
with-interrupts does.
const cl_env_ptr env = ecl_process_env();
cl_object variable = ecl_read_from_cstring("sys::*interrupts-enabled*");
/* Disable interrupts by lisp methods. All interrupts are queued.
* This is the preferred method to block interrupts for extended
* periods of time. */
ecl_bds_bind(env, variable, Cnil);
/* Protect from unwanted transfers of control */
ECL_CATCH_ALL_BEGIN(env) {
set_our_sighandlers_to_postpone_signals();
sigaction(SIGINT,ecl_sigint_handler,NULL);
sigaction(SIGSEGV,ecl_sigsegv_handler,NULL);
result=ecl_eval("
(handler-case
(ext:with-interrupts <actual code here>) ;;interrupts happen here
<condition handling and reporting> ;;and caught and reported here
)");
/* at this point there might be signals pending that
* happened at the error condition and reporting part.
* We probably should delete the following statement and
* ignore those signals. */
ecl_check_pending_interrupts();
} ECL_CATCH_ALL_END;
/* a signal arriving here would still be queued by ECL but won't
be processed. */
sigaction(SIGINT,our_sigint_handler,NULL);
sigaction(SIGSEGV,our_sigsegv_handler,NULL);
/* ... hence we clear them */
ecl_clear_interrupts_env(env);
set_our_handlers_to_process_signals();
On Mon, Feb 28, 2011 at 8:12 AM, Nils Bruin <nbruin at cecm.sfu.ca> wrote:
>
> Question: What would happen if a signal for ECL were queued but no
> mprotect were set? Would it take very long before the queue would be
> checked? Would the queue be checked at all?
Not in general, unless the user code is wrapped in some without-interrupts,
and then it would be checked only when exiting, or when there is some I/O
going on.
> If a foreign signal handler
> could get away with *just* queueing the signal to ECL, without
> mprotect-ing anything, integration would be much easier, because one
> doesn't have to deal with the possibility that a signal boomerangs back as
> a SIGSEGV (very elegant trick, though!)
The problem with that is that it forces us to set up periodic interrupt
checks that are costly, and should be scattered all over ECL's code. In
general I believe it would be better to live without interrupts, in an even
driven world plus some safe thread "aborting" operations.
Juanjo
--
Instituto de Física Fundamental, CSIC
c/ Serrano, 113b, Madrid 28006 (Spain)
http://juanjose.garciaripoll.googlepages.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/ecl-devel/attachments/20110228/53269fc0/attachment.html>
More information about the ecl-devel
mailing list