[Openmcl-devel] interruptions
Gary Byers
gb at clozure.com
Fri Feb 24 13:54:47 PST 2012
There's a long explanation for why the archives of this mailing
list aren't easily searchable (as they sometimes have been in
the past.) Part of that explanation includes "... and it's easy
to search them using URLs that involve the string "google", but
I never remember what that is. You kids and your www-thing!
That means that I can't just say "anyone who wants to know
more about user-defined signal handlers and CCL should just
search the list archives", since this and some other issues
do come up repeatedly and are often discussed at some length.
Instead, I have to say "there are several discussions of this
in the mailing list archives. One of the more extensive and
relatively recent discussions is in the thread starting at:
<http://clozure.com/pipermail/openmcl-devel/2010-July/011667.html>
".
(The mailing-list-archive search software that we've sometimes used in
the past is part of a non-standard extension to GNU Mailman.
clozure.com runs Ubuntu, and Ubuntu's packaging system doesn't
incorporate that extension. If we patch Mailman manually, it becomes
harder to benefit from Ubuntu's packaging system and those benefits -
someone else worries about keeping system components in synch so that
we don't have to do so very much - are real and significant.)
On Fri, 24 Feb 2012, Pascal J. Bourguignon wrote:
> Gary Byers <gb at clozure.com> writes:
>
>> Sorry to have missed this message.
>>
>> If you're asking how to affect what happens when the OS-level process
>> receives a SIGINT (as would be produced by a user typing ^C), there's
>> basically a two-part answer.
>>
>> The first part is that hooking into what currently happens - where some
>> thread, typically the listener, gets forced via PROCESS-INTERRUPT to
>> enter a break loop - is awkward.
>>
>> The second part of the answer is that WAIT-FOR-SIGNAL can be used
>> to determine if and when an asynchronous signal like ^C occurs; what
>> to do in response is up to you.
>> [?]
>
>
> Happily, in my current application, I have a tight inner loop in which I
> can call wait-for-signal, and signal a condition when a SIGINT is
> detected:
>
> (define-condition user-interrupt (condition)
> ((signal :initarg :signal
> :initform 0
> :reader user-interrupt-signal))
> (:report (lambda (condition stream)
> (format stream "~S signal ~D"
> 'user-interrupt
> (user-interrupt-signal condition)))))
>
>
> (defun yield-signals (signals)
> #+ccl
> (dolist (signum signals)
> (when (ccl:wait-for-signal signum 0)
> (signal 'user-interrupt :signal signum))))
>
> In the case of clisp, I guess that being initially a unthreaded
> implementation, they have it easier to convert unix signals into lisp
> condition, which they do in the case of SIGINT (clisp signals a
> SYSTEM:USER-INTERRUPT condition).
>
> ECL has something similar, with its ext::unix-signal-received condition,
> sent when a unix signal is received (this is activated with a call to
> (ext:catch-signal signum t)).
>
> In all cases, this allows the program to deal with SIGINT, in a lispy
> way, using HANDLER-CASE or HANDLER-BIND.
>
>
>
>
>
>
> Now in the case of ccl, and for the first part above, I don't see a
> published API to deal with it. As you said, one would have to "hook
> into", looking at the implementation. I can understand that in presence
> of multiple threads, signal handling doesn't necessarily "break" running
> threads with a lisp condition, but run in some specific thread. But the
> program should be able to provide a function that will do what it has to
> do for the given application, eg. call PROCESS-INTERRUPT on the relevant
> threads of the application.
>
>
> So, I guess what I'm asking for here, would be an API to install such a
> signal handler, something like:
>
> (ccl:set-signal-handler signum thunk)
>
> The thunk would be run in whatever thread is processing the unix signal
> signum. NIL could be given to remove it.
>
>
> One could write:
>
> (ccl:set-signal-handler +sigint+
> (lambda ()
> (ccl:process-interrupt *application-process*
> (lambda () (signal 'user-interrupt)))))
>
>
> and in *application-process*:
>
> (handler-case
> (progn
> (do-something-lengthy)
> (print 'done))
> (user-interrupt ()
> (print 'interrupted))
> (error (err)
> (print 'error
> (princ err))))
>
>
>
> --
> __Pascal Bourguignon__ http://www.informatimago.com/
> A bad day in () is better than a good day in {}.
>
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel
More information about the Openmcl-devel
mailing list