[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