mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Prevent CME in LaunchBarManager
This change synchronizes access to LaunchBarManager.descriptors, to avoid a ConcurrentModificationException when adding descriptors for 2 launches at the same time. Fixes: #262
This commit is contained in:
parent
c973dd5e80
commit
5bb96b2f88
2 changed files with 41 additions and 15 deletions
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
||||||
Bundle-ManifestVersion: 2
|
Bundle-ManifestVersion: 2
|
||||||
Bundle-Name: %pluginName
|
Bundle-Name: %pluginName
|
||||||
Bundle-SymbolicName: org.eclipse.launchbar.core;singleton:=true
|
Bundle-SymbolicName: org.eclipse.launchbar.core;singleton:=true
|
||||||
Bundle-Version: 2.5.0.qualifier
|
Bundle-Version: 2.5.100.qualifier
|
||||||
Bundle-Activator: org.eclipse.launchbar.core.internal.Activator
|
Bundle-Activator: org.eclipse.launchbar.core.internal.Activator
|
||||||
Bundle-Vendor: %providerName
|
Bundle-Vendor: %providerName
|
||||||
Require-Bundle: org.eclipse.core.runtime,
|
Require-Bundle: org.eclipse.core.runtime,
|
||||||
|
|
|
@ -140,11 +140,13 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchTargetListene
|
||||||
ILaunchDescriptor last = null;
|
ILaunchDescriptor last = null;
|
||||||
for (String id : split) {
|
for (String id : split) {
|
||||||
Pair<String, String> key = toId(id);
|
Pair<String, String> key = toId(id);
|
||||||
ILaunchDescriptor desc = descriptors.get(key);
|
synchronized (descriptors) {
|
||||||
if (desc != null) {
|
ILaunchDescriptor desc = descriptors.get(key);
|
||||||
descriptors.remove(key);
|
if (desc != null) {
|
||||||
descriptors.put(key, desc);
|
descriptors.remove(key);
|
||||||
last = desc;
|
descriptors.put(key, desc);
|
||||||
|
last = desc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Set the active desc, with MRU, it should be the last one
|
// Set the active desc, with MRU, it should be the last one
|
||||||
|
@ -304,7 +306,10 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchTargetListene
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addDescriptor(Object launchObject, ILaunchDescriptor descriptor) throws CoreException {
|
private void addDescriptor(Object launchObject, ILaunchDescriptor descriptor) throws CoreException {
|
||||||
descriptors.put(getDescriptorId(descriptor), descriptor);
|
Pair<String, String> descriptorId = getDescriptorId(descriptor);
|
||||||
|
synchronized (descriptors) {
|
||||||
|
descriptors.put(descriptorId, descriptor);
|
||||||
|
}
|
||||||
objectDescriptorMap.put(launchObject, descriptor);
|
objectDescriptorMap.put(launchObject, descriptor);
|
||||||
setActiveLaunchDescriptor(descriptor);
|
setActiveLaunchDescriptor(descriptor);
|
||||||
}
|
}
|
||||||
|
@ -371,7 +376,10 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchTargetListene
|
||||||
Activator.trace("launch object removed " + launchObject); //$NON-NLS-1$
|
Activator.trace("launch object removed " + launchObject); //$NON-NLS-1$
|
||||||
ILaunchDescriptor descriptor = objectDescriptorMap.remove(launchObject);
|
ILaunchDescriptor descriptor = objectDescriptorMap.remove(launchObject);
|
||||||
if (descriptor != null) {
|
if (descriptor != null) {
|
||||||
descriptors.remove(getDescriptorId(descriptor));
|
Pair<String, String> descriptorId = getDescriptorId(descriptor);
|
||||||
|
synchronized (descriptors) {
|
||||||
|
descriptors.remove(descriptorId);
|
||||||
|
}
|
||||||
if (descriptor.equals(activeLaunchDesc)) {
|
if (descriptor.equals(activeLaunchDesc)) {
|
||||||
setActiveLaunchDescriptor(getLastUsedDescriptor());
|
setActiveLaunchDescriptor(getLastUsedDescriptor());
|
||||||
}
|
}
|
||||||
|
@ -413,7 +421,10 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchTargetListene
|
||||||
private ILaunchDescriptor getLastUsedDescriptor() {
|
private ILaunchDescriptor getLastUsedDescriptor() {
|
||||||
if (descriptors.size() == 0)
|
if (descriptors.size() == 0)
|
||||||
return null;
|
return null;
|
||||||
ILaunchDescriptor[] descs = descriptors.values().toArray(new ILaunchDescriptor[descriptors.size()]);
|
ILaunchDescriptor[] descs;
|
||||||
|
synchronized (descriptors) {
|
||||||
|
descs = descriptors.values().toArray(new ILaunchDescriptor[descriptors.size()]);
|
||||||
|
}
|
||||||
return descs[descs.length - 1];
|
return descs[descs.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,7 +432,10 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchTargetListene
|
||||||
public ILaunchDescriptor[] getLaunchDescriptors() {
|
public ILaunchDescriptor[] getLaunchDescriptors() {
|
||||||
// return descriptor in usage order (most used first). UI can sort them
|
// return descriptor in usage order (most used first). UI can sort them
|
||||||
// later as it wishes
|
// later as it wishes
|
||||||
ArrayList<ILaunchDescriptor> values = new ArrayList<>(descriptors.values());
|
ArrayList<ILaunchDescriptor> values = new ArrayList<>();
|
||||||
|
synchronized (descriptors) {
|
||||||
|
values.addAll(descriptors.values());
|
||||||
|
}
|
||||||
Collections.reverse(values);
|
Collections.reverse(values);
|
||||||
return values.toArray(new ILaunchDescriptor[values.size()]);
|
return values.toArray(new ILaunchDescriptor[values.size()]);
|
||||||
}
|
}
|
||||||
|
@ -475,8 +489,14 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchTargetListene
|
||||||
Activator.trace("resync for " + descriptor); //$NON-NLS-1$
|
Activator.trace("resync for " + descriptor); //$NON-NLS-1$
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (descriptor != null && !descriptors.containsValue(descriptor)) {
|
if (descriptor != null) {
|
||||||
throw new IllegalStateException(Messages.LaunchBarManager_1);
|
boolean isContained;
|
||||||
|
synchronized (descriptors) {
|
||||||
|
isContained = descriptors.containsValue(descriptor);
|
||||||
|
}
|
||||||
|
if (!isContained) {
|
||||||
|
throw new IllegalStateException(Messages.LaunchBarManager_1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (descriptor == null) {
|
if (descriptor == null) {
|
||||||
// do not set to null unless no descriptors
|
// do not set to null unless no descriptors
|
||||||
|
@ -498,8 +518,10 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchTargetListene
|
||||||
if (descriptor != null) {
|
if (descriptor != null) {
|
||||||
// keeps most used descriptor last
|
// keeps most used descriptor last
|
||||||
Pair<String, String> id = getDescriptorId(descriptor);
|
Pair<String, String> id = getDescriptorId(descriptor);
|
||||||
descriptors.remove(id);
|
synchronized (descriptors) {
|
||||||
descriptors.put(id, descriptor);
|
descriptors.remove(id);
|
||||||
|
descriptors.put(id, descriptor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,7 +530,11 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchTargetListene
|
||||||
// Store the desc order, active one is the last one
|
// Store the desc order, active one is the last one
|
||||||
StringBuffer buff = new StringBuffer();
|
StringBuffer buff = new StringBuffer();
|
||||||
// TODO: this can be very long string
|
// TODO: this can be very long string
|
||||||
for (Pair<String, String> key : descriptors.keySet()) {
|
ArrayList<Pair<String, String>> keys = new ArrayList<>();
|
||||||
|
synchronized (descriptors) {
|
||||||
|
keys.addAll(descriptors.keySet());
|
||||||
|
}
|
||||||
|
for (Pair<String, String> key : keys) {
|
||||||
if (buff.length() > 0) {
|
if (buff.length() > 0) {
|
||||||
buff.append(',');
|
buff.append(',');
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue