mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
Fixed a few cases of SwingUpdateManager not getting disposed
This commit is contained in:
parent
6e8811d087
commit
0aca0689fa
24 changed files with 145 additions and 137 deletions
|
@ -1113,7 +1113,7 @@ public abstract class AbstractGenericTest extends AbstractGTest {
|
|||
*
|
||||
* @param r the runnable code snippet
|
||||
*/
|
||||
public static void runSwingLater(Runnable r) {
|
||||
public void runSwingLater(Runnable r) {
|
||||
runSwing(r, false);
|
||||
}
|
||||
|
||||
|
@ -1603,34 +1603,23 @@ public abstract class AbstractGenericTest extends AbstractGTest {
|
|||
(WeakSet<SwingUpdateManager>) getInstanceField("instances",
|
||||
SwingUpdateManager.class);
|
||||
for (AbstractSwingUpdateManager manager : s) {
|
||||
|
||||
// Ignore update managers that fire often and are unlikely to affect tests.
|
||||
// (Hardcoding this is brittle, but these update managers live in lower packages
|
||||
// and a larger refactoring didn't seem worth the cost at this time.)
|
||||
String name = manager.getName();
|
||||
if (name.equals("Context Updater") ||
|
||||
name.equals("Docking Windows Updater")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
set.add(manager);
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
// performance debug
|
||||
long start = System.nanoTime();
|
||||
boolean wasEverBusy = waitForSwing(set);
|
||||
boolean wasEverBusy = waitForSwing(set, true);
|
||||
long end = System.nanoTime();
|
||||
Msg.out("\twaitForSwing() - " +
|
||||
TimeUnit.MILLISECONDS.convert(end - start, TimeUnit.NANOSECONDS));
|
||||
*/
|
||||
|
||||
boolean wasEverBusy = waitForSwing(set);
|
||||
boolean wasEverBusy = waitForSwing(set, true);
|
||||
return wasEverBusy;
|
||||
}
|
||||
|
||||
private static boolean waitForSwing(Set<AbstractSwingUpdateManager> managers) {
|
||||
private static boolean waitForSwing(Set<AbstractSwingUpdateManager> managers, boolean flush) {
|
||||
|
||||
// Note: not sure how long is too long to wait for the Swing thread and update managers
|
||||
// to finish. This is usually less than a second. We have seen a degenerate
|
||||
|
@ -1640,7 +1629,7 @@ public abstract class AbstractGenericTest extends AbstractGTest {
|
|||
int totalTime = 0;
|
||||
|
||||
// flush all managers up front to get them started before we check them
|
||||
flushAllManagers(managers);
|
||||
flushAllManagers(managers, flush);
|
||||
|
||||
boolean wasEverBusy = false;
|
||||
boolean keepGoing = true;
|
||||
|
@ -1659,13 +1648,14 @@ public abstract class AbstractGenericTest extends AbstractGTest {
|
|||
|
||||
// Msg.out("busy manager: " + manager.toStringDebug());
|
||||
|
||||
doFlush(manager);
|
||||
doFlush(flush, manager);
|
||||
|
||||
keepGoing = true; // true, since we had a busy signal
|
||||
wasEverBusy = true;
|
||||
boolean isBusy = true;
|
||||
while (isBusy) {
|
||||
|
||||
keepGoing = true; // true, since we had a busy signal
|
||||
wasEverBusy = true;
|
||||
|
||||
totalTime += sleep(DEFAULT_WAIT_DELAY);
|
||||
if (totalTime >= MAX_SWING_TIMEOUT) {
|
||||
// eject!
|
||||
|
@ -1686,7 +1676,7 @@ public abstract class AbstractGenericTest extends AbstractGTest {
|
|||
return wasEverBusy;
|
||||
}
|
||||
|
||||
private static void flushAllManagers(Set<AbstractSwingUpdateManager> managers) {
|
||||
private static void flushAllManagers(Set<AbstractSwingUpdateManager> managers, boolean flush) {
|
||||
|
||||
//
|
||||
// Some update managers will make an update that causes another manager to schedule an
|
||||
|
@ -1703,26 +1693,21 @@ public abstract class AbstractGenericTest extends AbstractGTest {
|
|||
// which would be 2
|
||||
int n = 3;
|
||||
for (int i = 0; i < n; i++) {
|
||||
boolean didFlush = false;
|
||||
for (AbstractSwingUpdateManager manager : managers) {
|
||||
didFlush = doFlush(manager);
|
||||
}
|
||||
|
||||
if (!didFlush) {
|
||||
return; // skip extra waiting when no work was done
|
||||
doFlush(flush, manager);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean doFlush(AbstractSwingUpdateManager manager) {
|
||||
|
||||
if (!manager.hasPendingUpdates()) {
|
||||
return false; // skip the yield call, as it consumes time
|
||||
private static void doFlush(boolean doFlush, AbstractSwingUpdateManager manager) {
|
||||
if (!doFlush) {
|
||||
return;
|
||||
}
|
||||
|
||||
runSwingLater(() -> manager.flush());
|
||||
runSwing(() -> {
|
||||
manager.flush();
|
||||
}, false);
|
||||
yieldToSwing();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -56,6 +56,7 @@ public abstract class AbstractSwingUpdateManager {
|
|||
public static final int DEFAULT_MAX_DELAY = 30000;
|
||||
protected static final int MIN_DELAY_FLOOR = 10;
|
||||
protected static final int DEFAULT_MIN_DELAY = 250;
|
||||
protected static final String DEFAULT_NAME = AbstractSwingUpdateManager.class.getSimpleName();
|
||||
private static final WeakSet<AbstractSwingUpdateManager> instances =
|
||||
WeakDataStructureFactory.createCopyOnReadWeakSet();
|
||||
|
||||
|
@ -106,7 +107,7 @@ public abstract class AbstractSwingUpdateManager {
|
|||
* @param maxDelay the maximum amount of time to wait between gui updates.
|
||||
*/
|
||||
protected AbstractSwingUpdateManager(int minDelay, int maxDelay) {
|
||||
this(minDelay, maxDelay, null);
|
||||
this(minDelay, maxDelay, DEFAULT_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -123,7 +124,7 @@ public abstract class AbstractSwingUpdateManager {
|
|||
protected AbstractSwingUpdateManager(int minDelay, int maxDelay, String name) {
|
||||
|
||||
this.maxDelay = maxDelay;
|
||||
this.name = name != null ? name : getClass().getSimpleName();
|
||||
this.name = name;
|
||||
|
||||
recordInception();
|
||||
this.minDelay = Math.max(MIN_DELAY_FLOOR, minDelay);
|
||||
|
@ -182,15 +183,6 @@ public abstract class AbstractSwingUpdateManager {
|
|||
Swing.runNow(this::checkForWork);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name given to this update manager. If no name was provided at construction,
|
||||
* then the class name is used.
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Causes this run manager to run if it has a pending update
|
||||
*/
|
||||
|
@ -371,10 +363,12 @@ public abstract class AbstractSwingUpdateManager {
|
|||
StackTraceElement[] trace = t.getStackTrace();
|
||||
String classInfo = trace[0].toString();
|
||||
|
||||
/*
|
||||
// debug source of creation
|
||||
Throwable filtered = ReflectionUtilities.filterJavaThrowable(t);
|
||||
String string = ReflectionUtilities.stackTraceToString(filtered);
|
||||
classInfo = classInfo + "\n\tfrom:\n\n" + string;
|
||||
*/
|
||||
|
||||
return classInfo;
|
||||
}
|
||||
|
|
|
@ -36,11 +36,11 @@ public class BufferedSwingRunner extends AbstractSwingUpdateManager {
|
|||
* @param maxDelay the maximum amount of time to wait between gui updates.
|
||||
*/
|
||||
public BufferedSwingRunner(int minDelay, int maxDelay) {
|
||||
super(minDelay, maxDelay, null);
|
||||
super(minDelay, maxDelay, DEFAULT_NAME);
|
||||
}
|
||||
|
||||
public BufferedSwingRunner() {
|
||||
super(DEFAULT_MIN_DELAY, DEFAULT_MAX_DELAY, null);
|
||||
super(DEFAULT_MIN_DELAY, DEFAULT_MAX_DELAY, DEFAULT_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -82,7 +82,8 @@ public class SwingUpdateManager extends AbstractSwingUpdateManager {
|
|||
* @param r the runnable that performs the client work.
|
||||
*/
|
||||
public SwingUpdateManager(int minDelay, int maxDelay, Runnable r) {
|
||||
this(minDelay, maxDelay, null, r);
|
||||
super(minDelay, maxDelay, DEFAULT_NAME);
|
||||
this.clientRunnable = r;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -42,11 +42,6 @@ public class ConcurrentQTest extends AbstractGenericTest {
|
|||
private ConcurrentQ<TestItem, TestResult> q;
|
||||
private TestCallback callback = new TestCallback();
|
||||
|
||||
public ConcurrentQTest() {
|
||||
super();
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
@ -558,8 +553,10 @@ public class ConcurrentQTest extends AbstractGenericTest {
|
|||
// Msg.debug(this, "\tAFTER WAITING");
|
||||
|
||||
assertTrue("Timed-out waiting for queued items", checkpointRunner.waitForFinish(3000));
|
||||
Assert.assertNotEquals("All items were processed even though we cancelled the monitor - items " +
|
||||
"processed: " + callback.itemsProcessed(), callback.itemsProcessed(), totalItems);
|
||||
Assert.assertNotEquals(
|
||||
"All items were processed even though we cancelled the monitor - items " +
|
||||
"processed: " + callback.itemsProcessed(),
|
||||
callback.itemsProcessed(), totalItems);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -710,7 +707,7 @@ public class ConcurrentQTest extends AbstractGenericTest {
|
|||
private boolean expectException;
|
||||
private volatile Exception exception;
|
||||
|
||||
/** A thread to offer things to our bounded queue, which will block when full. */
|
||||
/* A thread to offer things to our bounded queue, which will block when full. */
|
||||
OfferThread(Iterator<TestItem> items, boolean expectException) {
|
||||
this.items = items;
|
||||
this.expectException = expectException;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue