[Openmcl-devel] Catching Control C

Gary Byers gb at clozure.com
Sat Jan 30 20:35:33 PST 2010


^C (SIGINT) is sent by the OS (the tty driver) to some thread
in the target process.  (POSIX doesn't say which thread, and
the last time that I checked there was some variance in OS
behavior in this regard: it might get sent to the initial
thread in the process, or to some thread that's already
scheduled.)

A handler in the lisp kernel handles SIGINT (and SIGQUIT
and SIGTERM) and just sets a bit in a global variable.

The default initial function in CCL does something like:

(progn
   (so-some-low-level-reinitialization)
   (start-listener-thread)
   (housekeeping-loop))

where HOUSEKEEPING-LOOP is something like:

(loop
   (sleep .33)
   (housekeeping)) ; do periodic things about 3 times per second

CCL::HOUSEKEEPING is defined in "ccl:level-1;l1-events.lisp" and
may be somewhat readable ...  One of the things that it does is
to see if the OS-level process has received any of SIGINT/SIGQUIT/
SIGTERM recently and, if so, try to determine what lisp thread should
handle the pending signal and, in some cases, how.  (The actual
thread-level handling is done via PROCESS-INTERRUPT.)

Some of this code is ancient (originally from the days before MCL
had cooperative threads); it used to provide the means by which GUI
event processing took place, which explains the filename and the
names of some of the functions involved.  The most important things
that happen in CCL::HOUSEKEEPING are:

   - handling of post-gc hooks for object termination/finalization
   - this deferred signal handling stuff
   - flushing (via FORCE-OUTPUT) of some interactive output streams

This deferred handling scheme may seem like overkill for a single-threaded
application, but it has some advantages in that situation as well: critical
code sections that don't want to be interrupted can ensure that they aren't
interrupted (via WITHOUT-INTERRUPTS) without having to manipulate the thread's
signal mask.

The scheme does mean that a single-threaded application either:
  - isn't interruptible via ^C
  - has to arrange to check for pending signals periodically, which may or
    may not fit into the application's structure.
  - fires off a thread to do CCL::HOUSEKEEPING-LOOP (or something like it),
    in which case it's not exactly a single-threaded application anymore.


On Sun, 31 Jan 2010, Waldek Hebisch wrote:

> How to catch Control C in a program?  On Clozure CL command
> line pressing Control C brings Lisp debugger.  However, when
> running my program Control C apparently is ignored.  I have
> set up an error handler and when using sbcl pressing Control C
> raises condition which my handler can catch.  But when
> I create an executable using Closure CL my handler is not
> called and apparently Control C is lost.
>
> --
>                              Waldek Hebisch
> hebisch at math.uni.wroc.pl
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel
>
>



More information about the Openmcl-devel mailing list