[Openmcl-devel] Unix signal handling
Ron Garret
ron at flownet.com
Tue Jul 6 17:35:16 PDT 2010
Actually, on thinking about this some more, a message queue isn't necessary because signals are already segregated by the OS. So something like this should work:
(defmacro set-signal-handler (signo &body body)
(let ((sem (make-semaphore))
(handler (gensym "HANDLER")))
`(progn
(defcallback ,handler (:int signo :void)
(declare (ignore signo))
(signal-semaphore ',sem))
(#_signal ,signo ,handler)
(process-run-function ,(format nil "SIGNAL ~A HANDLER" signo)
(lambda ()
(loop
(wait-on-semaphore ',sem)
, at body))))))
I tried it and it actually does seem to work. To really make this bulletproof you'd want to tweak it so that calling set-signal-handler multiple times on the same signals didn't leave garbage processes lying around.
rg
On Jul 6, 2010, at 3:57 PM, Ron Garret wrote:
> Seems to me the Right Way to do this is not to poll but to set up a message queue. The actual signal handlers would push their signal number onto the queue, and then there would be a signal servicing thread popping things off the queue and calling the appropriate (user-settable) handler function, which would now be running in a regular Lisp callback context. Seems like this ought to be doable at the user level through the FFI.
>
> rg
>
> On Jul 6, 2010, at 1:21 PM, Scott L. Burson wrote:
>
>> On Tue, Jul 6, 2010 at 11:52 AM, Gary Byers <gb at clozure.com> wrote:
>>
>>
>> On Tue, 6 Jul 2010, Daniel Weinreb wrote:
>>
>> You added ccl:*quit-interrupt-hook*, which is called
>> on SIGTERM. Does it have these problems?
>>
>> No.
>>
>> There's a handler for SIGTERM (and SIGINT and IIRC SIGQUIT)
>> in the lisp kernel; it just sets a flag in memory indicating
>> which of those signals have been received since the flag was
>> last cleared.
>>
>> Some lisp code that runs a few times a second checks/clears that flag
>> and interrupts some thread. There are a few hooks that give a little
>> bit of control over what thread gets interrupted and (in the case of
>> SIGQUIT/SIGTERM) what function gets called. That's (at most) just a
>> matter of interrupting a thread via PROCESS-INTERRUPT, and
>> PROCESS-INTERRUPT tries to be very careful about when/how the target
>> thread is interrupted.
>>
>> A more general mechanism would allow you to do something like:
>>
>> (define-signal-handler SIGQUIT
>> ;; This runs on an arbitrary thread at a more-or-less arbitrary
>> ;; time. The implementation has ensured that it's GC-safe to
>> ;; run lisp code now; beyond that, you have enough rope to hang
>> ;; yourself in lots of ways, and you may not be able to safely
>> ;; do too much more than set a flag here.
>> (arbitrary-code ...))
>>
>> but that mechanism doesn't exist and would require some implementation
>> support to even offer the GC-safety that the comment describes.
>>
>>
>> But couldn't this mechanism be implemented in exactly the same way as you have described doing for SIGTERM? It would certainly be adequate for my needs; I don't need microsecond response times (though 250ms would be a bit on the long side; maybe the poll rate of "a few times a second" needs to be 20/sec or so).
>>
>> -- Scott
>>
>> _______________________________________________
>> Openmcl-devel mailing list
>> Openmcl-devel at clozure.com
>> http://clozure.com/mailman/listinfo/openmcl-devel
>
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.clozure.com/pipermail/openmcl-devel/attachments/20100706/19c32e3c/attachment.htm>
More information about the Openmcl-devel
mailing list