Skip to content

Commit c2b51f1

Browse files
Provide custom request to support continue/pause all/other threads (#315)
* Provide custom request to support continue/pause all/other threads Signed-off-by: Jinbo Wang <[email protected]> * Address review comment Signed-off-by: Jinbo Wang <[email protected]>
1 parent adbc59d commit c2b51f1

File tree

2 files changed

+65
-3
lines changed

2 files changed

+65
-3
lines changed

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ThreadsRequestHandler.java

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import com.microsoft.java.debug.core.protocol.Requests.Command;
3030
import com.microsoft.java.debug.core.protocol.Requests.ContinueArguments;
3131
import com.microsoft.java.debug.core.protocol.Requests.PauseArguments;
32+
import com.microsoft.java.debug.core.protocol.Requests.ThreadOperationArguments;
3233
import com.microsoft.java.debug.core.protocol.Requests.ThreadsArguments;
3334
import com.microsoft.java.debug.core.protocol.Responses;
3435
import com.microsoft.java.debug.core.protocol.Types;
@@ -40,13 +41,16 @@ public class ThreadsRequestHandler implements IDebugRequestHandler {
4041

4142
@Override
4243
public List<Command> getTargetCommands() {
43-
return Arrays.asList(Command.THREADS, Command.PAUSE, Command.CONTINUE);
44+
return Arrays.asList(Command.THREADS, Command.PAUSE, Command.CONTINUE, Command.CONTINUEALL,
45+
Command.CONTINUEOTHERS, Command.PAUSEALL, Command.PAUSEOTHERS);
4446
}
4547

4648
@Override
47-
public CompletableFuture<Response> handle(Command command, Arguments arguments, Response response, IDebugAdapterContext context) {
49+
public CompletableFuture<Response> handle(Command command, Arguments arguments, Response response,
50+
IDebugAdapterContext context) {
4851
if (context.getDebugSession() == null) {
49-
return AdapterUtils.createAsyncErrorResponse(response, ErrorCode.EMPTY_DEBUG_SESSION, "Debug Session doesn't exist.");
52+
return AdapterUtils.createAsyncErrorResponse(response, ErrorCode.EMPTY_DEBUG_SESSION,
53+
"Debug Session doesn't exist.");
5054
}
5155

5256
switch (command) {
@@ -56,6 +60,14 @@ public CompletableFuture<Response> handle(Command command, Arguments arguments,
5660
return this.pause((PauseArguments) arguments, response, context);
5761
case CONTINUE:
5862
return this.resume((ContinueArguments) arguments, response, context);
63+
case CONTINUEALL:
64+
return this.resumeAll((ThreadOperationArguments) arguments, response, context);
65+
case CONTINUEOTHERS:
66+
return this.resumeOthers((ThreadOperationArguments) arguments, response, context);
67+
case PAUSEALL:
68+
return this.pauseAll((ThreadOperationArguments) arguments, response, context);
69+
case PAUSEOTHERS:
70+
return this.pauseOthers((ThreadOperationArguments) arguments, response, context);
5971
default:
6072
return AdapterUtils.createAsyncErrorResponse(response, ErrorCode.UNRECOGNIZED_REQUEST_FAILURE,
6173
String.format("Unrecognized request: { _request: %s }", command.toString()));
@@ -114,6 +126,48 @@ private CompletableFuture<Response> resume(Requests.ContinueArguments arguments,
114126
return CompletableFuture.completedFuture(response);
115127
}
116128

129+
private CompletableFuture<Response> resumeAll(Requests.ThreadOperationArguments arguments, Response response, IDebugAdapterContext context) {
130+
context.getExceptionManager().removeAllExceptions();
131+
context.getDebugSession().resume();
132+
context.getProtocolServer().sendEvent(new Events.ContinuedEvent(arguments.threadId, true));
133+
context.getRecyclableIdPool().removeAllObjects();
134+
return CompletableFuture.completedFuture(response);
135+
}
136+
137+
private CompletableFuture<Response> resumeOthers(Requests.ThreadOperationArguments arguments, Response response, IDebugAdapterContext context) {
138+
List<ThreadReference> threads = DebugUtility.getAllThreadsSafely(context.getDebugSession());
139+
for (ThreadReference thread : threads) {
140+
long threadId = thread.uniqueID();
141+
if (threadId != arguments.threadId && thread.isSuspended()) {
142+
context.getExceptionManager().removeException(threadId);
143+
DebugUtility.resumeThread(thread);
144+
context.getProtocolServer().sendEvent(new Events.ContinuedEvent(threadId));
145+
checkThreadRunningAndRecycleIds(thread, context);
146+
}
147+
}
148+
149+
return CompletableFuture.completedFuture(response);
150+
}
151+
152+
private CompletableFuture<Response> pauseAll(Requests.ThreadOperationArguments arguments, Response response, IDebugAdapterContext context) {
153+
context.getDebugSession().suspend();
154+
context.getProtocolServer().sendEvent(new Events.StoppedEvent("pause", arguments.threadId, true));
155+
return CompletableFuture.completedFuture(response);
156+
}
157+
158+
private CompletableFuture<Response> pauseOthers(Requests.ThreadOperationArguments arguments, Response response, IDebugAdapterContext context) {
159+
List<ThreadReference> threads = DebugUtility.getAllThreadsSafely(context.getDebugSession());
160+
for (ThreadReference thread : threads) {
161+
long threadId = thread.uniqueID();
162+
if (threadId != arguments.threadId && !thread.isCollected() && !thread.isSuspended()) {
163+
thread.suspend();
164+
context.getProtocolServer().sendEvent(new Events.StoppedEvent("pause", threadId));
165+
}
166+
}
167+
168+
return CompletableFuture.completedFuture(response);
169+
}
170+
117171
/**
118172
* Recycle the related ids owned by the specified thread.
119173
*/

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Requests.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,10 @@ public static class PauseArguments extends Arguments {
244244
public long threadId;
245245
}
246246

247+
public static class ThreadOperationArguments extends Arguments {
248+
public long threadId;
249+
}
250+
247251
public static class ScopesArguments extends Arguments {
248252
public int frameId;
249253
}
@@ -335,6 +339,10 @@ public static enum Command {
335339
EXCEPTIONINFO("exceptionInfo", ExceptionInfoArguments.class),
336340
DATABREAKPOINTINFO("dataBreakpointInfo", DataBreakpointInfoArguments.class),
337341
SETDATABREAKPOINTS("setDataBreakpoints", SetDataBreakpointsArguments.class),
342+
CONTINUEALL("continueAll", ThreadOperationArguments.class),
343+
CONTINUEOTHERS("continueOthers", ThreadOperationArguments.class),
344+
PAUSEALL("pauseAll", ThreadOperationArguments.class),
345+
PAUSEOTHERS("pauseOthers", ThreadOperationArguments.class),
338346
UNSUPPORTED("", Arguments.class);
339347

340348
private String command;

0 commit comments

Comments
 (0)