Skip to content

Commit

Permalink
Ignore SIGINT sent to an interactive repl server
Browse files Browse the repository at this point in the history
Unfortunately, even though *pump-in* is false, the server subprocess
still gets the SIGINT when you hit <ctrl-c>. REPLy used to take care of
that by registering a handler itself, but it's a ClassLoader leak, as
discussed in trptcolin/reply#127, so I removed it. But now subprocess
servers crash instead of gracefully being interrupted.

Here we're careful only to register the process in the specific case
where we're responsible for both the input and the server.

Pro: REPLy clients avoid classloader leaks.
Con: All REPLy clients have to implement this same sort of handling, but
only (?) if they're running in a subprocess.
  • Loading branch information
trptcolin committed Jun 18, 2014
1 parent 4aefda6 commit e7c2330
Showing 1 changed file with 14 additions and 2 deletions.
16 changes: 14 additions & 2 deletions src/leiningen/repl.clj
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,15 @@
(for [n (concat defaults nrepl-syms nses caught)]
(list 'quote n))))

(defn- ignore-sigint-form []
`(when (try (Class/forName "sun.misc.Signal")
(catch ClassNotFoundException e#))
(try
(sun.misc.Signal/handle
(sun.misc.Signal. "INT")
(proxy [sun.misc.SignalHandler] [] (handle [signal#])))
(catch Throwable e#))))

(defn- server-forms [project cfg ack-port start-msg?]
[`(let [server# (clojure.tools.nrepl.server/start-server
:bind ~(:host cfg) :port ~(:port cfg)
Expand Down Expand Up @@ -199,8 +208,11 @@
ack-port (:port @ack-server)]
(-> (bound-fn []
(binding [eval/*pump-in* false]
(apply eval/eval-in-project project
(server-forms project cfg ack-port headless?))))
(let [[evals requires]
(server-forms project cfg ack-port headless?)]
(eval/eval-in-project project
`(do ~(ignore-sigint-form) ~evals)
requires))))
(Thread.) (.start))
(when project @prep-blocker)
(when headless? @(promise))
Expand Down

0 comments on commit e7c2330

Please sign in to comment.