mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 02:09:44 +02:00
GT-2875 - Unswingable - review fixes
This commit is contained in:
parent
5e8340b7f8
commit
31f3cca1a5
27 changed files with 100 additions and 79 deletions
|
@ -26,10 +26,10 @@ import docking.action.DockingAction;
|
||||||
import docking.action.ToolBarData;
|
import docking.action.ToolBarData;
|
||||||
import docking.widgets.OptionDialog;
|
import docking.widgets.OptionDialog;
|
||||||
import ghidra.framework.plugintool.ComponentProviderAdapter;
|
import ghidra.framework.plugintool.ComponentProviderAdapter;
|
||||||
import ghidra.generic.function.Callback;
|
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
import resources.Icons;
|
import resources.Icons;
|
||||||
import resources.ResourceManager;
|
import resources.ResourceManager;
|
||||||
|
import utility.function.Callback;
|
||||||
|
|
||||||
public class InterpreterComponentProvider extends ComponentProviderAdapter
|
public class InterpreterComponentProvider extends ComponentProviderAdapter
|
||||||
implements InterpreterConsole {
|
implements InterpreterConsole {
|
||||||
|
|
|
@ -18,8 +18,8 @@ package ghidra.app.plugin.core.interpreter;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
import docking.action.DockingAction;
|
import docking.action.DockingAction;
|
||||||
import ghidra.generic.function.Callback;
|
|
||||||
import ghidra.util.Disposable;
|
import ghidra.util.Disposable;
|
||||||
|
import utility.function.Callback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interactive interpreter console.
|
* Interactive interpreter console.
|
||||||
|
|
|
@ -33,7 +33,6 @@ import ghidra.app.nav.NavigatableRemovalListener;
|
||||||
import ghidra.app.services.GoToService;
|
import ghidra.app.services.GoToService;
|
||||||
import ghidra.app.util.HelpTopics;
|
import ghidra.app.util.HelpTopics;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.generic.function.Callback;
|
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.util.ProgramLocation;
|
import ghidra.program.util.ProgramLocation;
|
||||||
import ghidra.program.util.ProgramSelection;
|
import ghidra.program.util.ProgramSelection;
|
||||||
|
@ -44,6 +43,7 @@ import ghidra.util.datastruct.WeakSet;
|
||||||
import ghidra.util.table.*;
|
import ghidra.util.table.*;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
import resources.ResourceManager;
|
import resources.ResourceManager;
|
||||||
|
import utility.function.Callback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialog to show a table of items. If the dialog is constructed with a non-null
|
* Dialog to show a table of items. If the dialog is constructed with a non-null
|
||||||
|
|
|
@ -49,7 +49,6 @@ import ghidra.app.context.ListingActionContext;
|
||||||
*/
|
*/
|
||||||
import ghidra.app.services.DataTypeManagerService;
|
import ghidra.app.services.DataTypeManagerService;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.generic.function.Callback;
|
|
||||||
import ghidra.program.database.symbol.EquateManager;
|
import ghidra.program.database.symbol.EquateManager;
|
||||||
import ghidra.program.model.data.DataTypeManager;
|
import ghidra.program.model.data.DataTypeManager;
|
||||||
import ghidra.program.model.data.Enum;
|
import ghidra.program.model.data.Enum;
|
||||||
|
@ -62,6 +61,7 @@ import ghidra.util.UniversalID;
|
||||||
import ghidra.util.layout.HorizontalLayout;
|
import ghidra.util.layout.HorizontalLayout;
|
||||||
import ghidra.util.layout.VerticalLayout;
|
import ghidra.util.layout.VerticalLayout;
|
||||||
import ghidra.util.table.*;
|
import ghidra.util.table.*;
|
||||||
|
import utility.function.Callback;
|
||||||
|
|
||||||
public class SetEquateDialog extends DialogComponentProvider {
|
public class SetEquateDialog extends DialogComponentProvider {
|
||||||
public static final int CANCELED = 0;
|
public static final int CANCELED = 0;
|
||||||
|
|
|
@ -47,6 +47,7 @@ import ghidra.util.exception.AssertException;
|
||||||
import ghidra.util.exception.RollbackException;
|
import ghidra.util.exception.RollbackException;
|
||||||
import junit.framework.AssertionFailedError;
|
import junit.framework.AssertionFailedError;
|
||||||
import utility.application.ApplicationLayout;
|
import utility.application.ApplicationLayout;
|
||||||
|
import utility.function.*;
|
||||||
|
|
||||||
public abstract class AbstractGhidraHeadlessIntegrationTest extends AbstractDockingTest {
|
public abstract class AbstractGhidraHeadlessIntegrationTest extends AbstractDockingTest {
|
||||||
|
|
||||||
|
|
|
@ -25,13 +25,13 @@ import org.junit.After;
|
||||||
|
|
||||||
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.generic.function.ExceptionalConsumer;
|
|
||||||
import ghidra.generic.function.ExceptionalFunction;
|
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.util.ProgramLocation;
|
import ghidra.program.util.ProgramLocation;
|
||||||
import ghidra.util.exception.AssertException;
|
import ghidra.util.exception.AssertException;
|
||||||
import util.CollectionUtils;
|
import util.CollectionUtils;
|
||||||
|
import utility.function.ExceptionalConsumer;
|
||||||
|
import utility.function.ExceptionalFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A convenience base class for creating tests that use the default tool and open a program.
|
* A convenience base class for creating tests that use the default tool and open a program.
|
||||||
|
|
|
@ -35,7 +35,6 @@ import ghidra.app.plugin.core.navigation.NextPrevAddressPlugin;
|
||||||
import ghidra.app.services.ProgramManager;
|
import ghidra.app.services.ProgramManager;
|
||||||
import ghidra.framework.plugintool.Plugin;
|
import ghidra.framework.plugintool.Plugin;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.generic.function.Callback;
|
|
||||||
import ghidra.program.database.ProgramBuilder;
|
import ghidra.program.database.ProgramBuilder;
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.data.DataType;
|
import ghidra.program.model.data.DataType;
|
||||||
|
@ -51,6 +50,7 @@ import ghidra.util.TrackedTaskListener;
|
||||||
import ghidra.util.table.GhidraTable;
|
import ghidra.util.table.GhidraTable;
|
||||||
import ghidra.util.table.field.AddressBasedLocation;
|
import ghidra.util.table.field.AddressBasedLocation;
|
||||||
import ghidra.util.task.Task;
|
import ghidra.util.task.Task;
|
||||||
|
import utility.function.Callback;
|
||||||
|
|
||||||
public class AutoTableDisassemblerTest extends AbstractGhidraHeadedIntegrationTest {
|
public class AutoTableDisassemblerTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
|
|
|
@ -32,10 +32,10 @@ import docking.event.mouse.GMouseListenerAdapter;
|
||||||
import docking.menu.DockingToolbarButton;
|
import docking.menu.DockingToolbarButton;
|
||||||
import docking.util.*;
|
import docking.util.*;
|
||||||
import docking.widgets.label.GDHtmlLabel;
|
import docking.widgets.label.GDHtmlLabel;
|
||||||
import ghidra.generic.function.Callback;
|
|
||||||
import ghidra.util.*;
|
import ghidra.util.*;
|
||||||
import ghidra.util.exception.AssertException;
|
import ghidra.util.exception.AssertException;
|
||||||
import ghidra.util.task.*;
|
import ghidra.util.task.*;
|
||||||
|
import utility.function.Callback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class used for creating dialogs in Ghidra. Subclass this to create a dialog provider that has
|
* Base class used for creating dialogs in Ghidra. Subclass this to create a dialog provider that has
|
||||||
|
|
|
@ -22,10 +22,10 @@ import javax.swing.*;
|
||||||
import javax.swing.event.DocumentEvent;
|
import javax.swing.event.DocumentEvent;
|
||||||
import javax.swing.event.DocumentListener;
|
import javax.swing.event.DocumentListener;
|
||||||
|
|
||||||
import ghidra.generic.function.Callback;
|
|
||||||
import ghidra.util.SystemUtilities;
|
import ghidra.util.SystemUtilities;
|
||||||
import ghidra.util.datastruct.WeakDataStructureFactory;
|
import ghidra.util.datastruct.WeakDataStructureFactory;
|
||||||
import ghidra.util.datastruct.WeakSet;
|
import ghidra.util.datastruct.WeakSet;
|
||||||
|
import utility.function.Callback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A text field that is meant to be used in conjunction with tables that allow filter text. This
|
* A text field that is meant to be used in conjunction with tables that allow filter text. This
|
||||||
|
|
|
@ -28,10 +28,10 @@ import docking.widgets.filechooser.GhidraFileChooser;
|
||||||
import docking.widgets.filechooser.GhidraFileChooserMode;
|
import docking.widgets.filechooser.GhidraFileChooserMode;
|
||||||
import docking.widgets.table.*;
|
import docking.widgets.table.*;
|
||||||
import ghidra.framework.preferences.Preferences;
|
import ghidra.framework.preferences.Preferences;
|
||||||
import ghidra.generic.function.Callback;
|
|
||||||
import ghidra.util.filechooser.GhidraFileChooserModel;
|
import ghidra.util.filechooser.GhidraFileChooserModel;
|
||||||
import ghidra.util.filechooser.GhidraFileFilter;
|
import ghidra.util.filechooser.GhidraFileFilter;
|
||||||
import resources.ResourceManager;
|
import resources.ResourceManager;
|
||||||
|
import utility.function.Callback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that has a table to show pathnames; the panel includes buttons to control
|
* Component that has a table to show pathnames; the panel includes buttons to control
|
||||||
|
|
|
@ -40,7 +40,6 @@ import docking.widgets.table.columnfilter.ColumnBasedTableFilter;
|
||||||
import docking.widgets.table.columnfilter.ColumnFilterSaveManager;
|
import docking.widgets.table.columnfilter.ColumnFilterSaveManager;
|
||||||
import docking.widgets.table.constraint.dialog.ColumnFilterDialog;
|
import docking.widgets.table.constraint.dialog.ColumnFilterDialog;
|
||||||
import ghidra.framework.options.PreferenceState;
|
import ghidra.framework.options.PreferenceState;
|
||||||
import ghidra.generic.function.Callback;
|
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.datastruct.WeakDataStructureFactory;
|
import ghidra.util.datastruct.WeakDataStructureFactory;
|
||||||
|
@ -50,6 +49,7 @@ import ghidra.util.task.SwingUpdateManager;
|
||||||
import resources.Icons;
|
import resources.Icons;
|
||||||
import resources.ResourceManager;
|
import resources.ResourceManager;
|
||||||
import utilities.util.reflection.ReflectionUtilities;
|
import utilities.util.reflection.ReflectionUtilities;
|
||||||
|
import utility.function.Callback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is a panel that provides a label and text field that allows users to input text that
|
* This class is a panel that provides a label and text field that allows users to input text that
|
||||||
|
|
|
@ -33,11 +33,11 @@ import docking.widgets.table.GTableFilterPanel;
|
||||||
import docking.widgets.table.RowObjectFilterModel;
|
import docking.widgets.table.RowObjectFilterModel;
|
||||||
import docking.widgets.table.columnfilter.*;
|
import docking.widgets.table.columnfilter.*;
|
||||||
import docking.widgets.table.constrainteditor.ColumnConstraintEditor;
|
import docking.widgets.table.constrainteditor.ColumnConstraintEditor;
|
||||||
import ghidra.generic.function.Callback;
|
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.layout.VerticalLayout;
|
import ghidra.util.layout.VerticalLayout;
|
||||||
import resources.ResourceManager;
|
import resources.ResourceManager;
|
||||||
|
import utility.function.Callback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialog for creating and editing column table filters.
|
* Dialog for creating and editing column table filters.
|
||||||
|
|
|
@ -176,8 +176,8 @@ public class TaskBuilder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the amount of time that will pass before showing the dialog. The default is
|
* Sets the amount of time that will pass before showing the dialog. The default is
|
||||||
* {@link TaskLauncher#INITIAL_DELAY} for non-modal tasks and
|
* {@link TaskLauncher#INITIAL_DELAY_MS} for non-modal tasks and
|
||||||
* {@link TaskLauncher#INITIAL_MODAL_DELAY} for modal tasks.
|
* {@link TaskLauncher#INITIAL_MODAL_DELAY_MS} for modal tasks.
|
||||||
*
|
*
|
||||||
* @param delay the delay time
|
* @param delay the delay time
|
||||||
* @return this builder
|
* @return this builder
|
||||||
|
|
|
@ -23,12 +23,19 @@ import ghidra.util.exception.UnableToSwingException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to initiate a Task in a new Thread, and to show a progress dialog that indicates
|
* Class to initiate a Task in a new Thread, and to show a progress dialog that indicates
|
||||||
* activity. The progress dialog will show an animation in the event that the task of this class
|
* activity <b>if the task takes too long</b>. The progress dialog will show an
|
||||||
* cannot show progress.
|
* animation in the event that the task of this class cannot show progress.
|
||||||
*
|
*
|
||||||
* <p>For complete control of how this class functions, use
|
* <p>For complete control of how this class functions, use
|
||||||
* {@link #TaskLauncher(Task, Component, int, int)}. Alternatively, for simpler uses,
|
* {@link #TaskLauncher(Task, Component, int, int)}. Alternatively, for simpler uses,
|
||||||
* see one of the many static convenience methods.
|
* see one of the many static convenience methods.
|
||||||
|
*
|
||||||
|
* <p><b>Important Usage Note:</b><br>
|
||||||
|
* For clients that are not on the Swing thread the behavior of this class is designed to
|
||||||
|
* prevent deadlocks. When called from a non-Swing thread, this class will attempt to show a
|
||||||
|
* modal dialog. However, if more than {@link #getSwingTimeoutInSeconds()} elapses while waiting
|
||||||
|
* for the Swing thread, then this class will <b>give up on using the Swing thread and will not
|
||||||
|
* create a background thread</b>. Instead, the client code will be run in the client thread.
|
||||||
*
|
*
|
||||||
* <a name="modal_usage"></a>
|
* <a name="modal_usage"></a>
|
||||||
* <p><b><a name="modal_usage">Modal Usage</a></b><br>
|
* <p><b><a name="modal_usage">Modal Usage</a></b><br>
|
||||||
|
@ -250,12 +257,12 @@ public class TaskLauncher {
|
||||||
Swing.runNow(() -> runner.run(), timeout, TimeUnit.SECONDS);
|
Swing.runNow(() -> runner.run(), timeout, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// template method to allow timeout change
|
// template method to allow timeout change; used by tests
|
||||||
protected int getSwingTimeoutInSeconds() {
|
protected int getSwingTimeoutInSeconds() {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// template method to allow task runner change
|
// template method to allow task runner change; used by tests
|
||||||
protected TaskRunner createTaskRunner(Task task, Component parent, int delayMs,
|
protected TaskRunner createTaskRunner(Task task, Component parent, int delayMs,
|
||||||
int dialogWidth) {
|
int dialogWidth) {
|
||||||
return new TaskRunner(task, parent, delayMs, dialogWidth);
|
return new TaskRunner(task, parent, delayMs, dialogWidth);
|
||||||
|
|
|
@ -33,7 +33,7 @@ import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import generic.test.AbstractGenericTest;
|
import generic.test.AbstractGenericTest;
|
||||||
import ghidra.generic.function.Callback;
|
import utility.function.Callback;
|
||||||
|
|
||||||
public class FilterTextFieldTest {
|
public class FilterTextFieldTest {
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ public class TaskUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the given listener added via {@link #addTrackedTask(Task)}.
|
* Removes the given listener added via {@link #addTrackedTask(Task,TaskMonitor)}.
|
||||||
* @param listener The listener that needs to be removed.
|
* @param listener The listener that needs to be removed.
|
||||||
*/
|
*/
|
||||||
public static void removeTrackedTaskListener(TrackedTaskListener listener) {
|
public static void removeTrackedTaskListener(TrackedTaskListener listener) {
|
||||||
|
|
|
@ -19,12 +19,12 @@ import java.util.Objects;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import ghidra.generic.function.Callback;
|
|
||||||
import ghidra.util.SystemUtilities;
|
import ghidra.util.SystemUtilities;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.exception.TimeoutException;
|
import ghidra.util.exception.TimeoutException;
|
||||||
import ghidra.util.timer.GTimer;
|
import ghidra.util.timer.GTimer;
|
||||||
import ghidra.util.timer.GTimerMonitor;
|
import ghidra.util.timer.GTimerMonitor;
|
||||||
|
import utility.function.Callback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A task monitor that allows clients the ability to specify a timeout after which this monitor
|
* A task monitor that allows clients the ability to specify a timeout after which this monitor
|
||||||
|
|
|
@ -24,12 +24,12 @@ import com.google.common.collect.Iterators;
|
||||||
|
|
||||||
import edu.uci.ics.jung.graph.util.EdgeType;
|
import edu.uci.ics.jung.graph.util.EdgeType;
|
||||||
import edu.uci.ics.jung.graph.util.Pair;
|
import edu.uci.ics.jung.graph.util.Pair;
|
||||||
import ghidra.generic.function.Callback;
|
|
||||||
import ghidra.graph.GraphAlgorithms;
|
import ghidra.graph.GraphAlgorithms;
|
||||||
import ghidra.graph.viewer.VisualEdge;
|
import ghidra.graph.viewer.VisualEdge;
|
||||||
import ghidra.graph.viewer.VisualVertex;
|
import ghidra.graph.viewer.VisualVertex;
|
||||||
import ghidra.graph.viewer.layout.VisualGraphLayout;
|
import ghidra.graph.viewer.layout.VisualGraphLayout;
|
||||||
import util.CollectionUtils;
|
import util.CollectionUtils;
|
||||||
|
import utility.function.Callback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A graph implementation that allows clients to mark vertices and edges as filtered. When
|
* A graph implementation that allows clients to mark vertices and edges as filtered. When
|
||||||
|
|
|
@ -17,11 +17,11 @@ package ghidra.graph.job;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import ghidra.generic.function.Callback;
|
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.SystemUtilities;
|
import ghidra.util.SystemUtilities;
|
||||||
import ghidra.util.datastruct.QueueStub;
|
import ghidra.util.datastruct.QueueStub;
|
||||||
import ghidra.util.exception.AssertException;
|
import ghidra.util.exception.AssertException;
|
||||||
|
import utility.function.Callback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class to run {@link GraphJob}s. This class will queue jobs and will run them
|
* A class to run {@link GraphJob}s. This class will queue jobs and will run them
|
||||||
|
|
|
@ -25,7 +25,6 @@ import java.util.Objects;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
|
||||||
import edu.uci.ics.jung.visualization.*;
|
import edu.uci.ics.jung.visualization.*;
|
||||||
import ghidra.generic.function.Callback;
|
|
||||||
import ghidra.graph.VisualGraph;
|
import ghidra.graph.VisualGraph;
|
||||||
import ghidra.graph.job.*;
|
import ghidra.graph.job.*;
|
||||||
import ghidra.graph.viewer.edge.routing.BasicEdgeRouter;
|
import ghidra.graph.viewer.edge.routing.BasicEdgeRouter;
|
||||||
|
@ -34,6 +33,7 @@ import ghidra.util.datastruct.WeakDataStructureFactory;
|
||||||
import ghidra.util.datastruct.WeakSet;
|
import ghidra.util.datastruct.WeakSet;
|
||||||
import ghidra.util.exception.AssertException;
|
import ghidra.util.exception.AssertException;
|
||||||
import ghidra.util.task.BusyListener;
|
import ghidra.util.task.BusyListener;
|
||||||
|
import utility.function.Callback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the class through which operations travel that manipulate the view and graph <b>while
|
* This is the class through which operations travel that manipulate the view and graph <b>while
|
||||||
|
|
|
@ -23,7 +23,6 @@ import java.util.function.Supplier;
|
||||||
|
|
||||||
import docking.DockingWindowManager;
|
import docking.DockingWindowManager;
|
||||||
import generic.concurrent.GThreadPool;
|
import generic.concurrent.GThreadPool;
|
||||||
import ghidra.generic.function.Callback;
|
|
||||||
import ghidra.graph.*;
|
import ghidra.graph.*;
|
||||||
import ghidra.graph.algo.ChkDominanceAlgorithm;
|
import ghidra.graph.algo.ChkDominanceAlgorithm;
|
||||||
import ghidra.graph.algo.ChkPostDominanceAlgorithm;
|
import ghidra.graph.algo.ChkPostDominanceAlgorithm;
|
||||||
|
@ -34,6 +33,7 @@ import ghidra.util.SystemUtilities;
|
||||||
import ghidra.util.datastruct.CallbackAccumulator;
|
import ghidra.util.datastruct.CallbackAccumulator;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.task.*;
|
import ghidra.util.task.*;
|
||||||
|
import utility.function.Callback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class that calculates flow between vertices and then triggers that flow to be painted
|
* A class that calculates flow between vertices and then triggers that flow to be painted
|
||||||
|
|
|
@ -18,10 +18,10 @@ package ghidra.graph.algo.viewer;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import ghidra.generic.function.Callback;
|
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.task.TaskMonitorAdapter;
|
import ghidra.util.task.TaskMonitorAdapter;
|
||||||
|
import utility.function.Callback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Task monitor that will trigger a {@link #wait()} when {@link #checkCanceled()} is called. This
|
* Task monitor that will trigger a {@link #wait()} when {@link #checkCanceled()} is called. This
|
||||||
|
|
|
@ -16,9 +16,7 @@
|
||||||
package ghidra.util;
|
package ghidra.util;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
@ -159,51 +157,39 @@ public class Swing {
|
||||||
throws UnableToSwingException {
|
throws UnableToSwingException {
|
||||||
|
|
||||||
if (isInHeadlessMode() || SystemUtilities.isEventDispatchThread()) {
|
if (isInHeadlessMode() || SystemUtilities.isEventDispatchThread()) {
|
||||||
doRunSwing(r, true, SWING_RUN_ERROR_MSG);
|
doRun(r, true, SWING_RUN_ERROR_MSG);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CountDownLatch start = new CountDownLatch(1);
|
/*
|
||||||
CountDownLatch end = new CountDownLatch(1);
|
We use the CyclicBarrier to force this thread and the Swing thread to wait for each
|
||||||
AtomicBoolean timedOut = new AtomicBoolean();
|
other. This allows the calling thread to know if/when the Swing thread starts and
|
||||||
|
the Swing thread to know if the calling thread timed-out.
|
||||||
|
*/
|
||||||
|
CyclicBarrier start = new CyclicBarrier(2);
|
||||||
|
CyclicBarrier end = new CyclicBarrier(2);
|
||||||
|
|
||||||
doRunSwing(() -> {
|
runLater(() -> {
|
||||||
|
|
||||||
start.countDown();
|
if (!waitFor(start)) {
|
||||||
|
return; // must have timed-out
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (timedOut.get()) {
|
|
||||||
// timed-out waiting for Swing lock, but eventually did get the lock; too late now
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
r.run();
|
r.run();
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
end.countDown();
|
waitFor(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
}, false, SWING_RUN_ERROR_MSG);
|
});
|
||||||
|
|
||||||
try {
|
if (!waitFor(start, timeout, unit)) {
|
||||||
timedOut.set(!start.await(timeout, unit));
|
|
||||||
}
|
|
||||||
catch (InterruptedException e) {
|
|
||||||
// handled below
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timedOut.get()) {
|
|
||||||
throw new UnableToSwingException(
|
throw new UnableToSwingException(
|
||||||
"Timed-out waiting for Swing thread lock in " + timeout + " " + unit);
|
"Timed-out waiting for Swing thread lock in " + timeout + " " + unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// we've started; wait for the runnable with no timeout
|
waitFor(end);
|
||||||
try {
|
|
||||||
end.await();
|
|
||||||
}
|
|
||||||
catch (InterruptedException e) {
|
|
||||||
// we sometimes interrupt our tasks intentionally, so don't report it
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -213,7 +199,7 @@ public class Swing {
|
||||||
* @param r the runnable
|
* @param r the runnable
|
||||||
*/
|
*/
|
||||||
public static void runLater(Runnable r) {
|
public static void runLater(Runnable r) {
|
||||||
doRunSwing(r, false, SWING_RUN_ERROR_MSG);
|
doRun(r, false, SWING_RUN_ERROR_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void runIfSwingOrRunLater(Runnable r) {
|
public static void runIfSwingOrRunLater(Runnable r) {
|
||||||
|
@ -230,33 +216,60 @@ public class Swing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean waitFor(CyclicBarrier barrier, long timeout, TimeUnit unit) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
barrier.await(timeout, unit);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (InterruptedException | BrokenBarrierException | TimeoutException e) {
|
||||||
|
// our Swing tasks may be interrupted from the framework
|
||||||
|
}
|
||||||
|
|
||||||
|
// timed-out or was interrupted
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean waitFor(CyclicBarrier barrier) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
barrier.await();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (InterruptedException | BrokenBarrierException e) {
|
||||||
|
// our Swing tasks may be interrupted from the framework
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean isInHeadlessMode() {
|
private static boolean isInHeadlessMode() {
|
||||||
return SystemUtilities.isInHeadlessMode();
|
return SystemUtilities.isInHeadlessMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void doRunSwing(Runnable r, boolean wait, String errorMessage) {
|
private static void doRun(Runnable r, boolean wait, String errorMessage) {
|
||||||
if (isInHeadlessMode()) {
|
if (isInHeadlessMode()) {
|
||||||
r.run();
|
r.run();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wait) {
|
if (!wait) {
|
||||||
if (SwingUtilities.isEventDispatchThread()) {
|
|
||||||
r.run();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
SwingUtilities.invokeAndWait(r);
|
|
||||||
}
|
|
||||||
catch (InterruptedException e) {
|
|
||||||
// we sometimes interrupt our tasks intentionally, so don't report it
|
|
||||||
}
|
|
||||||
catch (InvocationTargetException e) {
|
|
||||||
Msg.error(Swing.class, errorMessage + "\nException Message: " + e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SwingUtilities.invokeLater(r);
|
SwingUtilities.invokeLater(r);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SwingUtilities.isEventDispatchThread()) {
|
||||||
|
r.run();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
SwingUtilities.invokeAndWait(r);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e) {
|
||||||
|
// we sometimes interrupt our tasks intentionally, so don't report it
|
||||||
|
}
|
||||||
|
catch (InvocationTargetException e) {
|
||||||
|
Msg.error(Swing.class, errorMessage + "\nException Message: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package ghidra.generic.function;
|
package utility.function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A generic functional interface that is more semantically sound than {@link Runnable}. Use
|
* A generic functional interface that is more semantically sound than {@link Runnable}. Use
|
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package ghidra.generic.function;
|
package utility.function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A generic functional interface that is more semantically sound than {@link Runnable}. Use
|
* A generic functional interface that is more semantically sound than {@link Runnable}. Use
|
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package ghidra.generic.function;
|
package utility.function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A generic functional interface that allows you to consume an item and potentially throw
|
* A generic functional interface that allows you to consume an item and potentially throw
|
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package ghidra.generic.function;
|
package utility.function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A generic functional interface that allows you to consume an item, return a result,
|
* A generic functional interface that allows you to consume an item, return a result,
|
Loading…
Add table
Add a link
Reference in a new issue