fix to swing update manager

This commit is contained in:
ghidravore 2020-03-16 18:52:50 -04:00
parent b30657cd83
commit 53912fe9b1
2 changed files with 99 additions and 2 deletions

View file

@ -138,7 +138,7 @@ public class SwingUpdateManager {
recordInception();
this.minDelay = Math.max(MIN_DELAY_FLOOR, minDelay);
timer = new Timer(minDelay, e -> checkForWork());
timer = new Timer(minDelay, e -> timerCallback());
timer.setRepeats(false);
instances.add(this);
}
@ -261,12 +261,23 @@ public class SwingUpdateManager {
}
}
// This is similar to checkForWork except that it resets the task buffering when
// the time expires and there is no work to do.
private void timerCallback() {
if (shouldDoWork()) {
doWork();
}
else if (requestTime == NONE) {
bufferingStartTime = NONE; // The timer has fired and there is no pending work
}
}
// note: this is called on the Swing thread
private synchronized boolean shouldDoWork() {
// If no pending request, exit without restarting timer
if (requestTime == NONE) {
bufferingStartTime = NONE; // The timer has fired and there is no pending work
return false;
}

View file

@ -0,0 +1,86 @@
/* ###
* IP: GHIDRA
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.util.task;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import generic.test.AbstractGenericTest;
import ghidra.util.Msg;
import ghidra.util.SystemUtilities;
public class SwingUpdateManagerTimerTest extends AbstractGenericTest {
private static final int MIN_DELAY = 100;
private static final int MAX_DELAY = 10000;
private volatile int runnableCalled;
private SwingUpdateManager manager;
@Before
public void setUp() throws Exception {
manager = createUpdateManager(MIN_DELAY, MAX_DELAY);
// must turn this on to get the expected results, as in headless mode the update manager
// will run it's Swing work immediately on the test thread, which is not true to the
// default behavior
System.setProperty(SystemUtilities.HEADLESS_PROPERTY, Boolean.FALSE.toString());
}
@Test
public void testNotFiringTooOften() throws InterruptedException {
Thread t = new Thread(() -> {
for (int i = 0; i < 50; i++) {
manager.update();
manager.update();
manager.update();
manager.update();
sleep(10);
}
});
t.start();
t.join();
waitForManager();
assertEquals(2, runnableCalled);
}
//==================================================================================================
// Private Methods
//==================================================================================================
private void waitForManager() {
// let all swing updates finish, which may trigger the update manager
waitForSwing();
while (manager.isBusy()) {
sleep(DEFAULT_WAIT_DELAY);
}
// let any resulting swing events finish
waitForSwing();
}
private SwingUpdateManager createUpdateManager(int min, int max) {
return new SwingUpdateManager(min, max, "bob", new Runnable() {
@Override
public void run() {
runnableCalled++;
Msg.debug(this, "run() called - count: " + runnableCalled);
}
});
}
}