1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-27 02:45:32 +02:00

[247010] - Added a guard to avoid re-creating an adapter session after it's been disposed.

This commit is contained in:
Pawel Piech 2008-09-12 20:40:16 +00:00
parent 66960d32ba
commit 1d08e1c884
2 changed files with 57 additions and 5 deletions

View file

@ -13,6 +13,7 @@ package org.eclipse.dd.examples.pda.ui;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.WeakHashMap;
import org.eclipse.core.runtime.IAdapterFactory; import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.concurrent.Immutable;
@ -135,7 +136,7 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
// and debug model ID will be associated with all DMContexts from this // and debug model ID will be associated with all DMContexts from this
// session. // session.
session.registerModelAdapter(ILaunch.class, fLaunch); session.registerModelAdapter(ILaunch.class, fLaunch);
} }
void dispose() { void dispose() {
DsfSession session = fLaunch.getSession(); DsfSession session = fLaunch.getSession();
@ -165,13 +166,33 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
} }
} }
/**
* Active adapter sets. They are accessed using the launch instance
* which owns the debug services session.
*/
private static Map<PDALaunch, LaunchAdapterSet> fgLaunchAdapterSets = private static Map<PDALaunch, LaunchAdapterSet> fgLaunchAdapterSets =
Collections.synchronizedMap(new HashMap<PDALaunch, LaunchAdapterSet>()); Collections.synchronizedMap(new HashMap<PDALaunch, LaunchAdapterSet>());
/**
* Map of launches for which adapter sets have already been disposed.
* This map (used as a set) is maintained in order to avoid re-creating an
* adapter set after the launch was removed from the launch manager, but
* while the launch is still being held by other classes which may
* request its adapters. A weak map is used to avoid leaking
* memory once the launches are no longer referenced.
* <p>
* Access to this map is synchronized using the fgLaunchAdapterSets
* instance.
* </p>
*/
private static Map<ILaunch, Object> fgDisposedLaunchAdapterSets =
new WeakHashMap<ILaunch, Object>();
static void disposeAdapterSet(ILaunch launch) { static void disposeAdapterSet(ILaunch launch) {
synchronized(fgLaunchAdapterSets) { synchronized(fgLaunchAdapterSets) {
if ( fgLaunchAdapterSets.containsKey(launch) ) { if ( fgLaunchAdapterSets.containsKey(launch) ) {
fgLaunchAdapterSets.remove(launch).dispose(); fgLaunchAdapterSets.remove(launch).dispose();
fgDisposedLaunchAdapterSets.put(launch, null);
} }
} }
} }
@ -199,6 +220,11 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
// new set of adapters. // new set of adapters.
LaunchAdapterSet adapterSet; LaunchAdapterSet adapterSet;
synchronized(fgLaunchAdapterSets) { synchronized(fgLaunchAdapterSets) {
// The adapter set for the given launch was already disposed.
// Return a null adapter.
if (fgDisposedLaunchAdapterSets.containsKey(launch)) {
return null;
}
adapterSet = fgLaunchAdapterSets.get(launch); adapterSet = fgLaunchAdapterSets.get(launch);
if (adapterSet == null) { if (adapterSet == null) {
adapterSet = new LaunchAdapterSet(launch); adapterSet = new LaunchAdapterSet(launch);

View file

@ -13,6 +13,7 @@ package org.eclipse.dd.gdb.internal.ui;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.WeakHashMap;
import org.eclipse.cdt.debug.core.model.IRestart; import org.eclipse.cdt.debug.core.model.IRestart;
import org.eclipse.cdt.debug.core.model.ISteppingModeTarget; import org.eclipse.cdt.debug.core.model.ISteppingModeTarget;
@ -184,13 +185,33 @@ public class GdbAdapterFactory
} }
/**
* Active adapter sets. They are accessed using the launch instance
* which owns the debug services session.
*/
private static Map<GdbLaunch, SessionAdapterSet> fgLaunchAdapterSets = private static Map<GdbLaunch, SessionAdapterSet> fgLaunchAdapterSets =
Collections.synchronizedMap(new HashMap<GdbLaunch, SessionAdapterSet>()); Collections.synchronizedMap(new HashMap<GdbLaunch, SessionAdapterSet>());
/**
* Map of launches for which adapter sets have already been disposed.
* This map (used as a set) is maintained in order to avoid re-creating an
* adapter set after the launch was removed from the launch manager, but
* while the launch is still being held by other classes which may
* request its adapters. A weak map is used to avoid leaking
* memory once the launches are no longer referenced.
* <p>
* Access to this map is synchronized using the fgLaunchAdapterSets
* instance.
* </p>
*/
private static Map<ILaunch, SessionAdapterSet> fgDisposedLaunchAdapterSets =
new WeakHashMap<ILaunch, SessionAdapterSet>();
static void disposeAdapterSet(ILaunch launch) { static void disposeAdapterSet(ILaunch launch) {
synchronized(fgLaunchAdapterSets) { synchronized(fgLaunchAdapterSets) {
if ( fgLaunchAdapterSets.containsKey(launch) ) { if ( fgLaunchAdapterSets.containsKey(launch) ) {
fgLaunchAdapterSets.remove(launch).dispose(); fgLaunchAdapterSets.remove(launch).dispose();
fgDisposedLaunchAdapterSets.put(launch, null);
} }
} }
} }
@ -221,6 +242,11 @@ public class GdbAdapterFactory
SessionAdapterSet adapterSet; SessionAdapterSet adapterSet;
synchronized(fgLaunchAdapterSets) { synchronized(fgLaunchAdapterSets) {
// The adapter set for the given launch was already disposed.
// Return a null adapter.
if (fgDisposedLaunchAdapterSets.containsKey(launch)) {
return null;
}
adapterSet = fgLaunchAdapterSets.get(launch); adapterSet = fgLaunchAdapterSets.get(launch);
if (adapterSet == null) { if (adapterSet == null) {
adapterSet = new SessionAdapterSet(launch); adapterSet = new SessionAdapterSet(launch);