From 0a6f87f815a69ea335c3174578405628f1dafa0b Mon Sep 17 00:00:00 2001 From: xinyi-gong Date: Wed, 13 May 2026 13:26:29 +0800 Subject: [PATCH] fix nes related ui freeze --- .../eclipse/ui/completion/EditorsManager.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/completion/EditorsManager.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/completion/EditorsManager.java index 6e62c2ce..5a44850f 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/completion/EditorsManager.java +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/completion/EditorsManager.java @@ -162,8 +162,21 @@ public RenderManager getOrCreateNesRenderManager(ITextEditor editor) { return null; } - return nesRenderManagers.computeIfAbsent(editor, - ed -> new RenderManager(this.languageServer, this.nesProvider, ed)); + // Avoid computeIfAbsent() here: the RenderManager constructor calls + // Display.syncExec() via registerListeners(), and computeIfAbsent() holds + // an internal bucket lock during the mapping function. If the UI thread + // concurrently calls remove() on the same bucket, both threads deadlock. + // See https://github.com/microsoft/copilot-for-eclipse/issues/175 + RenderManager mgr = nesRenderManagers.get(editor); + if (mgr == null) { + mgr = new RenderManager(this.languageServer, this.nesProvider, editor); + RenderManager existing = nesRenderManagers.putIfAbsent(editor, mgr); + if (existing != null) { + mgr.dispose(); + mgr = existing; + } + } + return mgr; } /**