long nanos = unit.toNanos(timeout);
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
for (;;) {
IExecutionUnit eu = immediate.peek();
if (eu != null) {
IExecutionUnit x = immediate.poll();
assert x != null;
if (immediate.size() != 0)
available.signalAll();
return x;
}
DelayedExecutionUnit deu = delayed.peek();
if (deu == null) {
if (nanos <= 0)
return null;
else
nanos = available.awaitNanos(nanos);
} else {
long delay = deu.getDelay(TimeUnit.NANOSECONDS);
if (delay > 0) {
if (nanos <= 0)
return null;
if (delay > nanos)
delay = nanos;
long timeLeft = available.awaitNanos(delay);
nanos -= delay - timeLeft;
} else {
IExecutionUnit x = delayed.poll();
assert x != null;
if (delayed.size() != 0)
available.signalAll();
return x;
}