/*******************************************************************************
* Copyright (c) 2016 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.tracecompass.tmf.ui.tests.shared;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.swt.widgets.Display;
/**
* A utility class for methods related to waiting until certain conditions are met.
*/
public final class WaitUtils {
private WaitUtils() {
}
private static final long SLEEP_INTERVAL_MS = 100;
private static final long UI_THREAD_SLEEP_INTERVAL_MS = 10;
private static final long DEFAULT_MAX_WAIT_TIME_MS = 300000;
/**
* Waits for all Eclipse jobs to finish.
*
* @throws WaitTimeoutException
* once the waiting time passes the maximum value
*/
public static void waitForJobs() {
waitUntil(new IWaitCondition() {
@Override
public boolean test() throws Exception {
return Job.getJobManager().isIdle();
}
@Override
public String getFailureMessage() {
printJobs();
return "Timed out waiting for jobs to finish.";
}
});
}
/**
* Prints the state of all the jobs on stderr.
*/
public static void printJobs() {
Job[] jobs = Job.getJobManager().find(null);
for (Job job : jobs) {
System.err.println(job.toString() + " state: " + jobStateToString(job.getState())); //$NON-NLS-1$
Thread thread = job.getThread();
if (thread != null) {
for (StackTraceElement stractTraceElement : thread.getStackTrace()) {
System.err.println(" " + stractTraceElement); //$NON-NLS-1$
}
}
System.err.println();
}
}
private static String jobStateToString(int jobState) {
switch (jobState) {
case Job.RUNNING:
return "RUNNING"; //$NON-NLS-1$
case Job.WAITING:
return "WAITING"; //$NON-NLS-1$
case Job.SLEEPING:
return "SLEEPING"; //$NON-NLS-1$
case Job.NONE:
return "NONE"; //$NON-NLS-1$
default:
return "UNKNOWN"; //$NON-NLS-1$
}
}
/**
* Waits for a certain condition to be met.
*
* @param condition
* the condition to be met
*
* @throws WaitTimeoutException
* once the waiting time passes the maximum value
*/
public static void waitUntil(IWaitCondition condition) {
waitUntil(condition, DEFAULT_MAX_WAIT_TIME_MS);
}
/**
* Waits for a certain condition to be met.
*
* @param condition
* the condition to be met
* @param maxWait
* the maximum time to wait, in milliseconds. Once the waiting
* time passes the maximum value, a WaitTimeoutException is
* thrown
* @throws WaitTimeoutException
* once the waiting time passes the maximum value
*/
public static void waitUntil(IWaitCondition condition, long maxWait) {
long waitStart = System.currentTimeMillis();
Display display = Display.getCurrent();
try {
while (!condition.test()) {
if (System.currentTimeMillis() - waitStart > maxWait) {
throw new WaitTimeoutException(condition.getFailureMessage()); //$NON-NLS-1$
}
if (display != null) {
if (!display.readAndDispatch()) {
// We do not use Display.sleep because it might never wake up
// if there is no user interaction
try {
Thread.sleep(UI_THREAD_SLEEP_INTERVAL_MS);
} catch (final InterruptedException e) {
// Ignored
}
}
display.update();
} else {
try {
Thread.sleep(SLEEP_INTERVAL_MS);
} catch (final InterruptedException e) {
// Ignored
}
}
}
} catch (Exception e) {
throw new WaitTimeoutException(condition.getFailureMessage()); //$NON-NLS-1$
}
}
}