diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java index 449efeebd62..cd116a0eded 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java @@ -377,11 +377,11 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend { /** * @since 3.0 */ - public void interrupt(final RequestMonitor rm) { + public void interruptAndWait(int timeout, RequestMonitor rm) { if (fProcess instanceof Spawner) { Spawner gdbSpawner = (Spawner) fProcess; gdbSpawner.interrupt(); - fInterruptFailedJob = new MonitorInterruptJob(rm); + fInterruptFailedJob = new MonitorInterruptJob(timeout, rm); } else { rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Cannot interrupt.", null)); //$NON-NLS-1$ rm.done(); @@ -653,17 +653,34 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend { } /** - * Monitors an ongoing interrupt to be able to properly - * deal with the request monitor. + * Stores the request monitor that must be dealt with for + * the result of the interrupt operation. If the interrupt + * successfully suspends the backend, the request monitor can + * be retrieved and completed successfully, and then this job + * should be canceled. If this job is not canceled before + * the time is up, it will imply the interrupt did not + * successfully suspend the backend, and the current job will + * indicate this in the request monitor. + * + * The specified timeout is used to indicate how many milliseconds + * this job should wait for. INTERRUPT_TIMEOUT_DEFAULT indicates + * to use the default of 500 ms. The default is also use if the + * timeout value is 0 or negative. */ private class MonitorInterruptJob extends Job { + private final static int TIMEOUT_DEFAULT_VALUE = 500; private final RequestMonitor fRequestMonitor; - public MonitorInterruptJob(RequestMonitor rm) { + public MonitorInterruptJob(int timeout, RequestMonitor rm) { super("Interrupt monitor job."); setSystem(true); fRequestMonitor = rm; - schedule(5000); // Give the interrupt 5 seconds to succeed + + if (timeout == INTERRUPT_TIMEOUT_DEFAULT || timeout <= 0) { + timeout = TIMEOUT_DEFAULT_VALUE; // default of 0.5 seconds + } + + schedule(timeout); } @Override diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl.java index 0ee263647ce..78227362922 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl.java @@ -138,7 +138,7 @@ public class GDBRunControl extends MIRunControl { @Override protected void handleSuccess() { if (getData()) { - fGdb.interrupt(rm); + fGdb.interruptAndWait(IGDBBackend.INTERRUPT_TIMEOUT_DEFAULT, rm); } else { rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Context cannot be suspended.", null)); //$NON-NLS-1$ rm.done(); diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_0.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_0.java index ec7d521857d..867b1a181c7 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_0.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_0.java @@ -144,7 +144,7 @@ public class GDBRunControl_7_0 extends MIRunControl implements IReverseRunContro @Override protected void handleSuccess() { if (getData()) { - fGdb.interrupt(rm); + fGdb.interruptAndWait(IGDBBackend.INTERRUPT_TIMEOUT_DEFAULT, rm); } else { rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Context cannot be suspended.", null)); //$NON-NLS-1$ rm.done(); diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBBackend.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBBackend.java index 970f0a65724..84edfbe44b0 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBBackend.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBBackend.java @@ -40,6 +40,12 @@ import org.eclipse.core.runtime.IPath; */ public interface IGDBBackend extends IMIBackend { + /** + * ID to use when requesting that the interruptAndWait call wait for an + * implementation-specific default. + * @since 3.0 */ + public final static int INTERRUPT_TIMEOUT_DEFAULT = 0; + /** * Get path of the debugged program on host. * @@ -101,16 +107,22 @@ public interface IGDBBackend extends IMIBackend { * Sends an interrupt signal to the GDB process. */ public void interrupt(); - + /** - * Interrupts the backend. - * The request monitor indicates if the interrupt succeeded or not; - * it may or may not indicate that the backend is already interrupted, - * but does indicate if the backend will become interrupted. + * Interrupts the backend and wait to confirm the interrupt + * succeeded. The request monitor indicates to the caller if + * the interrupt succeeded or not. * + * @param timeout Maximum number of milliseconds to wait to confirm + * that the backend has been interrupted. A value + * of INTERRUPT_TIMEOUT_DEFAULT specifies to use an + * implementation-specific default value. + * Using a value of 0 or a negative value has unspecified + * behavior. + * * @since 3.0 */ - public void interrupt(RequestMonitor rm); + public void interruptAndWait(int timeout, RequestMonitor rm); /** * @return The type of the session currently ongoing with the backend