GP-4080: Display 'lock' overlay when cx/target has a transaction.

This commit is contained in:
Dan 2025-04-09 17:33:16 +00:00
parent a5bd358564
commit 5f1581b417
16 changed files with 203 additions and 23 deletions

View file

@ -41,15 +41,17 @@
<LI><IMG alt="" src="icon.debugger.connect"> <B>Connection:</B> A connection is a complete
connection to a Trace RMI client. It may have one or more (but usually only one) target trace
associated with it. The node displays a description given by the client along with the remote
host and port. Double-clicking the node will expand its targets, if any.</LI>
host and port. Double-clicking the node will expand its targets, if any. If the connection is
updating any trace, a busy ovelay is displayed on the icon.</LI>
<LI><IMG alt="" src="icon.debugger.record"> <B>Target:</B> These are children of their
creating connection. A client can create any number of traces to describe each target it
wishes to trace, but by convention each client ought to create only one. The target node
displays the name of the trace and the last snapshot activated by the client. Double-clicking
the node will activate the target at the last snapshot, and change to <B>Control Target</B>
<A href=
"help/topics/DebuggerControlPlugin/DebuggerControlPlugin.html#control_mode">mode</A>.</LI>
<A href="help/topics/DebuggerControlPlugin/DebuggerControlPlugin.html#control_mode">mode</A>.
If the connection is updating this target's trace, a busy overlay is displayed on the
icon.</LI>
</UL>
<H2>Actions</H2>

View file

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -15,10 +15,14 @@
*/
package ghidra.app.plugin.core.debug.gui.tracermi.connection.tree;
import javax.swing.Icon;
import docking.widgets.tree.GTreeNode;
import generic.theme.GIcon;
import ghidra.app.plugin.core.debug.gui.tracermi.connection.TraceRmiConnectionManagerProvider;
public abstract class AbstractTraceRmiManagerNode extends GTreeNode implements TraceRmiManagerNode {
protected static final Icon ICON_TX_OVERLAY = new GIcon("icon.debugger.overlay.tx");
protected final TraceRmiConnectionManagerProvider provider;
protected final String name;

View file

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -24,9 +24,11 @@ import ghidra.app.plugin.core.debug.gui.DebuggerResources;
import ghidra.app.plugin.core.debug.gui.tracermi.connection.TraceRmiConnectionManagerProvider;
import ghidra.debug.api.target.Target;
import ghidra.debug.api.tracermi.TraceRmiConnection;
import resources.MultiIcon;
public class TraceRmiConnectionNode extends AbstractTraceRmiManagerNode {
private static final Icon ICON = DebuggerResources.ICON_CONNECTION;
private static final Icon ICON_TX = new MultiIcon(ICON, ICON_TX_OVERLAY);
private final TraceRmiConnection connection;
private final Map<Target, TraceRmiTargetNode> targetNodes = new HashMap<>();
@ -45,7 +47,7 @@ public class TraceRmiConnectionNode extends AbstractTraceRmiManagerNode {
@Override
public Icon getIcon(boolean expanded) {
return ICON;
return connection.isBusy() ? ICON_TX : ICON;
}
@Override

View file

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -170,6 +170,29 @@ public class TraceRmiServiceNode extends AbstractTraceRmiManagerNode
provider.contextChanged();
}
protected static <K> void fireNodeChanged(Map<K, ? extends AbstractTraceRmiManagerNode> map,
K key) {
AbstractTraceRmiManagerNode node;
synchronized (map) {
node = map.get(key);
}
if (node != null) {
node.fireNodeChanged();
}
}
@Override
public void transactionOpened(TraceRmiConnection connection, Target target) {
fireNodeChanged(connectionNodes, connection);
fireNodeChanged(targetNodes, target);
}
@Override
public void transactionClosed(TraceRmiConnection connection, Target target, boolean aborted) {
fireNodeChanged(connectionNodes, connection);
fireNodeChanged(targetNodes, target);
}
@Override
public void targetPublished(Target target) {
// Dont care. Using targetPublished(connection, target) instead

View file

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -20,9 +20,11 @@ import javax.swing.Icon;
import ghidra.app.plugin.core.debug.gui.DebuggerResources;
import ghidra.app.plugin.core.debug.gui.tracermi.connection.TraceRmiConnectionManagerProvider;
import ghidra.debug.api.target.Target;
import resources.MultiIcon;
public class TraceRmiTargetNode extends AbstractTraceRmiManagerNode {
private static final Icon ICON = DebuggerResources.ICON_RECORD;
private static final Icon ICON_TX = new MultiIcon(ICON, ICON_TX_OVERLAY);
private final TraceRmiConnectionNode connectionNode;
private final Target target;
@ -36,7 +38,7 @@ public class TraceRmiTargetNode extends AbstractTraceRmiManagerNode {
@Override
public Icon getIcon(boolean expanded) {
return ICON;
return target.isBusy() ? ICON_TX : ICON;
}
@Override

View file

@ -977,6 +977,8 @@ public class TraceRmiHandler extends AbstractTraceRmiConnection {
if (restoreEvents) {
open.trace.setEventsEnabled(true);
}
Swing.runLater(
() -> plugin.listeners.invoke().transactionClosed(this, open.target, req.getAbort()));
return ReplyEndTx.getDefaultInstance();
}
@ -1188,6 +1190,7 @@ public class TraceRmiHandler extends AbstractTraceRmiConnection {
synchronized (openTxes) {
openTxes.put(tx.txId, tx);
}
Swing.runLater(() -> plugin.listeners.invoke().transactionOpened(this, open.target));
return ReplyStartTx.getDefaultInstance();
}
@ -1317,4 +1320,24 @@ public class TraceRmiHandler extends AbstractTraceRmiConnection {
}
return description;
}
@Override
public boolean isBusy() {
return !openTxes.isEmpty();
}
@Override
public boolean isBusy(Target target) {
OpenTrace openTrace = openTraces.getByTrace(target.getTrace());
if (openTrace == null || openTrace.target != target) {
return false;
}
for (Tid tid : openTxes.keySet()) {
if (Objects.equals(openTrace.doId, tid.doId)) {
return true;
}
}
return false;
}
}

View file

@ -427,8 +427,7 @@ public class TraceRmiTarget extends AbstractTarget {
.orElse(null);
}
record ParamAndObjectArg(RemoteParameter param, TraceObject obj) {
}
record ParamAndObjectArg(RemoteParameter param, TraceObject obj) {}
protected ParamAndObjectArg getFirstObjectArgument(RemoteMethod method,
Map<String, Object> args) {
@ -871,8 +870,7 @@ public class TraceRmiTarget extends AbstractTarget {
static final List<ToggleBreakMatcher> SPEC = matchers(HAS_SPEC);
}
record MatchKey(Class<? extends MethodMatcher> cls, ActionName action, TraceObjectSchema sch) {
}
record MatchKey(Class<? extends MethodMatcher> cls, ActionName action, TraceObjectSchema sch) {}
protected class Matches {
private final Map<MatchKey, MatchedMethod> map = new HashMap<>();
@ -1733,4 +1731,9 @@ public class TraceRmiTarget extends AbstractTarget {
}
});
}
@Override
public boolean isBusy() {
return connection.isBusy(this);
}
}

View file

@ -267,4 +267,14 @@ public abstract class TestTraceRmiConnection extends AbstractTraceRmiConnection
Trace trace = object.getTrace();
doActivate(object, trace, snapshots.get(trace));
}
@Override
public boolean isBusy() {
return false;
}
@Override
public boolean isBusy(Target target) {
return false;
}
}