@@ -4,6 +4,8 @@ import dotty.tools.dotc.core.Contexts.Context
4
4
5
5
import java .io .{File , PrintStream , IOException }
6
6
import java .lang .ProcessBuilder .Redirect
7
+ import java .util .concurrent .CancellationException
8
+ import java .util .{Timer , TimerTask }
7
9
8
10
import org .eclipse .lsp4j .jsonrpc .CancelChecker
9
11
@@ -32,7 +34,7 @@ private object Evaluator {
32
34
def get (cancelChecker : CancelChecker )(implicit ctx : Context ): Option [Evaluator ] = synchronized {
33
35
val classpath = ctx.settings.classpath.value
34
36
previousEvaluator match {
35
- case Some (cp, evaluator) if evaluator.isAlive() && cp == classpath =>
37
+ case Some (cp, evaluator) if evaluator.isAlive && cp == classpath =>
36
38
evaluator.reset(cancelChecker)
37
39
Some (evaluator)
38
40
case _ =>
@@ -53,7 +55,7 @@ private object Evaluator {
53
55
*/
54
56
private class Evaluator private (javaExec : String ,
55
57
userClasspath : String ,
56
- cancelChecker : CancelChecker ) {
58
+ private var cancelChecker : CancelChecker ) {
57
59
private val process =
58
60
new ProcessBuilder (
59
61
javaExec,
@@ -70,13 +72,24 @@ private class Evaluator private (javaExec: String,
70
72
// Messages coming out of the REPL
71
73
private val processOutput = new InputStreamConsumer (process.getInputStream())
72
74
73
- // The thread that monitors cancellation
74
- private val cancellationThread = new CancellationThread (cancelChecker, this )
75
- cancellationThread.start()
75
+ // A timer that monitors cancellation
76
+ private val cancellationTimer = new Timer ()
77
+ locally {
78
+ val task = new TimerTask {
79
+ def run (): Unit =
80
+ if (! isAlive)
81
+ cancellationTimer.cancel()
82
+ else
83
+ try cancelChecker.checkCanceled()
84
+ catch { case _ : CancellationException => exit() }
85
+ }
86
+ val checkCancelledDelayMs = 50L
87
+ cancellationTimer.schedule(task, checkCancelledDelayMs, checkCancelledDelayMs)
88
+ }
76
89
77
90
78
91
/** Is the process that runs the REPL still alive? */
79
- def isAlive () : Boolean = process.isAlive()
92
+ def isAlive : Boolean = process.isAlive
80
93
81
94
/**
82
95
* Submit `command` to the REPL, wait for the result.
@@ -97,16 +110,14 @@ private class Evaluator private (javaExec: String,
97
110
* Reset the REPL to its initial state, update the cancel checker.
98
111
*/
99
112
def reset (cancelChecker : CancelChecker ): Unit = {
100
- cancellationThread.setCancelChecker( cancelChecker)
113
+ this . cancelChecker = cancelChecker
101
114
eval(" :reset" )
102
115
}
103
116
104
117
/** Terminate this JVM. */
105
118
def exit (): Unit = {
106
119
process.destroyForcibly()
107
120
Evaluator .previousEvaluator = None
108
- cancellationThread.interrupt ()
121
+ cancellationTimer.cancel ()
109
122
}
110
-
111
123
}
112
-
0 commit comments