blob: e474222c49dea734d5560a37682bfd41e02a39dd [file] [log] [blame]
/*-
* Copyright (C) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This file was distributed by Oracle as part of a version of Oracle Berkeley
* DB Java Edition made available at:
*
* http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html
*
* Please see the LICENSE file included in the top-level directory of the
* appropriate version of Oracle Berkeley DB Java Edition for a copy of the
* license and additional information.
*/
package com.sleepycat.je.utilint;
import java.util.function.Supplier;
/**
* Utility class that permits a "poll based" waiting for a condition.
*
* Either the {@link #condition()} method should be implemented in a subclass,
* or the static {@link #await(long, long, Supplier)} method can be called.
* The latter allows passing a lambda.
*/
public abstract class PollCondition implements Supplier<Boolean> {
private final long checkPeriodMs;
private final long timeoutMs;
public PollCondition(long checkPeriodMs,
long timeoutMs) {
super();
assert checkPeriodMs <= timeoutMs;
this.checkPeriodMs = checkPeriodMs;
this.timeoutMs = timeoutMs;
}
protected abstract boolean condition();
@Override
public Boolean get() {
return condition();
}
/**
* Wait for the {@link #condition()} method to return true.
*/
public boolean await() {
return await(checkPeriodMs, timeoutMs, this);
}
/**
* Wait for a condition that can be specified as a lambda.
*/
public static boolean await(final long checkPeriodMs,
final long timeoutMs,
final Supplier<Boolean> cond) {
if (cond.get()) {
return true;
}
final long timeLimit = System.currentTimeMillis() + timeoutMs;
do {
try {
Thread.sleep(checkPeriodMs);
} catch (InterruptedException e) {
return false;
}
if (cond.get()) {
return true;
}
} while (System.currentTimeMillis() < timeLimit);
return false;
}
/**
* Like {@link #await(long, long, Supplier)} but calls waitOn.wait rather
* than Thread.sleep. This allows checking the condition on demand by
* calling waitOn.notify.
*/
public static boolean await(final long checkPeriodMs,
final long timeoutMs,
final Object waitOn,
final Supplier<Boolean> cond) {
if (cond.get()) {
return true;
}
final long timeLimit = System.currentTimeMillis() + timeoutMs;
do {
synchronized (waitOn) {
try {
waitOn.wait(checkPeriodMs);
} catch (InterruptedException e) {
return false;
}
}
if (cond.get()) {
return true;
}
} while (System.currentTimeMillis() < timeLimit);
return false;
}
}