Fixed a few cases of SwingUpdateManager not getting disposed

This commit is contained in:
ghidra1 2020-12-31 14:20:58 -05:00 committed by dragonmacher
parent 6e8811d087
commit 0aca0689fa
24 changed files with 145 additions and 137 deletions

View file

@ -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;
}
/**

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}
/**

View file

@ -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;