Skip to content

Commit 281c946

Browse files
cypokintellij-monorepo-bot
authored andcommitted
[rd debugger] fix showing breakpoint dialog, IJPL-213298
1. Fix data race when collection breakpoints to show and adding a new one. 2. Make the dialog showing only when the initial breakpoint is ready to be shown. ^IJPL-213298 fixed GitOrigin-RevId: 1508b08883fab72dc96de0e5d14ecba95f153801
1 parent 2c2458d commit 281c946

File tree

3 files changed

+31
-8
lines changed

3 files changed

+31
-8
lines changed

platform/xdebugger-impl/frontend/src/com/intellij/platform/debugger/impl/frontend/FrontendXBreakpointManager.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ class FrontendXBreakpointManager(private val project: Project, private val cs: C
128128

129129
/**
130130
* Waits for breakpoint creation from [XBreakpointEvent.BreakpointAdded] event from backend.
131+
* Returns `null` in case of timeout.
131132
*
132133
* [addBreakpoint] is not called in parallel, to have only one source of truth and avoid races.
133134
*/
@@ -385,9 +386,10 @@ class FrontendXBreakpointManager(private val project: Project, private val cs: C
385386
}
386387

387388
/**
388-
* Searches element with [search] or suspends until the element appears.
389+
* Searches an element with [search] or suspends until the element appears.
389390
* Uses [updateFlow] as a trigger for updates.
390-
* [updateFlow] must be a flow with replay
391+
* [updateFlow] must be a flow with replay.
392+
* Returns `null` in case of timeout.
391393
*/
392394
internal suspend fun <T> findOrAwaitElement(
393395
updateFlow: Flow<*>,

platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsDialog.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ protected BreakpointsDialog(@NotNull Project project,
102102

103103
collectGroupingRules();
104104

105+
// First subscribe, then collect — we shouldn't skip any changes.
106+
myBreakpointManager.subscribeOnBreakpointsChanges(myListenerDisposable, () -> {
107+
myRebuildAlarm.cancelAndRequest();
108+
return Unit.INSTANCE;
109+
});
105110
collectItems();
106111

107112
setTitle(XDebuggerBundle.message("xbreakpoints.dialog.title"));
@@ -355,11 +360,6 @@ public void actionPerformed(@NotNull AnActionEvent e) {
355360

356361
initSelection(myBreakpointItems);
357362

358-
myBreakpointManager.subscribeOnBreakpointsChanges(myListenerDisposable, () -> {
359-
myRebuildAlarm.cancelAndRequest();
360-
return Unit.INSTANCE;
361-
});
362-
363363
return decoratorPanel;
364364
}
365365

platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsDialogFactory.kt

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.intellij.xdebugger.impl.breakpoints.ui
33

44

55
import com.intellij.idea.AppMode
6+
import com.intellij.openapi.application.EDT
67
import com.intellij.openapi.components.Service
78
import com.intellij.openapi.components.service
89
import com.intellij.openapi.project.Project
@@ -17,13 +18,17 @@ import com.intellij.xdebugger.impl.breakpoints.XBreakpointBase
1718
import com.intellij.xdebugger.impl.breakpoints.XBreakpointProxy
1819
import com.intellij.xdebugger.impl.frame.XDebugManagerProxy
1920
import com.intellij.xdebugger.impl.rpc.XBreakpointId
21+
import kotlinx.coroutines.CoroutineScope
22+
import kotlinx.coroutines.Dispatchers
23+
import kotlinx.coroutines.launch
24+
import kotlinx.coroutines.withContext
2025
import org.jetbrains.annotations.ApiStatus
2126
import org.jetbrains.annotations.VisibleForTesting
2227

2328

2429
@Service(Service.Level.PROJECT)
2530
@ApiStatus.Internal
26-
class BreakpointsDialogFactory(private val project: Project) {
31+
class BreakpointsDialogFactory(private val project: Project, private val scope: CoroutineScope) {
2732
private var balloonToHide: Balloon? = null
2833
private var breakpointFromBalloon: Any? = null
2934

@@ -64,6 +69,22 @@ class BreakpointsDialogFactory(private val project: Project) {
6469

6570
@ApiStatus.Internal
6671
fun showDialogImpl(initialBreakpoint: XBreakpointId?) {
72+
if (initialBreakpoint == null) {
73+
showDialogImplImmediately(initialBreakpoint)
74+
return
75+
}
76+
77+
scope.launch {
78+
XDebugManagerProxy.getInstance()
79+
.getBreakpointManagerProxy(project)
80+
.awaitBreakpointCreation(initialBreakpoint)
81+
withContext(Dispatchers.EDT) {
82+
showDialogImplImmediately(initialBreakpoint)
83+
}
84+
}
85+
}
86+
87+
private fun showDialogImplImmediately(initialBreakpoint: XBreakpointId?) {
6788
if (selectInDialogShowing(initialBreakpoint)) return
6889

6990
val breakpointManager = XDebugManagerProxy.getInstance().getBreakpointManagerProxy(project)

0 commit comments

Comments
 (0)