From 1f053cd0fa7a28a40e2733eb0bc2f099f943d60c Mon Sep 17 00:00:00 2001 From: 41zu Date: Tue, 28 Oct 2025 12:25:53 +0100 Subject: [PATCH] Remove synchronisation on "Device.class", because it is deadlock prone. Information about the deadlock was posted on the RAP mailing list: https://www.eclipse.org/lists/rap-dev/msg01480.html --- .../swt/internal/widgets/DisplaysHolder.java | 30 +++++---- .../src/org/eclipse/swt/widgets/Display.java | 62 +++---------------- 2 files changed, 28 insertions(+), 64 deletions(-) diff --git a/bundles/org.eclipse.rap.rwt/src/org/eclipse/swt/internal/widgets/DisplaysHolder.java b/bundles/org.eclipse.rap.rwt/src/org/eclipse/swt/internal/widgets/DisplaysHolder.java index ac74ec87e7..f4dd45ebe6 100644 --- a/bundles/org.eclipse.rap.rwt/src/org/eclipse/swt/internal/widgets/DisplaysHolder.java +++ b/bundles/org.eclipse.rap.rwt/src/org/eclipse/swt/internal/widgets/DisplaysHolder.java @@ -12,23 +12,31 @@ package org.eclipse.swt.internal.widgets; import java.lang.ref.WeakReference; +import java.util.Collections; +import java.util.Map; +import java.util.WeakHashMap; import org.eclipse.swt.widgets.Display; -public class DisplaysHolder { - private WeakReference[] displays; - - @SuppressWarnings("unchecked") +public final class DisplaysHolder { + + private final Map> displays; + public DisplaysHolder() { - displays = new WeakReference[ 4 ]; + displays = Collections.synchronizedMap( new WeakHashMap<>() ); } - - public WeakReference[] getDisplays() { - return displays; + + public void addDisplay( Thread tread, Display display ) { + displays.put( tread, new WeakReference<>( display ) ); } - - public void setDisplays( WeakReference[] displays ) { - this.displays = displays; + + public Display getDisplay( Thread thread ) { + WeakReference wr = displays.get( thread ); + if ( wr != null ) { + return wr.get(); + } + return null; } + } diff --git a/bundles/org.eclipse.rap.rwt/src/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.rap.rwt/src/org/eclipse/swt/widgets/Display.java index aaf9df5878..10a9480663 100644 --- a/bundles/org.eclipse.rap.rwt/src/org/eclipse/swt/widgets/Display.java +++ b/bundles/org.eclipse.rap.rwt/src/org/eclipse/swt/widgets/Display.java @@ -19,7 +19,6 @@ import static org.eclipse.rap.rwt.remote.JsonMapping.readRectangle; import java.io.IOException; -import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; @@ -939,17 +938,11 @@ private void detachThread() { * @return the display for the given thread */ public static Display findDisplay( Thread thread ) { - synchronized( Device.class ) { - for( WeakReference displayRef : getDisplays() ) { - if( displayRef != null ) { - Display display = displayRef.get(); - if( display != null && !display.isDisposed() && display.thread == thread ) { - return display; - } - } - } + Display display = getDisplay( thread ); + if (display == null || display.thread != thread || display.isDisposed()) { return null; } + return display; } /** @@ -2217,57 +2210,20 @@ public boolean getTouchEnabled() { return false; } - @SuppressWarnings("unchecked") private void register() { - synchronized( Device.class ) { - boolean registered = false; - WeakReference[] displays = getDisplays(); - for( int i = 0; !registered && i < displays.length; i++ ) { - if( canDisplayRefBeReplaced( displays[ i ] ) ) { - displays[ i ] = new WeakReference<>( this ); - registered = true; - } - } - if( !registered ) { - WeakReference[] newDisplays = new WeakReference[ displays.length + 4 ]; - System.arraycopy( displays, 0, newDisplays, 0, displays.length ); - newDisplays[ displays.length ] = new WeakReference<>( this ); - setDisplays( newDisplays ); - } - } - } - - private boolean canDisplayRefBeReplaced( WeakReference displayRef ) { - boolean result = false; - if( displayRef == null ) { - result = true; - } else { - Display display = displayRef.get(); - if( display == null || display.thread == thread ) { - result = true; - } - } - return result; + addDisplay( this ); } private void deregister() { - synchronized( Device.class ) { - WeakReference[] displays = getDisplays(); - for( int i = 0; i < displays.length; i++ ) { - WeakReference current = displays[ i ]; - if( current != null && this == current.get() ) { - displays[ i ] = null; - } - } - } + } - private static WeakReference[] getDisplays() { - return ContextProvider.getApplicationContext().getDisplaysHolder().getDisplays(); + private static Display getDisplay( Thread thread ) { + return ContextProvider.getApplicationContext().getDisplaysHolder().getDisplay( thread ); } - private void setDisplays( WeakReference[] displays ) { - getApplicationContext().getDisplaysHolder().setDisplays( displays ); + private void addDisplay( Display display ) { + getApplicationContext().getDisplaysHolder().addDisplay( thread, display ); } /////////////////////