Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java63
1 files changed, 37 insertions, 26 deletions
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 d9e21806a10..c3e8e72c849 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
@@ -88,6 +88,7 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
private Properties fEnvVariables;
private SessionType fSessionType;
private Boolean fAttach;
+ private State fBackendState = State.NOT_INITIALIZED;
/**
* Unique ID of this service instance.
@@ -446,13 +447,7 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
}
public State getState() {
- if (fMonitorJob == null) {
- return State.NOT_INITIALIZED;
- } else if (fMonitorJob.fExited) {
- return State.TERMINATED;
- } else {
- return State.STARTED;
- }
+ return fBackendState;
}
public int getExitCode() {
@@ -519,6 +514,9 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
try {
fProcess = launchGDBProcess(commandLine);
+ fBackendState = State.STARTED;
+ // Don't send the backendStarted event yet. We wait until we have registered this service
+ // so that other services can have access to it.
} catch(CoreException e) {
gdbLaunchRequestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, e.getMessage(), e));
gdbLaunchRequestMonitor.done();
@@ -572,7 +570,17 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
@Override
protected IStatus run(IProgressMonitor monitor) {
- destroy();
+ if (GDBBackend.this.getState() == State.STARTED) {
+ // If we get here, our monitoring thread has been cleaned up already,
+ // but GDB is running. We have to terminate GDB and send
+ // the proper event.
+ assert fMonitorJob.fMonitorExited == true;
+ destroy();
+ fBackendState = State.TERMINATED;
+ getSession().dispatchEvent(
+ new BackendStateChangedEvent(getSession().getId(), getId(), State.TERMINATED),
+ getProperties());
+ }
int attempts = 0;
while (attempts < 10) {
@@ -616,8 +624,8 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
@Override
protected void shutdown(RequestMonitor requestMonitor) {
- if (!fMonitorJob.fExited) {
- fMonitorJob.kill();
+ if (fMonitorJob != null) {
+ fMonitorJob.kill();
}
requestMonitor.done();
}
@@ -639,9 +647,12 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
* the GDBControlInitializedDMEvent that's used to indicate that GDB
* back end is ready for MI commands. But we still fire the event as
* it does no harm and may be needed sometime.... 09/29/2008
+ *
+ * We send the event in the register step because that is when
+ * other services have access to it.
*/
getSession().dispatchEvent(
- new BackendStateChangedEvent(getSession().getId(), getId(), IMIBackend.State.STARTED),
+ new BackendStateChangedEvent(getSession().getId(), getId(), State.STARTED),
getProperties());
requestMonitor.done();
@@ -660,7 +671,7 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
* then notifies the associated runtime process.
*/
private class MonitorJob extends Job {
- boolean fExited = false;
+ boolean fMonitorExited = false;
DsfRunnable fMonitorStarted;
Process fMonProcess;
@@ -668,20 +679,20 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
protected IStatus run(IProgressMonitor monitor) {
synchronized(fMonProcess) {
getExecutor().submit(fMonitorStarted);
- while (!fExited) {
- try {
- fMonProcess.waitFor();
- fGDBExitValue = fMonProcess.exitValue();
- } catch (InterruptedException ie) {
- // clear interrupted state
- Thread.interrupted();
- } finally {
- fExited = true;
- getSession().dispatchEvent(
- new BackendStateChangedEvent(getSession().getId(), getId(), IMIBackend.State.TERMINATED),
- getProperties());
- }
+ try {
+ fMonProcess.waitFor();
+ fGDBExitValue = fMonProcess.exitValue();
+
+ fBackendState = State.TERMINATED;
+ getSession().dispatchEvent(
+ new BackendStateChangedEvent(getSession().getId(), getId(), State.TERMINATED),
+ getProperties());
+ } catch (InterruptedException ie) {
+ // clear interrupted state
+ Thread.interrupted();
}
+
+ fMonitorExited = true;
}
return Status.OK_STATUS;
}
@@ -695,7 +706,7 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
void kill() {
synchronized(fMonProcess) {
- if (!fExited) {
+ if (!fMonitorExited) {
getThread().interrupt();
}
}

Back to the top