136 lines
5.5 KiB
Java
136 lines
5.5 KiB
Java
|
package io.grpc.internal;
|
||
|
|
||
|
import com.google.common.base.Preconditions;
|
||
|
import java.util.IdentityHashMap;
|
||
|
import java.util.concurrent.Executors;
|
||
|
import java.util.concurrent.ScheduledExecutorService;
|
||
|
import java.util.concurrent.ScheduledFuture;
|
||
|
import java.util.concurrent.TimeUnit;
|
||
|
|
||
|
/* loaded from: classes6.dex */
|
||
|
public final class SharedResourceHolder {
|
||
|
static final long DESTROY_DELAY_SECONDS = 1;
|
||
|
private static final SharedResourceHolder holder = new SharedResourceHolder(new ScheduledExecutorFactory() { // from class: io.grpc.internal.SharedResourceHolder.1
|
||
|
@Override // io.grpc.internal.SharedResourceHolder.ScheduledExecutorFactory
|
||
|
public ScheduledExecutorService createScheduledExecutor() {
|
||
|
return Executors.newSingleThreadScheduledExecutor(GrpcUtil.getThreadFactory("grpc-shared-destroyer-%d", true));
|
||
|
}
|
||
|
});
|
||
|
private ScheduledExecutorService destroyer;
|
||
|
private final ScheduledExecutorFactory destroyerFactory;
|
||
|
private final IdentityHashMap<Resource<?>, Instance> instances = new IdentityHashMap<>();
|
||
|
|
||
|
/* loaded from: classes6.dex */
|
||
|
public interface Resource<T> {
|
||
|
void close(T t);
|
||
|
|
||
|
T create();
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
/* loaded from: classes6.dex */
|
||
|
public interface ScheduledExecutorFactory {
|
||
|
ScheduledExecutorService createScheduledExecutor();
|
||
|
}
|
||
|
|
||
|
SharedResourceHolder(ScheduledExecutorFactory scheduledExecutorFactory) {
|
||
|
this.destroyerFactory = scheduledExecutorFactory;
|
||
|
}
|
||
|
|
||
|
public static <T> T get(Resource<T> resource) {
|
||
|
return (T) holder.getInternal(resource);
|
||
|
}
|
||
|
|
||
|
public static <T> T release(Resource<T> resource, T t) {
|
||
|
return (T) holder.releaseInternal(resource, t);
|
||
|
}
|
||
|
|
||
|
final <T> T getInternal(Resource<T> resource) {
|
||
|
T t;
|
||
|
synchronized (this) {
|
||
|
Instance instance = this.instances.get(resource);
|
||
|
if (instance == null) {
|
||
|
instance = new Instance(resource.create());
|
||
|
this.instances.put(resource, instance);
|
||
|
}
|
||
|
if (instance.destroyTask != null) {
|
||
|
instance.destroyTask.cancel(false);
|
||
|
instance.destroyTask = null;
|
||
|
}
|
||
|
instance.refcount++;
|
||
|
t = (T) instance.payload;
|
||
|
}
|
||
|
return t;
|
||
|
}
|
||
|
|
||
|
final <T> T releaseInternal(Resource<T> resource, T t) {
|
||
|
synchronized (this) {
|
||
|
Instance instance = this.instances.get(resource);
|
||
|
if (instance == null) {
|
||
|
StringBuilder sb = new StringBuilder("No cached instance found for ");
|
||
|
sb.append(resource);
|
||
|
throw new IllegalArgumentException(sb.toString());
|
||
|
}
|
||
|
Preconditions.checkArgument(t == instance.payload, "Releasing the wrong instance");
|
||
|
Preconditions.checkState(instance.refcount > 0, "Refcount has already reached zero");
|
||
|
instance.refcount--;
|
||
|
if (instance.refcount == 0) {
|
||
|
Preconditions.checkState(instance.destroyTask == null, "Destroy task already scheduled");
|
||
|
if (this.destroyer == null) {
|
||
|
this.destroyer = this.destroyerFactory.createScheduledExecutor();
|
||
|
}
|
||
|
instance.destroyTask = this.destroyer.schedule(new LogExceptionRunnable(new Runnable(this, instance, resource, t) { // from class: io.grpc.internal.SharedResourceHolder.2
|
||
|
final SharedResourceHolder this$0;
|
||
|
final Instance val$cached;
|
||
|
final Object val$instance;
|
||
|
final Resource val$resource;
|
||
|
|
||
|
{
|
||
|
this.this$0 = this;
|
||
|
this.val$cached = instance;
|
||
|
this.val$resource = resource;
|
||
|
this.val$instance = t;
|
||
|
}
|
||
|
|
||
|
/* JADX WARN: Finally extract failed */
|
||
|
@Override // java.lang.Runnable
|
||
|
public void run() {
|
||
|
synchronized (this.this$0) {
|
||
|
if (this.val$cached.refcount == 0) {
|
||
|
try {
|
||
|
this.val$resource.close(this.val$instance);
|
||
|
this.this$0.instances.remove(this.val$resource);
|
||
|
if (this.this$0.instances.isEmpty()) {
|
||
|
this.this$0.destroyer.shutdown();
|
||
|
this.this$0.destroyer = null;
|
||
|
}
|
||
|
} catch (Throwable th) {
|
||
|
this.this$0.instances.remove(this.val$resource);
|
||
|
if (this.this$0.instances.isEmpty()) {
|
||
|
this.this$0.destroyer.shutdown();
|
||
|
this.this$0.destroyer = null;
|
||
|
}
|
||
|
throw th;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}), DESTROY_DELAY_SECONDS, TimeUnit.SECONDS);
|
||
|
}
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
/* loaded from: classes6.dex */
|
||
|
public static class Instance {
|
||
|
ScheduledFuture<?> destroyTask;
|
||
|
final Object payload;
|
||
|
int refcount;
|
||
|
|
||
|
Instance(Object obj) {
|
||
|
this.payload = obj;
|
||
|
}
|
||
|
}
|
||
|
}
|