I have many examples of Java bytecode, all of which I’d like to execute from Clojure. Each sequence of bytecode may contain an infinite loop, in which case I’d like to stop running it after a couple of seconds. I’ve been looking at futures as a means of doing this. Having hunted around for a couple of implementations I’ve tried both this code:
(deref (future (loop[a 1] (recur a)) :done!) 1000 :impatient!)
…and also the code at https://gist.github.com/3124000
In both cases, the loop appears to be timed out appropriately (and in the latter case the future is reported to have been both done and cancelled), but I see my CPU usage rise to 99% or thereabouts and stay there. I also see that each time I run this code, my Java process gains an extra thread.
It looks to me like the future is being cancelled, but the code is still running. In my program I will need to run, and time out, some very tight infinite loops (e.g. the Java bytecode equivalent of “20 PRINT GOTO 10”) and I don’t have the option of modifying the code that I’m running.
Any ideas why I’m seeing this behaviour; what I could do to prevent it; or alternative methods for me to realise my aim of running and timing out such code?
The only way I’ve found to actual kill a the code executing inside a thread is to use the deprecated
.stopmethod. In a lot of cases, the reason that it is deprecated isn’t really important.I had a function in clojail for doing just that. Feel free to snatch the function out or just pull in the library.