Make ExecutionEnvironment thread safe#867
Conversation
There was a problem hiding this comment.
Pull request overview
This PR makes the ExecutionEnvironment class thread-safe to fix a ConcurrentModificationException reported in issue #865. The changes address race conditions by introducing synchronized blocks, concurrent collections, and volatile fields to protect shared mutable state accessed by multiple threads.
Changes:
- Replaced standard collections with thread-safe alternatives:
ConcurrentHashMap.newKeySet()forfStrictlyCompatibleandCopyOnWriteArrayListforfCompatibleVMs - Added
synchronized(this)blocks to protect compound operations on shared state (maps, lists, caches) - Made lazy-initialized fields
volatile(fPropertiesInitialized,fDefault,fParticipants) to support safe double-checked locking - Removed obsolete Javadoc comments and redundant field initialization
Comments suppressed due to low confidence (1)
org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/environments/ExecutionEnvironment.java:295
- The check at line 289 (fCompatibleVMs.contains(vm)) occurs outside of synchronization, but fCompatibleVMs is a CopyOnWriteArrayList which can be modified concurrently by add() and remove() methods. While CopyOnWriteArrayList is thread-safe for its operations, this creates a time-of-check-time-of-use (TOCTOU) race condition: the VM could be removed from fCompatibleVMs between the contains() check and when fDefault is set (line 295), allowing an incompatible VM to become the default. Consider moving the contains() check inside a synchronized block or using the volatile fDefault with proper synchronization.
public void setDefaultVM(IVMInstall vm) {
init();
if (vm != null && !fCompatibleVMs.contains(vm)) {
throw new IllegalArgumentException(NLS.bind(EnvironmentMessages.EnvironmentsManager_0, getId()));
}
if (vm != null && vm.equals(fDefault)) {
return;
}
fDefault = vm;
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
...aunching/launching/org/eclipse/jdt/internal/launching/environments/ExecutionEnvironment.java
Show resolved
Hide resolved
...aunching/launching/org/eclipse/jdt/internal/launching/environments/ExecutionEnvironment.java
Show resolved
Hide resolved
...aunching/launching/org/eclipse/jdt/internal/launching/environments/ExecutionEnvironment.java
Show resolved
Hide resolved
...aunching/launching/org/eclipse/jdt/internal/launching/environments/ExecutionEnvironment.java
Outdated
Show resolved
Hide resolved
03702de to
f283dc6
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- removed non javadoc comments - removed default init from fields
- replaced method level lock on getParticipants() with inner lock with smaller scope - guard all (cross connected) maps & fields etc write access with the lock on EE - made some maps concurrent where read access was required outside the lock - made fields volatile where needed Fixes eclipse-jdt#865
f283dc6 to
c22bd67
Compare
|
This pull request changes some projects for the first time in this development cycle. An additional commit containing all the necessary changes was pushed to the top of this PR's branch. To obtain these changes (for example if you want to push more changes) either fetch from your fork or apply the git patch. Git patchFurther information are available in Common Build Issues - Missing version increments. |
Beside this, some cleanup in extra commit to get rid of useless code.
Fixes #865