134 lines
4.9 KiB
Java
134 lines
4.9 KiB
Java
|
package io.grpc;
|
||
|
|
||
|
import com.google.common.base.Preconditions;
|
||
|
import java.lang.Thread;
|
||
|
import java.util.Queue;
|
||
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||
|
import java.util.concurrent.Executor;
|
||
|
import java.util.concurrent.ScheduledExecutorService;
|
||
|
import java.util.concurrent.ScheduledFuture;
|
||
|
import java.util.concurrent.TimeUnit;
|
||
|
import java.util.concurrent.atomic.AtomicReference;
|
||
|
|
||
|
/* loaded from: classes6.dex */
|
||
|
public final class SynchronizationContext implements Executor {
|
||
|
private final Thread.UncaughtExceptionHandler uncaughtExceptionHandler;
|
||
|
private final Queue<Runnable> queue = new ConcurrentLinkedQueue();
|
||
|
private final AtomicReference<Thread> drainingThread = new AtomicReference<>();
|
||
|
|
||
|
public SynchronizationContext(Thread.UncaughtExceptionHandler uncaughtExceptionHandler) {
|
||
|
this.uncaughtExceptionHandler = (Thread.UncaughtExceptionHandler) Preconditions.checkNotNull(uncaughtExceptionHandler, "uncaughtExceptionHandler");
|
||
|
}
|
||
|
|
||
|
public final void drain() {
|
||
|
do {
|
||
|
AtomicReference<Thread> atomicReference = this.drainingThread;
|
||
|
Thread currentThread = Thread.currentThread();
|
||
|
while (!atomicReference.compareAndSet(null, currentThread)) {
|
||
|
if (atomicReference.get() != null) {
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
while (true) {
|
||
|
try {
|
||
|
Runnable poll = this.queue.poll();
|
||
|
if (poll == null) {
|
||
|
break;
|
||
|
}
|
||
|
try {
|
||
|
poll.run();
|
||
|
} catch (Throwable th) {
|
||
|
this.uncaughtExceptionHandler.uncaughtException(Thread.currentThread(), th);
|
||
|
}
|
||
|
} catch (Throwable th2) {
|
||
|
this.drainingThread.set(null);
|
||
|
throw th2;
|
||
|
}
|
||
|
}
|
||
|
this.drainingThread.set(null);
|
||
|
} while (!this.queue.isEmpty());
|
||
|
}
|
||
|
|
||
|
public final void executeLater(Runnable runnable) {
|
||
|
this.queue.add((Runnable) Preconditions.checkNotNull(runnable, "runnable is null"));
|
||
|
}
|
||
|
|
||
|
@Override // java.util.concurrent.Executor
|
||
|
public final void execute(Runnable runnable) {
|
||
|
executeLater(runnable);
|
||
|
drain();
|
||
|
}
|
||
|
|
||
|
public final void throwIfNotInThisSynchronizationContext() {
|
||
|
Preconditions.checkState(Thread.currentThread() == this.drainingThread.get(), "Not called from the SynchronizationContext");
|
||
|
}
|
||
|
|
||
|
public final ScheduledHandle schedule(Runnable runnable, long j, TimeUnit timeUnit, ScheduledExecutorService scheduledExecutorService) {
|
||
|
ManagedRunnable managedRunnable = new ManagedRunnable(runnable);
|
||
|
return new ScheduledHandle(managedRunnable, scheduledExecutorService.schedule(new Runnable(this, managedRunnable, runnable) { // from class: io.grpc.SynchronizationContext.1
|
||
|
final SynchronizationContext this$0;
|
||
|
final ManagedRunnable val$runnable;
|
||
|
final Runnable val$task;
|
||
|
|
||
|
{
|
||
|
this.this$0 = this;
|
||
|
this.val$runnable = managedRunnable;
|
||
|
this.val$task = runnable;
|
||
|
}
|
||
|
|
||
|
@Override // java.lang.Runnable
|
||
|
public void run() {
|
||
|
this.this$0.execute(this.val$runnable);
|
||
|
}
|
||
|
|
||
|
public String toString() {
|
||
|
StringBuilder sb = new StringBuilder();
|
||
|
sb.append(this.val$task.toString());
|
||
|
sb.append("(scheduled in SynchronizationContext)");
|
||
|
return sb.toString();
|
||
|
}
|
||
|
}, j, timeUnit));
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
/* loaded from: classes6.dex */
|
||
|
public static class ManagedRunnable implements Runnable {
|
||
|
boolean hasStarted;
|
||
|
boolean isCancelled;
|
||
|
final Runnable task;
|
||
|
|
||
|
ManagedRunnable(Runnable runnable) {
|
||
|
this.task = (Runnable) Preconditions.checkNotNull(runnable, "task");
|
||
|
}
|
||
|
|
||
|
@Override // java.lang.Runnable
|
||
|
public void run() {
|
||
|
if (this.isCancelled) {
|
||
|
return;
|
||
|
}
|
||
|
this.hasStarted = true;
|
||
|
this.task.run();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* loaded from: classes6.dex */
|
||
|
public static final class ScheduledHandle {
|
||
|
private final ScheduledFuture<?> future;
|
||
|
private final ManagedRunnable runnable;
|
||
|
|
||
|
private ScheduledHandle(ManagedRunnable managedRunnable, ScheduledFuture<?> scheduledFuture) {
|
||
|
this.runnable = (ManagedRunnable) Preconditions.checkNotNull(managedRunnable, "runnable");
|
||
|
this.future = (ScheduledFuture) Preconditions.checkNotNull(scheduledFuture, "future");
|
||
|
}
|
||
|
|
||
|
public final void cancel() {
|
||
|
this.runnable.isCancelled = true;
|
||
|
this.future.cancel(false);
|
||
|
}
|
||
|
|
||
|
public final boolean isPending() {
|
||
|
return (this.runnable.hasStarted || this.runnable.isCancelled) ? false : true;
|
||
|
}
|
||
|
}
|
||
|
}
|