1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-03-28 14:56:28 +01: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:
Simeon Andreev 2023-01-27 13:30:53 +01:00 committed by Jonah Graham
parent c973dd5e80
commit 5bb96b2f88
2 changed files with 41 additions and 15 deletions

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
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-Vendor: %providerName
Require-Bundle: org.eclipse.core.runtime,

View file

@ -140,11 +140,13 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchTargetListene
ILaunchDescriptor last = null;
for (String id : split) {
Pair<String, String> key = toId(id);
ILaunchDescriptor desc = descriptors.get(key);
if (desc != null) {
descriptors.remove(key);
descriptors.put(key, desc);
last = desc;
synchronized (descriptors) {
ILaunchDescriptor desc = descriptors.get(key);
if (desc != null) {
descriptors.remove(key);
descriptors.put(key, desc);
last = desc;
}
}
}
// 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 {
descriptors.put(getDescriptorId(descriptor), descriptor);
Pair<String, String> descriptorId = getDescriptorId(descriptor);
synchronized (descriptors) {
descriptors.put(descriptorId, descriptor);
}
objectDescriptorMap.put(launchObject, descriptor);
setActiveLaunchDescriptor(descriptor);
}
@ -371,7 +376,10 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchTargetListene
Activator.trace("launch object removed " + launchObject); //$NON-NLS-1$
ILaunchDescriptor descriptor = objectDescriptorMap.remove(launchObject);
if (descriptor != null) {
descriptors.remove(getDescriptorId(descriptor));
Pair<String, String> descriptorId = getDescriptorId(descriptor);
synchronized (descriptors) {
descriptors.remove(descriptorId);
}
if (descriptor.equals(activeLaunchDesc)) {
setActiveLaunchDescriptor(getLastUsedDescriptor());
}
@ -413,7 +421,10 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchTargetListene
private ILaunchDescriptor getLastUsedDescriptor() {
if (descriptors.size() == 0)
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];
}
@ -421,7 +432,10 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchTargetListene
public ILaunchDescriptor[] getLaunchDescriptors() {
// return descriptor in usage order (most used first). UI can sort them
// 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);
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$
return;
}
if (descriptor != null && !descriptors.containsValue(descriptor)) {
throw new IllegalStateException(Messages.LaunchBarManager_1);
if (descriptor != null) {
boolean isContained;
synchronized (descriptors) {
isContained = descriptors.containsValue(descriptor);
}
if (!isContained) {
throw new IllegalStateException(Messages.LaunchBarManager_1);
}
}
if (descriptor == null) {
// do not set to null unless no descriptors
@ -498,8 +518,10 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchTargetListene
if (descriptor != null) {
// keeps most used descriptor last
Pair<String, String> id = getDescriptorId(descriptor);
descriptors.remove(id);
descriptors.put(id, descriptor);
synchronized (descriptors) {
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
StringBuffer buff = new StringBuffer();
// 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) {
buff.append(',');
}