Peter Graves | 20 May 2006 14:49

Re: interruptability

On Sat, 20 May 2006 at 01:28:46 -0400, Alan Ruttenberg wrote:
> OK. To compile this for OS X,  In native.c we need
>
> JNIEnv *_env = 0;
> jclass _cls = 0;
> jmethodID _mid = 0;
>
> and the command line is
>
> gcc -dynamiclib -o libabcl.jnilib -O -D_REENTRANT -fPIC -I/System/ 
> Library/Frameworks/JavaVM.framework/Home/include native.c -framework  
> JAVAVM
>
> I copied it to  /Library/Java/Extensions/
>
> Unfortunately, I get a bus error when I try to use it.
> getCurrentThreadUserTime work though.
>
> OTOH, Slime tries to use (ext:interrupt-thread), and by tracing it, I  
> can see that it is called when I hit control-c, and that it is  
> apparently being called right away. But the break doesn't happen  
> until the loop ends.
>
> CL-USER> (CURRENT-THREAD)
> #<THREAD "new-repl-thread" {1909CB}>
> CL-USER> (dotimes (i 10000000))
>    0: (INTERRUPT-THREAD #<THREAD "new-repl-thread" {1909CB}>  
> #<FUNCTION SWANK:SIMPLE-BREAK {5B1698}>)
>    0: INTERRUPT-THREAD returned T
> <wait until the dotimes finishes>
> break happens now
>
> And the computation continues. When it finally finishes, I get the  
> break. The way I read the code, it depends on Thread.interrupt being  
> called, which should generate a InterruptedException in the thread  
> being interrupted, which you catch and use to call processInterrupts.  
> InterruptedException says "Thrown when a thread is waiting, sleeping,  
> or otherwise paused for a long time and another thread interrupts it  
> using the interrupt method in class Thread.". This apparently doesn't  
> happen in a timely manner.

Yeah, I think this is a Java issue. There may be a workaround, but the
workaround is likely to depend on what platform you're on and what
version of Java you're using. I'm not too optimistic about a general
solution.

> For the control-c handler, in any case, in a situation where there  
> are multiple threads, who's to guarantee that the right thread  
> notices Lisp.Interrupted.

Good point.

The original idea of the control c handler was to be able to break out
of situations where there was only one Lisp thread and that thread was
stuck in a loop, which sometimes happened with Paul Dietz's random
tester in the early days of ABCL's compiler.

Using control c in that sort of situation works more often than not, in
my experience, although sometimes it just crashes Java.

I never really expected the control c handler to handle multithreaded
situations. If you want to interrupt a background thread, presumably
you know which thread that is, and, in theory, you can use INTERRUPT-
THREAD. It seems like this is what slime is doing. The problem is that
INTERRUPT-THREAD doesn't really work, but, as mentioned, I think that's
probably a Java issue.

> Since you already have the infrastructure for Lisp.interrupted, would  
> the following work? Change Lisp.interrupted to be an Object. In  
> handleInterrupt, if Lisp.Interrupt is True or False, then handle the  
> way you do now. If not, check if it is equal to the current thread  
> and if not, do nothing. That way you can call setInterrupted with a  
> specific thread and know that it will pick it up.

It might be worth a try, but if the stuck thread doesn't respond to
Thread.interrupt(), I doubt that it's going to notice Lisp.interrupted
either.

Note, by the way, that handleInterrupt() only gets called in
interpreted Lisp code or in Lisp code compiled with safety >= speed;
code in pure-Java libraries will never see Lisp.interrupted at all.

-Peter

-------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

Gmane