Skip to content

Fix race condition in ImageHandleManager with ConcurrentHashMap#26

Draft
Copilot wants to merge 4 commits intomasterfrom
copilot/add-race-condition-testcase
Draft

Fix race condition in ImageHandleManager with ConcurrentHashMap#26
Copilot wants to merge 4 commits intomasterfrom
copilot/add-race-condition-testcase

Conversation

Copy link
Copy Markdown

Copilot AI commented Jan 13, 2026

Multiple threads concurrently accessing ImageHandleManager.getOrCreate() for the same zoom level could create duplicate handles, causing resource leaks and wasted CPU/memory. The non-thread-safe HashMap allowed this race:

// Thread A: get(150) → null, creates H1, put(150, H1)
// Thread B: get(150) → null, creates H2, put(150, H2)  // H1 leaked

Changes

ImageHandleManager (Image.java)

  • HashMapConcurrentHashMap for thread-safe handle storage
  • getOrCreate(): manual check-create-put → atomic computeIfAbsent()
  • Removes redundant remove() call in destroyHandles()

ImageData caching

  • HashMapConcurrentHashMap in ImageFromImageDataProviderWrapper and BaseImageProviderWrapper
  • Already used computeIfAbsent(), now properly thread-safe

Implementation

// Before: 10+ lines, race-prone
DestroyableImageHandle imageHandle = (DestroyableImageHandle) get(zoom);
if (imageHandle != null) return imageHandle;
imageHandle = creator.get();
zoomLevelToImageHandle.put(zoom, imageHandle);
return imageHandle;

// After: atomic, 1 line
return zoomLevelToImageHandle.computeIfAbsent(zoom, k -> creator.get());

Testing

Snippet_ImageHandleRaceCondition.java: Demonstrates race condition with 20 threads × 100 iterations, tracks duplicate creation

test_ConcurrentImageHandleAccess(): JUnit test verifying exactly 1 handle created per zoom under concurrent access (10 threads × 50 iterations)

Rationale

ConcurrentHashMap chosen over double-checked locking for simplicity, correctness, and lock-free read performance. A unified caching structure was considered but deferred as it requires architectural refactoring beyond immediate thread-safety needs.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • www.eclipse.org
    • Triggering command: /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/21.0.9-10/x64/bin/java /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/21.0.9-10/x64/bin/java --enable-native-access=ALL-UNNAMED -classpath /opt/hostedtoolcache/maven/3.9.12/x64/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/opt/hostedtoolcache/maven/3.9.12/x64/bin/m2.conf -Dmaven.home=/opt/hostedtoolcache/maven/3.9.12/x64 -Dlibrary.jansi.path=/opt/hostedtoolcache/maven/3.9.12/x64/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/REDACTED/work/eclipse.platform.swt/eclipse.platform.swt org.codehaus.plexus.classworlds.launcher.Launcher clean compile -DskipTests -pl bundles/org.eclipse.swt -am (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

The comment here eclipse-platform#2905 (comment) describes a possible scenario for a race condition.

I would need a testcase tha replicates the described scenario (e.g. with modify the code with some barriers we can use in a snippet). Also there needs to be an analysisy if the PR actually fixes the problem and double-checked locking is a good aproach or if it wont work with a ConcurrentMap maybe better. We should also consider different aproach where instead of the two maps we just merge both maps into using a special datastructure that can handle both cases. This seems a much better way forward to me.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 3 commits January 13, 2026 08:14
- Replace HashMap with ConcurrentHashMap in ImageHandleManager
- Use computeIfAbsent() for thread-safe getOrCreate()
- Fix similar race conditions in cachedImageData maps in provider wrappers
- Add test snippet to demonstrate the race condition scenario

Co-authored-by: laeubi <1331477+laeubi@users.noreply.github.com>
- Test verifies no race conditions with multiple threads
- Ensures exactly one handle created per zoom level
- Includes proper error handling and timeout
- Validates the ConcurrentHashMap fix

Co-authored-by: laeubi <1331477+laeubi@users.noreply.github.com>
- Remove redundant remove() call in destroyHandles()
- Use public getImageData() API instead of internal win32_getHandle() in snippet
- Build verification passed

Co-authored-by: laeubi <1331477+laeubi@users.noreply.github.com>
Copilot AI changed the title [WIP] Add testcase for race condition scenario in SWT Fix race condition in ImageHandleManager with ConcurrentHashMap Jan 13, 2026
Copilot AI requested a review from laeubi January 13, 2026 08:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants