|
Lines 10-15
Link Here
|
| 10 |
* Ericsson - Modified for handling of multiple stacks and threads |
10 |
* Ericsson - Modified for handling of multiple stacks and threads |
| 11 |
* Nokia - create and use backend service. |
11 |
* Nokia - create and use backend service. |
| 12 |
* Onur Akdemir (TUBITAK BILGEM-ITI) - Multi-process debugging (Bug 237306) |
12 |
* Onur Akdemir (TUBITAK BILGEM-ITI) - Multi-process debugging (Bug 237306) |
|
|
13 |
* Mohamed Hussein (Mentor Graphics) - Add timeout for gdb commands (Bug 361934) |
| 13 |
*******************************************************************************/ |
14 |
*******************************************************************************/ |
| 14 |
package org.eclipse.cdt.dsf.mi.service.command; |
15 |
package org.eclipse.cdt.dsf.mi.service.command; |
| 15 |
|
16 |
|
|
Lines 25-35
Link Here
|
| 25 |
import java.util.List; |
26 |
import java.util.List; |
| 26 |
import java.util.Map; |
27 |
import java.util.Map; |
| 27 |
import java.util.concurrent.BlockingQueue; |
28 |
import java.util.concurrent.BlockingQueue; |
|
|
29 |
import java.util.concurrent.Callable; |
| 30 |
import java.util.concurrent.Executors; |
| 28 |
import java.util.concurrent.LinkedBlockingQueue; |
31 |
import java.util.concurrent.LinkedBlockingQueue; |
| 29 |
import java.util.concurrent.RejectedExecutionException; |
32 |
import java.util.concurrent.RejectedExecutionException; |
|
|
33 |
import java.util.concurrent.ScheduledExecutorService; |
| 34 |
import java.util.concurrent.ScheduledFuture; |
| 35 |
import java.util.concurrent.TimeUnit; |
| 30 |
|
36 |
|
| 31 |
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; |
37 |
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; |
| 32 |
import org.eclipse.cdt.dsf.concurrent.DsfRunnable; |
38 |
import org.eclipse.cdt.dsf.concurrent.DsfRunnable; |
|
|
39 |
import org.eclipse.cdt.dsf.concurrent.RequestMonitor; |
| 33 |
import org.eclipse.cdt.dsf.datamodel.DMContexts; |
40 |
import org.eclipse.cdt.dsf.datamodel.DMContexts; |
| 34 |
import org.eclipse.cdt.dsf.datamodel.IDMContext; |
41 |
import org.eclipse.cdt.dsf.datamodel.IDMContext; |
| 35 |
import org.eclipse.cdt.dsf.debug.service.IRunControl; |
42 |
import org.eclipse.cdt.dsf.debug.service.IRunControl; |
|
Lines 39-44
Link Here
|
| 39 |
import org.eclipse.cdt.dsf.debug.service.command.ICommandResult; |
46 |
import org.eclipse.cdt.dsf.debug.service.command.ICommandResult; |
| 40 |
import org.eclipse.cdt.dsf.debug.service.command.ICommandToken; |
47 |
import org.eclipse.cdt.dsf.debug.service.command.ICommandToken; |
| 41 |
import org.eclipse.cdt.dsf.debug.service.command.IEventListener; |
48 |
import org.eclipse.cdt.dsf.debug.service.command.IEventListener; |
|
|
49 |
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants; |
| 42 |
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; |
50 |
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; |
| 43 |
import org.eclipse.cdt.dsf.gdb.service.GDBBackend; |
51 |
import org.eclipse.cdt.dsf.gdb.service.GDBBackend; |
| 44 |
import org.eclipse.cdt.dsf.mi.service.IMICommandControl; |
52 |
import org.eclipse.cdt.dsf.mi.service.IMICommandControl; |
|
Lines 59-64
Link Here
|
| 59 |
import org.eclipse.cdt.dsf.service.AbstractDsfService; |
67 |
import org.eclipse.cdt.dsf.service.AbstractDsfService; |
| 60 |
import org.eclipse.cdt.dsf.service.DsfSession; |
68 |
import org.eclipse.cdt.dsf.service.DsfSession; |
| 61 |
import org.eclipse.core.runtime.IStatus; |
69 |
import org.eclipse.core.runtime.IStatus; |
|
|
70 |
import org.eclipse.core.runtime.Platform; |
| 62 |
import org.eclipse.core.runtime.Status; |
71 |
import org.eclipse.core.runtime.Status; |
| 63 |
|
72 |
|
| 64 |
import com.ibm.icu.text.MessageFormat; |
73 |
import com.ibm.icu.text.MessageFormat; |
|
Lines 72-77
Link Here
|
| 72 |
public abstract class AbstractMIControl extends AbstractDsfService |
81 |
public abstract class AbstractMIControl extends AbstractDsfService |
| 73 |
implements IMICommandControl |
82 |
implements IMICommandControl |
| 74 |
{ |
83 |
{ |
|
|
84 |
/** |
| 85 |
* Maximum number of gdb commands allowed to be on the wire at the same time. |
| 86 |
* @since 4.1 |
| 87 |
*/ |
| 88 |
protected static final int NUM_OF_PARALLEL_COMMANDS = 3; |
| 89 |
|
| 75 |
private static final String MI_TRACE_IDENTIFIER = " [MI] "; //$NON-NLS-1$ |
90 |
private static final String MI_TRACE_IDENTIFIER = " [MI] "; //$NON-NLS-1$ |
| 76 |
|
91 |
|
| 77 |
/* |
92 |
/* |
|
Lines 160-166
Link Here
|
| 160 |
fCommandFactory = factory; |
175 |
fCommandFactory = factory; |
| 161 |
} |
176 |
} |
| 162 |
|
177 |
|
| 163 |
/** |
178 |
@Override |
|
|
179 |
public void initialize(RequestMonitor rm) { |
| 180 |
super.initialize(rm); |
| 181 |
addTimeOutCommandListener(rm); |
| 182 |
} |
| 183 |
|
| 184 |
/** |
| 185 |
* Adds a timeout listener for gdb commands if the preference requires it. |
| 186 |
* @see IGdbDebugPreferenceConstants#PREF_COMMAND_TIMEOUT_ENABLE |
| 187 |
* @since 4.1 |
| 188 |
*/ |
| 189 |
protected void addTimeOutCommandListener(final RequestMonitor requestMonitor) { |
| 190 |
if (Platform.getPreferencesService().getBoolean(GdbPlugin.PLUGIN_ID, |
| 191 |
IGdbDebugPreferenceConstants.PREF_COMMAND_TIMEOUT_ENABLE, true, null)) { |
| 192 |
addCommandListener(new TimeOutCommandListener(requestMonitor)); |
| 193 |
} |
| 194 |
} |
| 195 |
|
| 196 |
/** |
| 197 |
* A Timeout command listener that will shutdown the gdb connection if any of the gdb commands timed out. |
| 198 |
* @see IGdbDebugPreferenceConstants#PREF_DEFAULT_COMMAND_TIMEOUT |
| 199 |
* @author mhussein |
| 200 |
*/ |
| 201 |
private class TimeOutCommandListener implements ICommandListener { |
| 202 |
private ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(NUM_OF_PARALLEL_COMMANDS); |
| 203 |
|
| 204 |
private Map<ICommandToken, ScheduledFuture<?>> commands = new HashMap<ICommandToken, ScheduledFuture<?>>(NUM_OF_PARALLEL_COMMANDS); |
| 205 |
private int timeout; |
| 206 |
private final RequestMonitor rm; |
| 207 |
|
| 208 |
public TimeOutCommandListener(RequestMonitor rm) { |
| 209 |
this.rm = rm; |
| 210 |
timeout = Platform.getPreferencesService().getInt(GdbPlugin.PLUGIN_ID, IGdbDebugPreferenceConstants.PREF_DEFAULT_COMMAND_TIMEOUT, 30, null); |
| 211 |
} |
| 212 |
@Override |
| 213 |
public void commandQueued(ICommandToken token) {} |
| 214 |
@Override |
| 215 |
public void commandRemoved(ICommandToken token) {} |
| 216 |
|
| 217 |
@Override |
| 218 |
public void commandSent(final ICommandToken token) { |
| 219 |
ScheduledFuture<?> task = scheduler.schedule(new Callable<Object>() { |
| 220 |
@Override |
| 221 |
public Object call() { |
| 222 |
shutdown(rm); |
| 223 |
return null; |
| 224 |
} |
| 225 |
}, timeout, TimeUnit.SECONDS); |
| 226 |
commands.put(token, task); |
| 227 |
} |
| 228 |
|
| 229 |
@Override |
| 230 |
public void commandDone(ICommandToken token, ICommandResult result) { |
| 231 |
if (commands.containsKey(token)) { |
| 232 |
ScheduledFuture<?> task = commands.remove(token); |
| 233 |
task.cancel(true); |
| 234 |
} |
| 235 |
} |
| 236 |
} |
| 237 |
|
| 238 |
/** |
| 164 |
* Set the tracing stream for the MI communication. If this method is never |
239 |
* Set the tracing stream for the MI communication. If this method is never |
| 165 |
* called, tracing will be off, by default. |
240 |
* called, tracing will be off, by default. |
| 166 |
* |
241 |
* |
|
Lines 319-325
Link Here
|
| 319 |
fCommandQueue.add(handle); |
394 |
fCommandQueue.add(handle); |
| 320 |
processCommandQueued(handle); |
395 |
processCommandQueued(handle); |
| 321 |
|
396 |
|
| 322 |
if (fRxCommands.size() < 3) { |
397 |
if (fRxCommands.size() < NUM_OF_PARALLEL_COMMANDS) { |
| 323 |
// In a separate dispatch cycle. This allows command listeners |
398 |
// In a separate dispatch cycle. This allows command listeners |
| 324 |
// to respond to the command queued event. |
399 |
// to respond to the command queued event. |
| 325 |
getExecutor().execute(new DsfRunnable() { |
400 |
getExecutor().execute(new DsfRunnable() { |