377 lines
14 KiB
Java
377 lines
14 KiB
Java
|
package okhttp3.internal.concurrent;
|
||
|
|
||
|
import com.huawei.hms.android.HwBuildEx;
|
||
|
import java.util.ArrayList;
|
||
|
import java.util.Iterator;
|
||
|
import java.util.List;
|
||
|
import java.util.concurrent.SynchronousQueue;
|
||
|
import java.util.concurrent.ThreadFactory;
|
||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||
|
import java.util.concurrent.TimeUnit;
|
||
|
import java.util.logging.Level;
|
||
|
import java.util.logging.Logger;
|
||
|
import o.C14866gag;
|
||
|
import o.C14881gav;
|
||
|
import o.C14953gcr;
|
||
|
import o.C14957gcv;
|
||
|
import okhttp3.internal.Util;
|
||
|
|
||
|
/* loaded from: classes.dex */
|
||
|
public final class TaskRunner {
|
||
|
public static final Companion Companion = new Companion(null);
|
||
|
public static final TaskRunner INSTANCE = new TaskRunner(new RealBackend(Util.threadFactory(C14957gcv.c(Util.okHttpName, (Object) " TaskRunner"), true)));
|
||
|
private static final Logger logger;
|
||
|
private final Backend backend;
|
||
|
private final List<TaskQueue> busyQueues;
|
||
|
private boolean coordinatorWaiting;
|
||
|
private long coordinatorWakeUpAt;
|
||
|
private int nextQueueName;
|
||
|
private final List<TaskQueue> readyQueues;
|
||
|
private final Runnable runnable;
|
||
|
|
||
|
/* loaded from: classes.dex */
|
||
|
public interface Backend {
|
||
|
void beforeTask(TaskRunner taskRunner);
|
||
|
|
||
|
void coordinatorNotify(TaskRunner taskRunner);
|
||
|
|
||
|
void coordinatorWait(TaskRunner taskRunner, long j);
|
||
|
|
||
|
void execute(Runnable runnable);
|
||
|
|
||
|
long nanoTime();
|
||
|
}
|
||
|
|
||
|
public TaskRunner(Backend backend) {
|
||
|
C14957gcv.e(backend, "");
|
||
|
this.backend = backend;
|
||
|
this.nextQueueName = HwBuildEx.VersionCodes.CUR_DEVELOPMENT;
|
||
|
this.busyQueues = new ArrayList();
|
||
|
this.readyQueues = new ArrayList();
|
||
|
this.runnable = new Runnable(this) { // from class: okhttp3.internal.concurrent.TaskRunner$runnable$1
|
||
|
final TaskRunner this$0;
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
{
|
||
|
this.this$0 = this;
|
||
|
}
|
||
|
|
||
|
@Override // java.lang.Runnable
|
||
|
public final void run() {
|
||
|
Task awaitTaskToRun;
|
||
|
long j;
|
||
|
while (true) {
|
||
|
TaskRunner taskRunner = this.this$0;
|
||
|
synchronized (taskRunner) {
|
||
|
awaitTaskToRun = taskRunner.awaitTaskToRun();
|
||
|
}
|
||
|
if (awaitTaskToRun == null) {
|
||
|
return;
|
||
|
}
|
||
|
TaskQueue queue$okhttp = awaitTaskToRun.getQueue$okhttp();
|
||
|
C14957gcv.e(queue$okhttp);
|
||
|
TaskRunner taskRunner2 = this.this$0;
|
||
|
boolean isLoggable = TaskRunner.Companion.getLogger().isLoggable(Level.FINE);
|
||
|
if (isLoggable) {
|
||
|
j = queue$okhttp.getTaskRunner$okhttp().getBackend().nanoTime();
|
||
|
TaskLoggerKt.access$log(awaitTaskToRun, queue$okhttp, "starting");
|
||
|
} else {
|
||
|
j = -1;
|
||
|
}
|
||
|
try {
|
||
|
try {
|
||
|
taskRunner2.runTask(awaitTaskToRun);
|
||
|
C14866gag c14866gag = C14866gag.c;
|
||
|
if (isLoggable) {
|
||
|
TaskLoggerKt.access$log(awaitTaskToRun, queue$okhttp, C14957gcv.c("finished run in ", (Object) TaskLoggerKt.formatDuration(queue$okhttp.getTaskRunner$okhttp().getBackend().nanoTime() - j)));
|
||
|
}
|
||
|
} finally {
|
||
|
}
|
||
|
} catch (Throwable th) {
|
||
|
if (isLoggable) {
|
||
|
TaskLoggerKt.access$log(awaitTaskToRun, queue$okhttp, C14957gcv.c("failed a run in ", (Object) TaskLoggerKt.formatDuration(queue$okhttp.getTaskRunner$okhttp().getBackend().nanoTime() - j)));
|
||
|
}
|
||
|
throw th;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
public final TaskQueue newQueue() {
|
||
|
int i;
|
||
|
synchronized (this) {
|
||
|
i = this.nextQueueName;
|
||
|
this.nextQueueName = i + 1;
|
||
|
}
|
||
|
return new TaskQueue(this, C14957gcv.c("Q", Integer.valueOf(i)));
|
||
|
}
|
||
|
|
||
|
public final List<TaskQueue> activeQueues() {
|
||
|
List<TaskQueue> e;
|
||
|
synchronized (this) {
|
||
|
e = C14881gav.e(this.busyQueues, this.readyQueues);
|
||
|
}
|
||
|
return e;
|
||
|
}
|
||
|
|
||
|
public final void cancelAll() {
|
||
|
int size = this.busyQueues.size() - 1;
|
||
|
if (size >= 0) {
|
||
|
while (true) {
|
||
|
int i = size - 1;
|
||
|
this.busyQueues.get(size).cancelAllAndDecide$okhttp();
|
||
|
if (i < 0) {
|
||
|
break;
|
||
|
} else {
|
||
|
size = i;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
int size2 = this.readyQueues.size() - 1;
|
||
|
if (size2 < 0) {
|
||
|
return;
|
||
|
}
|
||
|
while (true) {
|
||
|
int i2 = size2 - 1;
|
||
|
TaskQueue taskQueue = this.readyQueues.get(size2);
|
||
|
taskQueue.cancelAllAndDecide$okhttp();
|
||
|
if (taskQueue.getFutureTasks$okhttp().isEmpty()) {
|
||
|
this.readyQueues.remove(size2);
|
||
|
}
|
||
|
if (i2 < 0) {
|
||
|
return;
|
||
|
} else {
|
||
|
size2 = i2;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* loaded from: classes.dex */
|
||
|
public static final class RealBackend implements Backend {
|
||
|
private final ThreadPoolExecutor executor;
|
||
|
|
||
|
public RealBackend(ThreadFactory threadFactory) {
|
||
|
C14957gcv.e(threadFactory, "");
|
||
|
this.executor = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue(), threadFactory);
|
||
|
}
|
||
|
|
||
|
@Override // okhttp3.internal.concurrent.TaskRunner.Backend
|
||
|
public final long nanoTime() {
|
||
|
return System.nanoTime();
|
||
|
}
|
||
|
|
||
|
@Override // okhttp3.internal.concurrent.TaskRunner.Backend
|
||
|
public final void coordinatorWait(TaskRunner taskRunner, long j) throws InterruptedException {
|
||
|
C14957gcv.e(taskRunner, "");
|
||
|
long j2 = j / 1000000;
|
||
|
if (j2 > 0 || j > 0) {
|
||
|
taskRunner.wait(j2, (int) (j - (1000000 * j2)));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override // okhttp3.internal.concurrent.TaskRunner.Backend
|
||
|
public final void execute(Runnable runnable) {
|
||
|
C14957gcv.e(runnable, "");
|
||
|
this.executor.execute(runnable);
|
||
|
}
|
||
|
|
||
|
public final void shutdown() {
|
||
|
this.executor.shutdown();
|
||
|
}
|
||
|
|
||
|
@Override // okhttp3.internal.concurrent.TaskRunner.Backend
|
||
|
public final void coordinatorNotify(TaskRunner taskRunner) {
|
||
|
C14957gcv.e(taskRunner, "");
|
||
|
taskRunner.notify();
|
||
|
}
|
||
|
|
||
|
@Override // okhttp3.internal.concurrent.TaskRunner.Backend
|
||
|
public final void beforeTask(TaskRunner taskRunner) {
|
||
|
C14957gcv.e(taskRunner, "");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* loaded from: classes.dex */
|
||
|
public static final class Companion {
|
||
|
private Companion() {
|
||
|
}
|
||
|
|
||
|
public final Logger getLogger() {
|
||
|
return TaskRunner.logger;
|
||
|
}
|
||
|
|
||
|
public /* synthetic */ Companion(C14953gcr c14953gcr) {
|
||
|
this();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static {
|
||
|
Logger logger2 = Logger.getLogger(TaskRunner.class.getName());
|
||
|
C14957gcv.c(logger2, "");
|
||
|
logger = logger2;
|
||
|
}
|
||
|
|
||
|
public final void kickCoordinator$okhttp(TaskQueue taskQueue) {
|
||
|
C14957gcv.e(taskQueue, "");
|
||
|
if (!Util.assertionsEnabled || Thread.holdsLock(this)) {
|
||
|
if (taskQueue.getActiveTask$okhttp() == null) {
|
||
|
if (!taskQueue.getFutureTasks$okhttp().isEmpty()) {
|
||
|
Util.addIfAbsent(this.readyQueues, taskQueue);
|
||
|
} else {
|
||
|
this.readyQueues.remove(taskQueue);
|
||
|
}
|
||
|
}
|
||
|
if (this.coordinatorWaiting) {
|
||
|
this.backend.coordinatorNotify(this);
|
||
|
return;
|
||
|
} else {
|
||
|
this.backend.execute(this.runnable);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
StringBuilder sb = new StringBuilder("Thread ");
|
||
|
sb.append((Object) Thread.currentThread().getName());
|
||
|
sb.append(" MUST hold lock on ");
|
||
|
sb.append(this);
|
||
|
throw new AssertionError(sb.toString());
|
||
|
}
|
||
|
|
||
|
private final void beforeRun(Task task) {
|
||
|
if (!Util.assertionsEnabled || Thread.holdsLock(this)) {
|
||
|
task.setNextExecuteNanoTime$okhttp(-1L);
|
||
|
TaskQueue queue$okhttp = task.getQueue$okhttp();
|
||
|
C14957gcv.e(queue$okhttp);
|
||
|
queue$okhttp.getFutureTasks$okhttp().remove(task);
|
||
|
this.readyQueues.remove(queue$okhttp);
|
||
|
queue$okhttp.setActiveTask$okhttp(task);
|
||
|
this.busyQueues.add(queue$okhttp);
|
||
|
return;
|
||
|
}
|
||
|
StringBuilder sb = new StringBuilder("Thread ");
|
||
|
sb.append((Object) Thread.currentThread().getName());
|
||
|
sb.append(" MUST hold lock on ");
|
||
|
sb.append(this);
|
||
|
throw new AssertionError(sb.toString());
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: private */
|
||
|
public final void runTask(Task task) {
|
||
|
if (Util.assertionsEnabled && Thread.holdsLock(this)) {
|
||
|
StringBuilder sb = new StringBuilder("Thread ");
|
||
|
sb.append((Object) Thread.currentThread().getName());
|
||
|
sb.append(" MUST NOT hold lock on ");
|
||
|
sb.append(this);
|
||
|
throw new AssertionError(sb.toString());
|
||
|
}
|
||
|
Thread currentThread = Thread.currentThread();
|
||
|
String name = currentThread.getName();
|
||
|
currentThread.setName(task.getName());
|
||
|
try {
|
||
|
long runOnce = task.runOnce();
|
||
|
synchronized (this) {
|
||
|
afterRun(task, runOnce);
|
||
|
C14866gag c14866gag = C14866gag.c;
|
||
|
}
|
||
|
currentThread.setName(name);
|
||
|
} catch (Throwable th) {
|
||
|
synchronized (this) {
|
||
|
afterRun(task, -1L);
|
||
|
C14866gag c14866gag2 = C14866gag.c;
|
||
|
currentThread.setName(name);
|
||
|
throw th;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private final void afterRun(Task task, long j) {
|
||
|
if (!Util.assertionsEnabled || Thread.holdsLock(this)) {
|
||
|
TaskQueue queue$okhttp = task.getQueue$okhttp();
|
||
|
C14957gcv.e(queue$okhttp);
|
||
|
if (queue$okhttp.getActiveTask$okhttp() != task) {
|
||
|
throw new IllegalStateException("Check failed.".toString());
|
||
|
}
|
||
|
boolean cancelActiveTask$okhttp = queue$okhttp.getCancelActiveTask$okhttp();
|
||
|
queue$okhttp.setCancelActiveTask$okhttp(false);
|
||
|
queue$okhttp.setActiveTask$okhttp(null);
|
||
|
this.busyQueues.remove(queue$okhttp);
|
||
|
if (j != -1 && !cancelActiveTask$okhttp && !queue$okhttp.getShutdown$okhttp()) {
|
||
|
queue$okhttp.scheduleAndDecide$okhttp(task, j, true);
|
||
|
}
|
||
|
if (!queue$okhttp.getFutureTasks$okhttp().isEmpty()) {
|
||
|
this.readyQueues.add(queue$okhttp);
|
||
|
return;
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
StringBuilder sb = new StringBuilder("Thread ");
|
||
|
sb.append((Object) Thread.currentThread().getName());
|
||
|
sb.append(" MUST hold lock on ");
|
||
|
sb.append(this);
|
||
|
throw new AssertionError(sb.toString());
|
||
|
}
|
||
|
|
||
|
public final Task awaitTaskToRun() {
|
||
|
boolean z;
|
||
|
if (!Util.assertionsEnabled || Thread.holdsLock(this)) {
|
||
|
while (!this.readyQueues.isEmpty()) {
|
||
|
long nanoTime = this.backend.nanoTime();
|
||
|
Iterator<TaskQueue> it = this.readyQueues.iterator();
|
||
|
long j = Long.MAX_VALUE;
|
||
|
Task task = null;
|
||
|
while (true) {
|
||
|
if (!it.hasNext()) {
|
||
|
z = false;
|
||
|
break;
|
||
|
}
|
||
|
Task task2 = it.next().getFutureTasks$okhttp().get(0);
|
||
|
long max = Math.max(0L, task2.getNextExecuteNanoTime$okhttp() - nanoTime);
|
||
|
if (max > 0) {
|
||
|
j = Math.min(max, j);
|
||
|
} else {
|
||
|
if (task != null) {
|
||
|
z = true;
|
||
|
break;
|
||
|
}
|
||
|
task = task2;
|
||
|
}
|
||
|
}
|
||
|
if (task != null) {
|
||
|
beforeRun(task);
|
||
|
if (z || (!this.coordinatorWaiting && (!this.readyQueues.isEmpty()))) {
|
||
|
this.backend.execute(this.runnable);
|
||
|
}
|
||
|
return task;
|
||
|
}
|
||
|
if (this.coordinatorWaiting) {
|
||
|
if (j < this.coordinatorWakeUpAt - nanoTime) {
|
||
|
this.backend.coordinatorNotify(this);
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
this.coordinatorWaiting = true;
|
||
|
this.coordinatorWakeUpAt = nanoTime + j;
|
||
|
try {
|
||
|
try {
|
||
|
this.backend.coordinatorWait(this, j);
|
||
|
} catch (InterruptedException unused) {
|
||
|
cancelAll();
|
||
|
}
|
||
|
} finally {
|
||
|
this.coordinatorWaiting = false;
|
||
|
}
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
StringBuilder sb = new StringBuilder("Thread ");
|
||
|
sb.append((Object) Thread.currentThread().getName());
|
||
|
sb.append(" MUST hold lock on ");
|
||
|
sb.append(this);
|
||
|
throw new AssertionError(sb.toString());
|
||
|
}
|
||
|
|
||
|
public final Backend getBackend() {
|
||
|
return this.backend;
|
||
|
}
|
||
|
}
|