aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChouser <chouser@n01se.net>2009-03-06 22:42:43 +0000
committerChouser <chouser@n01se.net>2009-03-06 22:42:43 +0000
commit042c0445b39d40c798ec1cc8eeee4927b817282a (patch)
tree0210fe679cc3c2aa28113ec2ce897b28dd4d6c64
parentd3e8f4910bdc1cf758b66ee158d655245167763e (diff)
repl-utils: add Ctrl-C support. See 'add-break-thread!'
-rw-r--r--src/clojure/contrib/repl_utils.clj34
1 files changed, 33 insertions, 1 deletions
diff --git a/src/clojure/contrib/repl_utils.clj b/src/clojure/contrib/repl_utils.clj
index 671cb39d..9d85d140 100644
--- a/src/clojure/contrib/repl_utils.clj
+++ b/src/clojure/contrib/repl_utils.clj
@@ -121,4 +121,36 @@
[n]
`(println (or (get-source '~n) (str "Source not found"))))
-(load "repl_utils/javadoc") \ No newline at end of file
+
+(def #^{:doc "Threads to stop when Ctrl-C is pressed. See 'add-break-thread!'"}
+ break-threads (ref nil))
+
+(defn start-handling-break
+ "Register INT signal handler. After calling this, Ctrl-C will cause
+ all break-threads to be stopped. See 'add-break-thread!'"
+ []
+ (when-not
+ (dosync
+ (let [inited @break-threads]
+ (ref-set break-threads {})
+ inited))
+ (sun.misc.Signal/handle
+ (sun.misc.Signal. "INT")
+ (proxy [sun.misc.SignalHandler] []
+ (handle [sig]
+ (let [exc (Exception. (str sig))]
+ (doseq [tref (vals @break-threads) :when (.get tref)]
+ (.stop (.get tref) exc))))))))
+
+(defn add-break-thread!
+ "Add the given thread to break-threads so that it will be stopped
+ any time the user presses Ctrl-C. Calls start-handling-break for
+ you. Adds the current thread if none is give."
+ ([] (add-break-thread! (Thread/currentThread)))
+ ([t]
+ (start-handling-break)
+ (let [tref (java.lang.ref.WeakReference. t)]
+ (dosync (commute break-threads assoc (.getId t) tref)))))
+
+
+(load "repl_utils/javadoc")