/*******************************************************************************
* Copyright (c) 2006, 2010 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
* Nokia - create and use backend service.
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.actions;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.debug.service.IProcesses;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext;
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.debug.core.commands.IDebugCommandRequest;
import org.eclipse.debug.core.commands.IEnabledStateRequest;
import org.eclipse.debug.core.commands.ITerminateHandler;
public class DsfTerminateCommand implements ITerminateHandler {
private final DsfExecutor fExecutor;
private final DsfServicesTracker fTracker;
public DsfTerminateCommand(DsfSession session) {
fExecutor = session.getExecutor();
fTracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), session.getId());
}
public void dispose() {
fTracker.dispose();
}
// Run control may not be avilable after a connection is terminated and shut down.
public void canExecute(final IEnabledStateRequest request) {
if (request.getElements().length != 1 ||
!(request.getElements()[0] instanceof IDMVMContext) )
{
request.setEnabled(false);
request.done();
return;
}
IDMVMContext vmc = (IDMVMContext)request.getElements()[0];
// First check if there is an ancestor process to terminate. This is the smallest entity we can terminate
final IProcessDMContext processDmc = DMContexts.getAncestorOfType(vmc.getDMContext(), IProcessDMContext.class);
if (processDmc == null) {
request.setEnabled(false);
request.done();
return;
}
try {
fExecutor.execute(
new DsfRunnable() {
public void run() {
// Get the processes service and the exec context.
IProcesses procService = fTracker.getService(IProcesses.class);
if (procService == null) {
// Service already invalid.
request.setEnabled(false);
request.done();
} else {
procService.canTerminate(processDmc, new DataRequestMonitor<Boolean>(ImmediateExecutor.getInstance(), null) {
@Override
protected void handleCompleted() {
request.setEnabled(isSuccess() && getData());
request.done();
}
});
}
}
});
} catch (RejectedExecutionException e) {
request.setEnabled(false);
request.done();
}
}
public boolean execute(final IDebugCommandRequest request) {
if (request.getElements().length != 1 ||
!(request.getElements()[0] instanceof IDMVMContext)) {
request.done();
return false;
}
IDMVMContext vmc = (IDMVMContext)request.getElements()[0];
// First check if there is an ancestor process to terminate. This is the smallest entity we can terminate
final IProcessDMContext processDmc = DMContexts.getAncestorOfType(vmc.getDMContext(), IProcessDMContext.class);
if (processDmc == null) {
request.done();
return false;
}
try {
fExecutor.execute(new DsfRunnable() {
public void run() {
IProcesses procService = fTracker.getService(IProcesses.class);
if (procService != null) {
procService.terminate(processDmc, new RequestMonitor(ImmediateExecutor.getInstance(), null) {
@Override
protected void handleCompleted() {
request.setStatus(getStatus());
request.done();
};
});
} else {
request.done();
}
}
});
} catch (RejectedExecutionException e) {
request.done();
}
return false;
}
}