Re: Interrupting repl in Slime
Alessio Stalla <[email protected]> Thu, 7 Apr 2022 09:22:56 +0200
| Newsgroups | gmane.editors.j.devel |
|---|---|
| Message-ID | <CAL2Kp+gOggKd1NRk5XtdQbKS4q4nEzxRU697SXM=KXPTAhwsjw@mail.gmail.com> |
To me, this looks overly complicated with all these flags. I never understood why ABCL does all this. Java threads already natively have an interrupt flag. Is there a reason for not using the native Java mechanism? https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html On Thu, 7 Apr 2022 at 00:13, Alan Ruttenberg <[email protected]> wrote: > Hi folks, > > Maybe someone has a feel for how interrupts work in ABCL? > > Doing an interrupt in ABCL from Slime doesn't interrupt until the end of a > function or sleep or wait is called. This means whenever I accidentally > have a too long or infinite loop by mistake the only thing I can do is quit > lisp and start over. This is probably THE most irritating problem I have > with ABCL. It doesn't happen often but when it does it completely disrupts > work. > > Slime handles an interrupt by calling interrupt-thread. Interrupt-thread > saves the function and sets a flag. When the interrupted process next > checks the flag it will call the interrupt function. At first I thought > lisp wasn't checking for an interrupt often enough, but that's not the > problem. If I compile (loop for i = 1) I get > > public final LispObject execute() { > ; do { > ; if (!Lisp.interrupted) { > ; continue; > ; } > ; Lisp.handleInterrupt(); > ; } while (true); > ; } > > So why doesn't the interrupt work? Well it seems there are two paths to > interrupt. One is via interrupt-thread. Here is the code that sets the flag. > > final synchronized void interrupt(LispObject function, LispObject args) > { > pending = new Cons(args, pending); > pending = new Cons(function, pending); > threadInterrupted = true; > javaThread.interrupt(); > } > > Note that it is setting thread.threadInterrupted rather than > Lisp.interrupted. In fact, the only way to set Lisp.interrupted is via > Lisp.setInterrupted() and the only function that calls that is > ext:interrupt-lisp. Nothing calls ext:interrupt-lisp. So that nice check > within the loop is checking for a signal that currently never arrives. > > The javathread.interrupt is only periodically detected by an explicit call > or via an InterruptedException that Java will throw when the thread yields > or via a check of thread.isInterrupted. The latter is checked in one place, > inside a catch, which afaik isn't executed unless there's an error in the > thread - it's the "Ignoring uncaught exception" path. > > Now, if I call ext:interrupt-lisp from the *inferior-lisp* a break comes > up during the infinite loop and I can kill it! This is the desired > behavior. > > The problem is, I can't figure out where to call (ext:interrupt-lisp) > within slime. I tried to put it right after interrupt-thread when that is > called in swank::queue-thread-interrupt, which is what is eventually called > when you hit C-c in the repl. But that causes an error and kills the slime > session. And emacs, for that matter, which needs to be force quit. > > I'm thinking that in the case of a control-c we should not use > thread-interrupt but rather lisp interrupted. threadInterrupted is thread > local and Lisp.interrupted is a global. So technically the control c might > not go to the right thread, since all threads are checking the global. But > in the situation where it's locked in an infinite loop, there's no other > thread doing anything, so the right thing happens. In any case I think > that's probably easy to fix by setting another volatile to the thread to be > interrupted. In general one would have to worry about a race condition if > there were several places that might call interrupt-lisp, but in this case > it would only be called with an explicit Control-c and perhaps on a request > to kill a thread from the slime threads buffer. > > It's an open question as to whether interrupt-thread should take advantage > of this as well, but that would require more care to avoid a race condition. > > Any help on sorting this would be much appreciated. > > Thanks, > Alan >