673 lines
22 KiB
Java
673 lines
22 KiB
Java
|
package com.google.common.util.concurrent;
|
||
|
|
||
|
import com.google.common.base.Preconditions;
|
||
|
import com.google.common.primitives.Longs;
|
||
|
import java.util.concurrent.TimeUnit;
|
||
|
import java.util.concurrent.locks.Condition;
|
||
|
import java.util.concurrent.locks.ReentrantLock;
|
||
|
|
||
|
/* loaded from: classes2.dex */
|
||
|
public final class Monitor {
|
||
|
private Guard activeGuards;
|
||
|
private final boolean fair;
|
||
|
private final ReentrantLock lock;
|
||
|
|
||
|
/* loaded from: classes2.dex */
|
||
|
public static abstract class Guard {
|
||
|
final Condition condition;
|
||
|
final Monitor monitor;
|
||
|
Guard next;
|
||
|
int waiterCount = 0;
|
||
|
|
||
|
public abstract boolean isSatisfied();
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: protected */
|
||
|
public Guard(Monitor monitor) {
|
||
|
this.monitor = (Monitor) Preconditions.checkNotNull(monitor, "monitor");
|
||
|
this.condition = monitor.lock.newCondition();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public Monitor() {
|
||
|
this(false);
|
||
|
}
|
||
|
|
||
|
public Monitor(boolean z) {
|
||
|
this.activeGuards = null;
|
||
|
this.fair = z;
|
||
|
this.lock = new ReentrantLock(z);
|
||
|
}
|
||
|
|
||
|
public final void enter() {
|
||
|
this.lock.lock();
|
||
|
}
|
||
|
|
||
|
public final boolean enter(long j, TimeUnit timeUnit) {
|
||
|
boolean tryLock;
|
||
|
long safeNanos = toSafeNanos(j, timeUnit);
|
||
|
ReentrantLock reentrantLock = this.lock;
|
||
|
boolean z = true;
|
||
|
if (!this.fair && reentrantLock.tryLock()) {
|
||
|
return true;
|
||
|
}
|
||
|
boolean interrupted = Thread.interrupted();
|
||
|
try {
|
||
|
long nanoTime = System.nanoTime();
|
||
|
long j2 = safeNanos;
|
||
|
while (true) {
|
||
|
try {
|
||
|
try {
|
||
|
tryLock = reentrantLock.tryLock(j2, TimeUnit.NANOSECONDS);
|
||
|
break;
|
||
|
} catch (Throwable th) {
|
||
|
th = th;
|
||
|
if (z) {
|
||
|
Thread.currentThread().interrupt();
|
||
|
}
|
||
|
throw th;
|
||
|
}
|
||
|
} catch (InterruptedException unused) {
|
||
|
j2 = remainingNanos(nanoTime, safeNanos);
|
||
|
interrupted = true;
|
||
|
}
|
||
|
}
|
||
|
if (interrupted) {
|
||
|
Thread.currentThread().interrupt();
|
||
|
}
|
||
|
return tryLock;
|
||
|
} catch (Throwable th2) {
|
||
|
th = th2;
|
||
|
z = interrupted;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public final void enterInterruptibly() throws InterruptedException {
|
||
|
this.lock.lockInterruptibly();
|
||
|
}
|
||
|
|
||
|
public final boolean enterInterruptibly(long j, TimeUnit timeUnit) throws InterruptedException {
|
||
|
return this.lock.tryLock(j, timeUnit);
|
||
|
}
|
||
|
|
||
|
public final boolean tryEnter() {
|
||
|
return this.lock.tryLock();
|
||
|
}
|
||
|
|
||
|
public final void enterWhen(Guard guard) throws InterruptedException {
|
||
|
if (guard.monitor != this) {
|
||
|
throw new IllegalMonitorStateException();
|
||
|
}
|
||
|
ReentrantLock reentrantLock = this.lock;
|
||
|
boolean isHeldByCurrentThread = reentrantLock.isHeldByCurrentThread();
|
||
|
reentrantLock.lockInterruptibly();
|
||
|
try {
|
||
|
if (guard.isSatisfied()) {
|
||
|
return;
|
||
|
}
|
||
|
await(guard, isHeldByCurrentThread);
|
||
|
} catch (Throwable th) {
|
||
|
leave();
|
||
|
throw th;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* JADX WARN: Code restructure failed: missing block: B:17:0x0047, code lost:
|
||
|
|
||
|
if (awaitNanos(r11, r0, r3) != false) goto L24;
|
||
|
*/
|
||
|
/* JADX WARN: Removed duplicated region for block: B:13:0x003a */
|
||
|
/* JADX WARN: Removed duplicated region for block: B:19:0x004c A[DONT_GENERATE] */
|
||
|
/*
|
||
|
Code decompiled incorrectly, please refer to instructions dump.
|
||
|
To view partially-correct add '--show-bad-code' argument
|
||
|
*/
|
||
|
public final boolean enterWhen(com.google.common.util.concurrent.Monitor.Guard r11, long r12, java.util.concurrent.TimeUnit r14) throws java.lang.InterruptedException {
|
||
|
/*
|
||
|
r10 = this;
|
||
|
long r0 = toSafeNanos(r12, r14)
|
||
|
com.google.common.util.concurrent.Monitor r2 = r11.monitor
|
||
|
if (r2 != r10) goto L60
|
||
|
java.util.concurrent.locks.ReentrantLock r2 = r10.lock
|
||
|
boolean r3 = r2.isHeldByCurrentThread()
|
||
|
boolean r4 = r10.fair
|
||
|
r5 = 0
|
||
|
r7 = 0
|
||
|
if (r4 != 0) goto L29
|
||
|
boolean r4 = java.lang.Thread.interrupted()
|
||
|
if (r4 != 0) goto L23
|
||
|
boolean r4 = r2.tryLock()
|
||
|
if (r4 == 0) goto L29
|
||
|
r8 = r5
|
||
|
goto L34
|
||
|
L23:
|
||
|
java.lang.InterruptedException r11 = new java.lang.InterruptedException
|
||
|
r11.<init>()
|
||
|
throw r11
|
||
|
L29:
|
||
|
long r8 = initNanoTime(r0)
|
||
|
boolean r12 = r2.tryLock(r12, r14)
|
||
|
if (r12 != 0) goto L34
|
||
|
return r7
|
||
|
L34:
|
||
|
boolean r12 = r11.isSatisfied() // Catch: java.lang.Throwable -> L50
|
||
|
if (r12 != 0) goto L49
|
||
|
int r12 = (r8 > r5 ? 1 : (r8 == r5 ? 0 : -1))
|
||
|
if (r12 != 0) goto L3f
|
||
|
goto L43
|
||
|
L3f:
|
||
|
long r0 = remainingNanos(r8, r0) // Catch: java.lang.Throwable -> L50
|
||
|
L43:
|
||
|
boolean r11 = r10.awaitNanos(r11, r0, r3) // Catch: java.lang.Throwable -> L50
|
||
|
if (r11 == 0) goto L4a
|
||
|
L49:
|
||
|
r7 = 1
|
||
|
L4a:
|
||
|
if (r7 != 0) goto L4f
|
||
|
r2.unlock()
|
||
|
L4f:
|
||
|
return r7
|
||
|
L50:
|
||
|
r11 = move-exception
|
||
|
if (r3 != 0) goto L5c
|
||
|
r10.signalNextWaiter() // Catch: java.lang.Throwable -> L57
|
||
|
goto L5c
|
||
|
L57:
|
||
|
r11 = move-exception
|
||
|
r2.unlock()
|
||
|
throw r11
|
||
|
L5c:
|
||
|
r2.unlock()
|
||
|
throw r11
|
||
|
L60:
|
||
|
java.lang.IllegalMonitorStateException r11 = new java.lang.IllegalMonitorStateException
|
||
|
r11.<init>()
|
||
|
throw r11
|
||
|
*/
|
||
|
throw new UnsupportedOperationException("Method not decompiled: com.google.common.util.concurrent.Monitor.enterWhen(com.google.common.util.concurrent.Monitor$Guard, long, java.util.concurrent.TimeUnit):boolean");
|
||
|
}
|
||
|
|
||
|
public final void enterWhenUninterruptibly(Guard guard) {
|
||
|
if (guard.monitor != this) {
|
||
|
throw new IllegalMonitorStateException();
|
||
|
}
|
||
|
ReentrantLock reentrantLock = this.lock;
|
||
|
boolean isHeldByCurrentThread = reentrantLock.isHeldByCurrentThread();
|
||
|
reentrantLock.lock();
|
||
|
try {
|
||
|
if (guard.isSatisfied()) {
|
||
|
return;
|
||
|
}
|
||
|
awaitUninterruptibly(guard, isHeldByCurrentThread);
|
||
|
} catch (Throwable th) {
|
||
|
leave();
|
||
|
throw th;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* JADX WARN: Removed duplicated region for block: B:15:0x0037 */
|
||
|
/* JADX WARN: Removed duplicated region for block: B:22:0x004b A[Catch: all -> 0x0072, TRY_ENTER, TRY_LEAVE, TryCatch #1 {all -> 0x0072, blocks: (B:5:0x0012, B:7:0x001a, B:22:0x004b, B:32:0x0059, B:33:0x005c, B:34:0x0023, B:37:0x0028, B:13:0x0030, B:17:0x003b, B:18:0x0045, B:27:0x0041), top: B:4:0x0012, inners: #2, #5 }] */
|
||
|
/* JADX WARN: Removed duplicated region for block: B:24:0x0050 */
|
||
|
/*
|
||
|
Code decompiled incorrectly, please refer to instructions dump.
|
||
|
To view partially-correct add '--show-bad-code' argument
|
||
|
*/
|
||
|
public final boolean enterWhenUninterruptibly(com.google.common.util.concurrent.Monitor.Guard r12, long r13, java.util.concurrent.TimeUnit r15) {
|
||
|
/*
|
||
|
r11 = this;
|
||
|
long r13 = toSafeNanos(r13, r15)
|
||
|
com.google.common.util.concurrent.Monitor r15 = r12.monitor
|
||
|
if (r15 != r11) goto L7e
|
||
|
java.util.concurrent.locks.ReentrantLock r15 = r11.lock
|
||
|
boolean r0 = r15.isHeldByCurrentThread()
|
||
|
boolean r1 = java.lang.Thread.interrupted()
|
||
|
boolean r2 = r11.fair // Catch: java.lang.Throwable -> L72
|
||
|
r3 = 0
|
||
|
r4 = 0
|
||
|
r6 = 1
|
||
|
if (r2 != 0) goto L23
|
||
|
boolean r2 = r15.tryLock() // Catch: java.lang.Throwable -> L72
|
||
|
if (r2 != 0) goto L21
|
||
|
goto L23
|
||
|
L21:
|
||
|
r7 = r4
|
||
|
goto L30
|
||
|
L23:
|
||
|
long r7 = initNanoTime(r13) // Catch: java.lang.Throwable -> L72
|
||
|
r9 = r13
|
||
|
L28:
|
||
|
java.util.concurrent.TimeUnit r2 = java.util.concurrent.TimeUnit.NANOSECONDS // Catch: java.lang.InterruptedException -> L6a java.lang.Throwable -> L72
|
||
|
boolean r2 = r15.tryLock(r9, r2) // Catch: java.lang.InterruptedException -> L6a java.lang.Throwable -> L72
|
||
|
if (r2 == 0) goto L60
|
||
|
L30:
|
||
|
boolean r2 = r12.isSatisfied() // Catch: java.lang.Throwable -> L58 java.lang.InterruptedException -> L5d
|
||
|
if (r2 == 0) goto L37
|
||
|
goto L49
|
||
|
L37:
|
||
|
int r2 = (r7 > r4 ? 1 : (r7 == r4 ? 0 : -1))
|
||
|
if (r2 != 0) goto L41
|
||
|
long r7 = initNanoTime(r13) // Catch: java.lang.Throwable -> L58 java.lang.InterruptedException -> L5d
|
||
|
r9 = r13
|
||
|
goto L45
|
||
|
L41:
|
||
|
long r9 = remainingNanos(r7, r13) // Catch: java.lang.Throwable -> L58 java.lang.InterruptedException -> L5d
|
||
|
L45:
|
||
|
boolean r6 = r11.awaitNanos(r12, r9, r0) // Catch: java.lang.Throwable -> L58 java.lang.InterruptedException -> L5d
|
||
|
L49:
|
||
|
if (r6 != 0) goto L4e
|
||
|
r15.unlock() // Catch: java.lang.Throwable -> L72
|
||
|
L4e:
|
||
|
if (r1 == 0) goto L57
|
||
|
java.lang.Thread r12 = java.lang.Thread.currentThread()
|
||
|
r12.interrupt()
|
||
|
L57:
|
||
|
return r6
|
||
|
L58:
|
||
|
r12 = move-exception
|
||
|
r15.unlock() // Catch: java.lang.Throwable -> L72
|
||
|
throw r12 // Catch: java.lang.Throwable -> L72
|
||
|
L5d:
|
||
|
r0 = r3
|
||
|
r1 = r6
|
||
|
goto L30
|
||
|
L60:
|
||
|
if (r1 == 0) goto L69
|
||
|
java.lang.Thread r12 = java.lang.Thread.currentThread()
|
||
|
r12.interrupt()
|
||
|
L69:
|
||
|
return r3
|
||
|
L6a:
|
||
|
long r9 = remainingNanos(r7, r13) // Catch: java.lang.Throwable -> L70
|
||
|
r1 = r6
|
||
|
goto L28
|
||
|
L70:
|
||
|
r12 = move-exception
|
||
|
goto L74
|
||
|
L72:
|
||
|
r12 = move-exception
|
||
|
r6 = r1
|
||
|
L74:
|
||
|
if (r6 == 0) goto L7d
|
||
|
java.lang.Thread r13 = java.lang.Thread.currentThread()
|
||
|
r13.interrupt()
|
||
|
L7d:
|
||
|
throw r12
|
||
|
L7e:
|
||
|
java.lang.IllegalMonitorStateException r12 = new java.lang.IllegalMonitorStateException
|
||
|
r12.<init>()
|
||
|
throw r12
|
||
|
*/
|
||
|
throw new UnsupportedOperationException("Method not decompiled: com.google.common.util.concurrent.Monitor.enterWhenUninterruptibly(com.google.common.util.concurrent.Monitor$Guard, long, java.util.concurrent.TimeUnit):boolean");
|
||
|
}
|
||
|
|
||
|
public final boolean enterIf(Guard guard) {
|
||
|
if (guard.monitor != this) {
|
||
|
throw new IllegalMonitorStateException();
|
||
|
}
|
||
|
ReentrantLock reentrantLock = this.lock;
|
||
|
reentrantLock.lock();
|
||
|
try {
|
||
|
boolean isSatisfied = guard.isSatisfied();
|
||
|
if (!isSatisfied) {
|
||
|
}
|
||
|
return isSatisfied;
|
||
|
} finally {
|
||
|
reentrantLock.unlock();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public final boolean enterIf(Guard guard, long j, TimeUnit timeUnit) {
|
||
|
if (guard.monitor != this) {
|
||
|
throw new IllegalMonitorStateException();
|
||
|
}
|
||
|
if (!enter(j, timeUnit)) {
|
||
|
return false;
|
||
|
}
|
||
|
try {
|
||
|
boolean isSatisfied = guard.isSatisfied();
|
||
|
if (!isSatisfied) {
|
||
|
}
|
||
|
return isSatisfied;
|
||
|
} finally {
|
||
|
this.lock.unlock();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public final boolean enterIfInterruptibly(Guard guard) throws InterruptedException {
|
||
|
if (guard.monitor != this) {
|
||
|
throw new IllegalMonitorStateException();
|
||
|
}
|
||
|
ReentrantLock reentrantLock = this.lock;
|
||
|
reentrantLock.lockInterruptibly();
|
||
|
try {
|
||
|
boolean isSatisfied = guard.isSatisfied();
|
||
|
if (!isSatisfied) {
|
||
|
}
|
||
|
return isSatisfied;
|
||
|
} finally {
|
||
|
reentrantLock.unlock();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public final boolean enterIfInterruptibly(Guard guard, long j, TimeUnit timeUnit) throws InterruptedException {
|
||
|
if (guard.monitor != this) {
|
||
|
throw new IllegalMonitorStateException();
|
||
|
}
|
||
|
ReentrantLock reentrantLock = this.lock;
|
||
|
if (!reentrantLock.tryLock(j, timeUnit)) {
|
||
|
return false;
|
||
|
}
|
||
|
try {
|
||
|
boolean isSatisfied = guard.isSatisfied();
|
||
|
if (!isSatisfied) {
|
||
|
}
|
||
|
return isSatisfied;
|
||
|
} finally {
|
||
|
reentrantLock.unlock();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public final boolean tryEnterIf(Guard guard) {
|
||
|
if (guard.monitor != this) {
|
||
|
throw new IllegalMonitorStateException();
|
||
|
}
|
||
|
ReentrantLock reentrantLock = this.lock;
|
||
|
if (!reentrantLock.tryLock()) {
|
||
|
return false;
|
||
|
}
|
||
|
try {
|
||
|
boolean isSatisfied = guard.isSatisfied();
|
||
|
if (!isSatisfied) {
|
||
|
}
|
||
|
return isSatisfied;
|
||
|
} finally {
|
||
|
reentrantLock.unlock();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public final void waitFor(Guard guard) throws InterruptedException {
|
||
|
if (!((guard.monitor == this) & this.lock.isHeldByCurrentThread())) {
|
||
|
throw new IllegalMonitorStateException();
|
||
|
}
|
||
|
if (guard.isSatisfied()) {
|
||
|
return;
|
||
|
}
|
||
|
await(guard, true);
|
||
|
}
|
||
|
|
||
|
public final boolean waitFor(Guard guard, long j, TimeUnit timeUnit) throws InterruptedException {
|
||
|
long safeNanos = toSafeNanos(j, timeUnit);
|
||
|
if (!((guard.monitor == this) & this.lock.isHeldByCurrentThread())) {
|
||
|
throw new IllegalMonitorStateException();
|
||
|
}
|
||
|
if (guard.isSatisfied()) {
|
||
|
return true;
|
||
|
}
|
||
|
if (Thread.interrupted()) {
|
||
|
throw new InterruptedException();
|
||
|
}
|
||
|
return awaitNanos(guard, safeNanos, true);
|
||
|
}
|
||
|
|
||
|
public final void waitForUninterruptibly(Guard guard) {
|
||
|
if (!((guard.monitor == this) & this.lock.isHeldByCurrentThread())) {
|
||
|
throw new IllegalMonitorStateException();
|
||
|
}
|
||
|
if (guard.isSatisfied()) {
|
||
|
return;
|
||
|
}
|
||
|
awaitUninterruptibly(guard, true);
|
||
|
}
|
||
|
|
||
|
/* JADX WARN: Removed duplicated region for block: B:29:0x0050 */
|
||
|
/*
|
||
|
Code decompiled incorrectly, please refer to instructions dump.
|
||
|
To view partially-correct add '--show-bad-code' argument
|
||
|
*/
|
||
|
public final boolean waitForUninterruptibly(com.google.common.util.concurrent.Monitor.Guard r8, long r9, java.util.concurrent.TimeUnit r11) {
|
||
|
/*
|
||
|
r7 = this;
|
||
|
long r9 = toSafeNanos(r9, r11)
|
||
|
com.google.common.util.concurrent.Monitor r11 = r8.monitor
|
||
|
r0 = 0
|
||
|
r1 = 1
|
||
|
if (r11 != r7) goto Lc
|
||
|
r11 = r1
|
||
|
goto Ld
|
||
|
Lc:
|
||
|
r11 = r0
|
||
|
Ld:
|
||
|
java.util.concurrent.locks.ReentrantLock r2 = r7.lock
|
||
|
boolean r2 = r2.isHeldByCurrentThread()
|
||
|
r11 = r11 & r2
|
||
|
if (r11 == 0) goto L58
|
||
|
boolean r11 = r8.isSatisfied()
|
||
|
if (r11 == 0) goto L1d
|
||
|
return r1
|
||
|
L1d:
|
||
|
long r2 = initNanoTime(r9)
|
||
|
boolean r11 = java.lang.Thread.interrupted()
|
||
|
r4 = r9
|
||
|
r6 = r1
|
||
|
L27:
|
||
|
boolean r8 = r7.awaitNanos(r8, r4, r6) // Catch: java.lang.Throwable -> L35 java.lang.InterruptedException -> L38
|
||
|
if (r11 == 0) goto L34
|
||
|
java.lang.Thread r9 = java.lang.Thread.currentThread()
|
||
|
r9.interrupt()
|
||
|
L34:
|
||
|
return r8
|
||
|
L35:
|
||
|
r8 = move-exception
|
||
|
r1 = r11
|
||
|
goto L4e
|
||
|
L38:
|
||
|
boolean r11 = r8.isSatisfied() // Catch: java.lang.Throwable -> L4d
|
||
|
if (r11 == 0) goto L46
|
||
|
java.lang.Thread r8 = java.lang.Thread.currentThread()
|
||
|
r8.interrupt()
|
||
|
return r1
|
||
|
L46:
|
||
|
long r4 = remainingNanos(r2, r9) // Catch: java.lang.Throwable -> L4d
|
||
|
r6 = r0
|
||
|
r11 = r1
|
||
|
goto L27
|
||
|
L4d:
|
||
|
r8 = move-exception
|
||
|
L4e:
|
||
|
if (r1 == 0) goto L57
|
||
|
java.lang.Thread r9 = java.lang.Thread.currentThread()
|
||
|
r9.interrupt()
|
||
|
L57:
|
||
|
throw r8
|
||
|
L58:
|
||
|
java.lang.IllegalMonitorStateException r8 = new java.lang.IllegalMonitorStateException
|
||
|
r8.<init>()
|
||
|
throw r8
|
||
|
*/
|
||
|
throw new UnsupportedOperationException("Method not decompiled: com.google.common.util.concurrent.Monitor.waitForUninterruptibly(com.google.common.util.concurrent.Monitor$Guard, long, java.util.concurrent.TimeUnit):boolean");
|
||
|
}
|
||
|
|
||
|
public final void leave() {
|
||
|
ReentrantLock reentrantLock = this.lock;
|
||
|
try {
|
||
|
if (reentrantLock.getHoldCount() == 1) {
|
||
|
signalNextWaiter();
|
||
|
}
|
||
|
} finally {
|
||
|
reentrantLock.unlock();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public final boolean isOccupied() {
|
||
|
return this.lock.isLocked();
|
||
|
}
|
||
|
|
||
|
public final boolean isOccupiedByCurrentThread() {
|
||
|
return this.lock.isHeldByCurrentThread();
|
||
|
}
|
||
|
|
||
|
public final int getOccupiedDepth() {
|
||
|
return this.lock.getHoldCount();
|
||
|
}
|
||
|
|
||
|
public final int getQueueLength() {
|
||
|
return this.lock.getQueueLength();
|
||
|
}
|
||
|
|
||
|
public final boolean hasQueuedThreads() {
|
||
|
return this.lock.hasQueuedThreads();
|
||
|
}
|
||
|
|
||
|
public final boolean hasQueuedThread(Thread thread) {
|
||
|
return this.lock.hasQueuedThread(thread);
|
||
|
}
|
||
|
|
||
|
public final boolean hasWaiters(Guard guard) {
|
||
|
return getWaitQueueLength(guard) > 0;
|
||
|
}
|
||
|
|
||
|
public final int getWaitQueueLength(Guard guard) {
|
||
|
if (guard.monitor != this) {
|
||
|
throw new IllegalMonitorStateException();
|
||
|
}
|
||
|
this.lock.lock();
|
||
|
try {
|
||
|
return guard.waiterCount;
|
||
|
} finally {
|
||
|
this.lock.unlock();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static long toSafeNanos(long j, TimeUnit timeUnit) {
|
||
|
return Longs.constrainToRange(timeUnit.toNanos(j), 0L, 6917529027641081853L);
|
||
|
}
|
||
|
|
||
|
private static long initNanoTime(long j) {
|
||
|
if (j <= 0) {
|
||
|
return 0L;
|
||
|
}
|
||
|
long nanoTime = System.nanoTime();
|
||
|
if (nanoTime == 0) {
|
||
|
return 1L;
|
||
|
}
|
||
|
return nanoTime;
|
||
|
}
|
||
|
|
||
|
private static long remainingNanos(long j, long j2) {
|
||
|
if (j2 <= 0) {
|
||
|
return 0L;
|
||
|
}
|
||
|
return j2 - (System.nanoTime() - j);
|
||
|
}
|
||
|
|
||
|
private void signalNextWaiter() {
|
||
|
for (Guard guard = this.activeGuards; guard != null; guard = guard.next) {
|
||
|
if (isSatisfied(guard)) {
|
||
|
guard.condition.signal();
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private boolean isSatisfied(Guard guard) {
|
||
|
try {
|
||
|
return guard.isSatisfied();
|
||
|
} catch (Throwable th) {
|
||
|
signalAllWaiters();
|
||
|
throw th;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void signalAllWaiters() {
|
||
|
for (Guard guard = this.activeGuards; guard != null; guard = guard.next) {
|
||
|
guard.condition.signalAll();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void beginWaitingFor(Guard guard) {
|
||
|
int i = guard.waiterCount;
|
||
|
guard.waiterCount = i + 1;
|
||
|
if (i == 0) {
|
||
|
guard.next = this.activeGuards;
|
||
|
this.activeGuards = guard;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void endWaitingFor(Guard guard) {
|
||
|
int i = guard.waiterCount - 1;
|
||
|
guard.waiterCount = i;
|
||
|
if (i == 0) {
|
||
|
Guard guard2 = this.activeGuards;
|
||
|
Guard guard3 = null;
|
||
|
while (guard2 != guard) {
|
||
|
guard3 = guard2;
|
||
|
guard2 = guard2.next;
|
||
|
}
|
||
|
if (guard3 == null) {
|
||
|
this.activeGuards = guard2.next;
|
||
|
} else {
|
||
|
guard3.next = guard2.next;
|
||
|
}
|
||
|
guard2.next = null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void await(Guard guard, boolean z) throws InterruptedException {
|
||
|
if (z) {
|
||
|
signalNextWaiter();
|
||
|
}
|
||
|
beginWaitingFor(guard);
|
||
|
do {
|
||
|
try {
|
||
|
guard.condition.await();
|
||
|
} finally {
|
||
|
endWaitingFor(guard);
|
||
|
}
|
||
|
} while (!guard.isSatisfied());
|
||
|
}
|
||
|
|
||
|
private void awaitUninterruptibly(Guard guard, boolean z) {
|
||
|
if (z) {
|
||
|
signalNextWaiter();
|
||
|
}
|
||
|
beginWaitingFor(guard);
|
||
|
do {
|
||
|
try {
|
||
|
guard.condition.awaitUninterruptibly();
|
||
|
} finally {
|
||
|
endWaitingFor(guard);
|
||
|
}
|
||
|
} while (!guard.isSatisfied());
|
||
|
}
|
||
|
|
||
|
private boolean awaitNanos(Guard guard, long j, boolean z) throws InterruptedException {
|
||
|
boolean z2 = true;
|
||
|
while (j > 0) {
|
||
|
if (z2) {
|
||
|
if (z) {
|
||
|
try {
|
||
|
signalNextWaiter();
|
||
|
} finally {
|
||
|
if (!z2) {
|
||
|
endWaitingFor(guard);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
beginWaitingFor(guard);
|
||
|
z2 = false;
|
||
|
}
|
||
|
j = guard.condition.awaitNanos(j);
|
||
|
if (guard.isSatisfied()) {
|
||
|
if (!z2) {
|
||
|
endWaitingFor(guard);
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public final boolean isFair() {
|
||
|
return this.fair;
|
||
|
}
|
||
|
}
|