On Mar 15, 12:24 pm, Raffael Cavallaro <
raffaelcavall...@gmail.com>
wrote:
I had a number of problems getting this to work in slime, just thought
I'd share for anyone else trying it out.
First, putting (add-break-thread!) in user.clj adds a break on the
main thread, but its the Swank REPL Thread that you actually want to
break out of. Calling (add-break-thread!) manually in the *slime-repl
clojure* buffer works.
Second, you have to switch to the *inferior-lisp* buffer in order for
Ctrl-C Ctrl-C to issue the SIGINT which will result in your Swank REPL
Thread getting a break.
Third, (and most excitingly) doing this will kill the Swank REPL
Thread. Calling Thread.stop(Throwable t), which the add-break-thread!
machinery does, seems to set the thread's interrupted status (*).
Even if you catch the initial SIGINT exception (t), the next call that
can throw an InterruptedException (like Object.wait or Thread.sleep)
will do so. The process of throwing it clears the interrupted status
flag, and after that things are back to normal.
Its this InterruptedException which kills the Swank REPL Thread when
it occurs unexpectedly. Unfortunately I can't see any way for the add-
break-thread!/start-handling-break SIGINT handler to prevent this; I
think the thread having .stop called on it has to clean things up
itself. I was able to keep the repl thread alive by putting a (Thread/
interrupted) call in swank.core/eval-for-emacs just before the (set!
*e t) call. Thread/interrupted clears the current thread's
interrupted status.
(*) - actually the interrupted status is not set if you are in the
middle of a call that can throw InterruptedException, see
Thread.interrupt() docs. So for example:
user=> (add-break-thread!)
{1 #<WeakReference java.lang.ref.WeakReference@8722c99>}
user=> (Thread/sleep 10000)
^Cjava.lang.Exception: SIGINT (NO_SOURCE_FILE:0)
user=> (Thread/sleep 10) ; OK, interrupted status has not been set
nil
user=> (dorun (iterate inc 0))
^Cjava.lang.RuntimeException: java.lang.Exception: SIGINT
(NO_SOURCE_FILE:0)
user=> (Thread/sleep 10) ; will throw InterruptedException
java.lang.InterruptedException: sleep interrupted (NO_SOURCE_FILE:0)
One final note -- start-handling-break resets the break-threads map to
{} every time it is called, meaning that add-break-thread! effectively
sets the thread its called on as the *only* thread to have a break.
Is that a bug?
Other than these niggles add-break-thread! gets the job done, and it
sure is nice not to have to restart everything.
--
Gavin Scott
gavin...@gmail.com