23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
25 |
26 package jdk.internal.jshell.jdi; |
26 package jdk.internal.jshell.jdi; |
27 |
27 |
|
28 import java.util.function.Consumer; |
28 import com.sun.jdi.*; |
29 import com.sun.jdi.*; |
29 import com.sun.jdi.event.*; |
30 import com.sun.jdi.event.*; |
30 |
31 |
31 /** |
32 /** |
32 * Handler of Java Debug Interface events. |
33 * Handler of Java Debug Interface events. |
33 * Adapted from jdb EventHandler; Handling of events not used by JShell stubbed out. |
34 * Adapted from jdb EventHandler; Handling of events not used by JShell stubbed out. |
34 */ |
35 */ |
35 class JDIEventHandler implements Runnable { |
36 class JDIEventHandler implements Runnable { |
36 |
37 |
37 Thread thread; |
38 private final Thread thread; |
38 volatile boolean connected = true; |
39 private volatile boolean connected = true; |
39 boolean completed = false; |
40 private boolean completed = false; |
40 String shutdownMessageKey; |
41 private final VirtualMachine vm; |
41 final JDIEnv env; |
42 private final Consumer<Boolean> reportVMExit; |
42 |
43 |
43 JDIEventHandler(JDIEnv env) { |
44 JDIEventHandler(VirtualMachine vm, Consumer<Boolean> reportVMExit) { |
44 this.env = env; |
45 this.vm = vm; |
|
46 this.reportVMExit = reportVMExit; |
45 this.thread = new Thread(this, "event-handler"); |
47 this.thread = new Thread(this, "event-handler"); |
46 this.thread.start(); |
48 } |
|
49 |
|
50 void start() { |
|
51 thread.start(); |
47 } |
52 } |
48 |
53 |
49 synchronized void shutdown() { |
54 synchronized void shutdown() { |
50 connected = false; // force run() loop termination |
55 connected = false; // force run() loop termination |
51 thread.interrupt(); |
56 thread.interrupt(); |
109 private boolean vmDied = false; |
114 private boolean vmDied = false; |
110 |
115 |
111 private void handleExitEvent(Event event) { |
116 private void handleExitEvent(Event event) { |
112 if (event instanceof VMDeathEvent) { |
117 if (event instanceof VMDeathEvent) { |
113 vmDied = true; |
118 vmDied = true; |
114 shutdownMessageKey = "The application exited"; |
|
115 } else if (event instanceof VMDisconnectEvent) { |
119 } else if (event instanceof VMDisconnectEvent) { |
116 connected = false; |
120 connected = false; |
117 if (!vmDied) { |
|
118 shutdownMessageKey = "The application has been disconnected"; |
|
119 } |
|
120 } else { |
121 } else { |
121 throw new InternalError("Unexpected event type: " + |
122 throw new InternalError("Unexpected event type: " + |
122 event.getClass()); |
123 event.getClass()); |
123 } |
124 } |
124 env.shutdown(); |
125 reportVMExit.accept(vmDied); |
125 } |
126 } |
126 |
127 |
127 synchronized void handleDisconnectedException() { |
128 private synchronized void handleDisconnectedException() { |
128 /* |
129 /* |
129 * A VMDisconnectedException has happened while dealing with |
130 * A VMDisconnectedException has happened while dealing with |
130 * another event. We need to flush the event queue, dealing only |
131 * another event. We need to flush the event queue, dealing only |
131 * with exit events (VMDeath, VMDisconnect) so that we terminate |
132 * with exit events (VMDeath, VMDisconnect) so that we terminate |
132 * correctly. |
133 * correctly. |
133 */ |
134 */ |
134 EventQueue queue = env.vm().eventQueue(); |
135 EventQueue queue = vm.eventQueue(); |
135 while (connected) { |
136 while (connected) { |
136 try { |
137 try { |
137 EventSet eventSet = queue.remove(); |
138 EventSet eventSet = queue.remove(); |
138 EventIterator iter = eventSet.eventIterator(); |
139 EventIterator iter = eventSet.eventIterator(); |
139 while (iter.hasNext()) { |
140 while (iter.hasNext()) { |