导航菜单

页面标题

页面副标题

⁣逼‌多​多⁣ v3.6.2 - ServerImpl.java 源代码

正在查看: ⁣逼‌多​多⁣ v3.6.2 应用的 ServerImpl.java JAVA 源代码文件

本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。


package io.grpc.internal;

import com.google.common.util.concurrent.g;
import com.google.common.util.concurrent.h;
import com.google.common.util.concurrent.k;
import io.grpc.Attributes;
import io.grpc.BinaryLog;
import io.grpc.CompressorRegistry;
import io.grpc.Context;
import io.grpc.Contexts;
import io.grpc.Deadline;
import io.grpc.Decompressor;
import io.grpc.DecompressorRegistry;
import io.grpc.HandlerRegistry;
import io.grpc.InternalChannelz;
import io.grpc.InternalInstrumented;
import io.grpc.InternalLogId;
import io.grpc.InternalServerInterceptors;
import io.grpc.InternalStatus;
import io.grpc.Metadata;
import io.grpc.Server;
import io.grpc.ServerCall;
import io.grpc.ServerCallExecutorSupplier;
import io.grpc.ServerCallHandler;
import io.grpc.ServerInterceptor;
import io.grpc.ServerMethodDefinition;
import io.grpc.ServerServiceDefinition;
import io.grpc.ServerTransportFilter;
import io.grpc.Status;
import io.grpc.internal.StreamListener;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import q.l;

public final class ServerImpl extends Server implements InternalInstrumented<InternalChannelz.ServerStats> {
    private final BinaryLog binlog;
    private final InternalChannelz channelz;
    private final CompressorRegistry compressorRegistry;
    private final DecompressorRegistry decompressorRegistry;
    private Executor executor;
    private final ObjectPool<? extends Executor> executorPool;
    private final ServerCallExecutorSupplier executorSupplier;
    private final HandlerRegistry fallbackRegistry;
    private final long handshakeTimeoutMillis;
    private final ServerInterceptor[] interceptors;
    private final HandlerRegistry registry;
    private final Context rootContext;
    private final CallTracer serverCallTracer;
    private boolean serverShutdownCallbackInvoked;
    private boolean shutdown;
    private Status shutdownNowStatus;
    private boolean started;
    private boolean terminated;
    private final Deadline.Ticker ticker;
    private final List<ServerTransportFilter> transportFilters;
    private final InternalServer transportServer;
    private boolean transportServersTerminated;
    private static final Logger log = Logger.getLogger(ServerImpl.class.getName());
    private static final ServerStreamListener NOOP_LISTENER = new NoopListener();
    private final Object lock = new Object();
    private final Set<ServerTransport> transports = new HashSet();
    private final InternalLogId logId = InternalLogId.allocate("Server", String.valueOf(getListenSocketsIgnoringLifecycle()));

    static final class ContextCloser implements Runnable {
        private final Throwable cause;
        private final Context.CancellableContext context;

        ContextCloser(Context.CancellableContext cancellableContext, Throwable th) {
            this.context = cancellableContext;
            this.cause = th;
        }

        @Override
        public void run() {
            this.context.cancel(this.cause);
        }
    }

    static final class JumpToApplicationThreadServerStreamListener implements ServerStreamListener {
        private final Executor callExecutor;
        private final Executor cancelExecutor;
        private final Context.CancellableContext context;
        private ServerStreamListener listener;
        private final ServerStream stream;
        private final g1.d tag;

        public JumpToApplicationThreadServerStreamListener(Executor executor, Executor executor2, ServerStream serverStream, Context.CancellableContext cancellableContext, g1.d dVar) {
            this.callExecutor = executor;
            this.cancelExecutor = executor2;
            this.stream = serverStream;
            this.context = cancellableContext;
            this.tag = dVar;
        }

        private void closedInternal(final Status status) {
            if (!status.isOk()) {
                Throwable cause = status.getCause();
                if (cause == null) {
                    cause = InternalStatus.asRuntimeException(Status.CANCELLED.withDescription("RPC cancelled"), null, false);
                }
                this.cancelExecutor.execute(new ContextCloser(this.context, cause));
            }
            final g1.b g = g1.c.g();
            this.callExecutor.execute(new ContextRunnable() {
                {
                    super(JumpToApplicationThreadServerStreamListener.this.context);
                }

                @Override
                public void runInContext() {
                    g1.e i = g1.c.i("ServerCallListener(app).closed");
                    try {
                        g1.c.a(JumpToApplicationThreadServerStreamListener.this.tag);
                        g1.c.f(g);
                        JumpToApplicationThreadServerStreamListener.this.getListener().closed(status);
                        if (i != null) {
                            i.close();
                        }
                    } catch (Throwable th) {
                        if (i != null) {
                            try {
                                i.close();
                            } catch (Throwable th2) {
                                th.addSuppressed(th2);
                            }
                        }
                        throw th;
                    }
                }
            });
        }

        public ServerStreamListener getListener() {
            ServerStreamListener serverStreamListener = this.listener;
            if (serverStreamListener != null) {
                return serverStreamListener;
            }
            throw new IllegalStateException("listener unset");
        }

        public void internalClose(Throwable th) {
            this.stream.close(Status.UNKNOWN.withDescription("Application error processing RPC").withCause(th), new Metadata());
        }

        @Override
        public void closed(Status status) {
            g1.e i = g1.c.i("ServerStreamListener.closed");
            try {
                g1.c.a(this.tag);
                closedInternal(status);
                if (i != null) {
                    i.close();
                }
            } catch (Throwable th) {
                if (i != null) {
                    try {
                        i.close();
                    } catch (Throwable th2) {
                        th.addSuppressed(th2);
                    }
                }
                throw th;
            }
        }

        @Override
        public void halfClosed() {
            g1.e i = g1.c.i("ServerStreamListener.halfClosed");
            try {
                g1.c.a(this.tag);
                final g1.b g = g1.c.g();
                this.callExecutor.execute(new ContextRunnable() {
                    {
                        super(JumpToApplicationThreadServerStreamListener.this.context);
                    }

                    @Override
                    public void runInContext() {
                        try {
                            g1.e i2 = g1.c.i("ServerCallListener(app).halfClosed");
                            try {
                                g1.c.a(JumpToApplicationThreadServerStreamListener.this.tag);
                                g1.c.f(g);
                                JumpToApplicationThreadServerStreamListener.this.getListener().halfClosed();
                                if (i2 != null) {
                                    i2.close();
                                }
                            } finally {
                            }
                        } catch (Throwable th) {
                            JumpToApplicationThreadServerStreamListener.this.internalClose(th);
                            throw th;
                        }
                    }
                });
                if (i != null) {
                    i.close();
                }
            } catch (Throwable th) {
                if (i != null) {
                    try {
                        i.close();
                    } catch (Throwable th2) {
                        th.addSuppressed(th2);
                    }
                }
                throw th;
            }
        }

        @Override
        public void messagesAvailable(final StreamListener.MessageProducer messageProducer) {
            g1.e i = g1.c.i("ServerStreamListener.messagesAvailable");
            try {
                g1.c.a(this.tag);
                final g1.b g = g1.c.g();
                this.callExecutor.execute(new ContextRunnable() {
                    {
                        super(JumpToApplicationThreadServerStreamListener.this.context);
                    }

                    @Override
                    public void runInContext() {
                        try {
                            g1.e i2 = g1.c.i("ServerCallListener(app).messagesAvailable");
                            try {
                                g1.c.a(JumpToApplicationThreadServerStreamListener.this.tag);
                                g1.c.f(g);
                                JumpToApplicationThreadServerStreamListener.this.getListener().messagesAvailable(messageProducer);
                                if (i2 != null) {
                                    i2.close();
                                }
                            } finally {
                            }
                        } catch (Throwable th) {
                            JumpToApplicationThreadServerStreamListener.this.internalClose(th);
                            throw th;
                        }
                    }
                });
                if (i != null) {
                    i.close();
                }
            } catch (Throwable th) {
                if (i != null) {
                    try {
                        i.close();
                    } catch (Throwable th2) {
                        th.addSuppressed(th2);
                    }
                }
                throw th;
            }
        }

        @Override
        public void onReady() {
            g1.e i = g1.c.i("ServerStreamListener.onReady");
            try {
                g1.c.a(this.tag);
                final g1.b g = g1.c.g();
                this.callExecutor.execute(new ContextRunnable() {
                    {
                        super(JumpToApplicationThreadServerStreamListener.this.context);
                    }

                    @Override
                    public void runInContext() {
                        try {
                            g1.e i2 = g1.c.i("ServerCallListener(app).onReady");
                            try {
                                g1.c.a(JumpToApplicationThreadServerStreamListener.this.tag);
                                g1.c.f(g);
                                JumpToApplicationThreadServerStreamListener.this.getListener().onReady();
                                if (i2 != null) {
                                    i2.close();
                                }
                            } finally {
                            }
                        } catch (Throwable th) {
                            JumpToApplicationThreadServerStreamListener.this.internalClose(th);
                            throw th;
                        }
                    }
                });
                if (i != null) {
                    i.close();
                }
            } catch (Throwable th) {
                if (i != null) {
                    try {
                        i.close();
                    } catch (Throwable th2) {
                        th.addSuppressed(th2);
                    }
                }
                throw th;
            }
        }

        void setListener(ServerStreamListener serverStreamListener) {
            l.o(serverStreamListener, "listener must not be null");
            l.u(this.listener == null, "Listener already set");
            this.listener = serverStreamListener;
        }
    }

    private static final class NoopListener implements ServerStreamListener {
        private NoopListener() {
        }

        @Override
        public void closed(Status status) {
        }

        @Override
        public void halfClosed() {
        }

        @Override
        public void messagesAvailable(StreamListener.MessageProducer messageProducer) {
            while (true) {
                InputStream next = messageProducer.next();
                if (next == null) {
                    return;
                }
                try {
                    next.close();
                } catch (IOException e) {
                    while (true) {
                        InputStream next2 = messageProducer.next();
                        if (next2 == null) {
                            throw new RuntimeException(e);
                        }
                        try {
                            next2.close();
                        } catch (IOException e2) {
                            ServerImpl.log.log(Level.WARNING, "Exception closing stream", (Throwable) e2);
                        }
                    }
                }
            }
        }

        @Override
        public void onReady() {
        }
    }

    private final class ServerListenerImpl implements ServerListener {
        private ServerListenerImpl() {
        }

        @Override
        public void serverShutdown() {
            synchronized (ServerImpl.this.lock) {
                try {
                    if (ServerImpl.this.serverShutdownCallbackInvoked) {
                        return;
                    }
                    ArrayList arrayList = new ArrayList(ServerImpl.this.transports);
                    Status status = ServerImpl.this.shutdownNowStatus;
                    ServerImpl.this.serverShutdownCallbackInvoked = true;
                    Iterator it = arrayList.iterator();
                    while (it.hasNext()) {
                        ServerTransport serverTransport = (ServerTransport) it.next();
                        if (status == null) {
                            serverTransport.shutdown();
                        } else {
                            serverTransport.shutdownNow(status);
                        }
                    }
                    synchronized (ServerImpl.this.lock) {
                        ServerImpl.this.transportServersTerminated = true;
                        ServerImpl.this.checkForTermination();
                    }
                } catch (Throwable th) {
                    throw th;
                }
            }
        }

        @Override
        public ServerTransportListener transportCreated(ServerTransport serverTransport) {
            synchronized (ServerImpl.this.lock) {
                ServerImpl.this.transports.add(serverTransport);
            }
            ServerTransportListenerImpl serverTransportListenerImpl = ServerImpl.this.new ServerTransportListenerImpl(serverTransport);
            serverTransportListenerImpl.init();
            return serverTransportListenerImpl;
        }
    }

    private final class ServerTransportListenerImpl implements ServerTransportListener {
        private Attributes attributes;
        private Future<?> handshakeTimeoutFuture;
        private final ServerTransport transport;

        private final class ServerCallParameters<ReqT, RespT> {
            ServerCallImpl<ReqT, RespT> call;
            ServerCallHandler<ReqT, RespT> callHandler;

            public ServerCallParameters(ServerCallImpl<ReqT, RespT> serverCallImpl, ServerCallHandler<ReqT, RespT> serverCallHandler) {
                this.call = serverCallImpl;
                this.callHandler = serverCallHandler;
            }
        }

        ServerTransportListenerImpl(ServerTransport serverTransport) {
            this.transport = serverTransport;
        }

        private Context.CancellableContext createContext(Metadata metadata, StatsTraceContext statsTraceContext) {
            Long l = (Long) metadata.get(GrpcUtil.TIMEOUT_KEY);
            Context withValue = statsTraceContext.serverFilterContext(ServerImpl.this.rootContext).withValue(io.grpc.InternalServer.SERVER_CONTEXT_KEY, ServerImpl.this);
            return l == null ? withValue.withCancellation() : withValue.withDeadline(Deadline.after(l.longValue(), TimeUnit.NANOSECONDS, ServerImpl.this.ticker), this.transport.getScheduledExecutorService());
        }

        public <WReqT, WRespT> ServerStreamListener startWrappedCall(String str, ServerCallParameters<WReqT, WRespT> serverCallParameters, Metadata metadata) {
            ServerCall.Listener<WReqT> startCall = serverCallParameters.callHandler.startCall(serverCallParameters.call, metadata);
            if (startCall != null) {
                return serverCallParameters.call.newServerStreamListener(startCall);
            }
            throw new NullPointerException("startCall() returned a null listener for method " + str);
        }

        private void streamCreatedInternal(ServerStream serverStream, String str, Metadata metadata, g1.d dVar) {
            Executor serializingExecutor;
            if (ServerImpl.this.executorSupplier == null && ServerImpl.this.executor == h.a()) {
                serializingExecutor = new SerializeReentrantCallsDirectExecutor();
                serverStream.optimizeForDirectExecutor();
            } else {
                serializingExecutor = new SerializingExecutor(ServerImpl.this.executor);
            }
            Executor executor = serializingExecutor;
            Metadata.Key<String> key = GrpcUtil.MESSAGE_ENCODING_KEY;
            if (metadata.containsKey(key)) {
                String str2 = (String) metadata.get(key);
                Decompressor lookupDecompressor = ServerImpl.this.decompressorRegistry.lookupDecompressor(str2);
                if (lookupDecompressor == null) {
                    serverStream.setListener(ServerImpl.NOOP_LISTENER);
                    serverStream.close(Status.UNIMPLEMENTED.withDescription(String.format("Can't find decompressor for %s", str2)), new Metadata());
                    return;
                }
                serverStream.setDecompressor(lookupDecompressor);
            }
            StatsTraceContext statsTraceContext = (StatsTraceContext) l.o(serverStream.statsTraceContext(), "statsTraceCtx not present from stream");
            Context.CancellableContext createContext = createContext(metadata, statsTraceContext);
            g1.b g = g1.c.g();
            JumpToApplicationThreadServerStreamListener jumpToApplicationThreadServerStreamListener = new JumpToApplicationThreadServerStreamListener(executor, ServerImpl.this.executor, serverStream, createContext, dVar);
            serverStream.setListener(jumpToApplicationThreadServerStreamListener);
            k n = k.n();
            executor.execute(new ContextRunnable(createContext, dVar, g, str, serverStream, jumpToApplicationThreadServerStreamListener, n, statsTraceContext, metadata, executor) {
                final Context.CancellableContext val$context;
                final k val$future;
                final Metadata val$headers;
                final JumpToApplicationThreadServerStreamListener val$jumpListener;
                final g1.b val$link;
                final String val$methodName;
                final StatsTraceContext val$statsTraceCtx;
                final ServerStream val$stream;
                final g1.d val$tag;
                final Executor val$wrappedExecutor;

                {
                    super(createContext);
                    this.val$context = createContext;
                    this.val$tag = dVar;
                    this.val$link = g;
                    this.val$methodName = str;
                    this.val$stream = serverStream;
                    this.val$jumpListener = jumpToApplicationThreadServerStreamListener;
                    this.val$future = n;
                    this.val$statsTraceCtx = statsTraceContext;
                    this.val$headers = metadata;
                    this.val$wrappedExecutor = executor;
                }

                private <ReqT, RespT> ServerCallParameters<ReqT, RespT> maySwitchExecutor(ServerMethodDefinition<ReqT, RespT> serverMethodDefinition, ServerStream serverStream2, Metadata metadata2, Context.CancellableContext cancellableContext, g1.d dVar2) {
                    Executor executor2;
                    ServerCallImpl serverCallImpl = new ServerCallImpl(serverStream2, serverMethodDefinition.getMethodDescriptor(), metadata2, cancellableContext, ServerImpl.this.decompressorRegistry, ServerImpl.this.compressorRegistry, ServerImpl.this.serverCallTracer, dVar2);
                    if (ServerImpl.this.executorSupplier != null && (executor2 = ServerImpl.this.executorSupplier.getExecutor(serverCallImpl, metadata2)) != null) {
                        ((SerializingExecutor) this.val$wrappedExecutor).setExecutor(executor2);
                    }
                    return ServerTransportListenerImpl.this.new ServerCallParameters<>(serverCallImpl, serverMethodDefinition.getServerCallHandler());
                }

                private void runInternal() {
                    try {
                        ServerMethodDefinition<?, ?> lookupMethod = ServerImpl.this.registry.lookupMethod(this.val$methodName);
                        if (lookupMethod == null) {
                            lookupMethod = ServerImpl.this.fallbackRegistry.lookupMethod(this.val$methodName, this.val$stream.getAuthority());
                        }
                        if (lookupMethod != null) {
                            this.val$future.set(maySwitchExecutor(ServerTransportListenerImpl.this.wrapMethod(this.val$stream, lookupMethod, this.val$statsTraceCtx), this.val$stream, this.val$headers, this.val$context, this.val$tag));
                            return;
                        }
                        Status withDescription = Status.UNIMPLEMENTED.withDescription("Method not found: " + this.val$methodName);
                        this.val$jumpListener.setListener(ServerImpl.NOOP_LISTENER);
                        this.val$stream.close(withDescription, new Metadata());
                        this.val$context.cancel(null);
                        this.val$future.cancel(false);
                    } catch (Throwable th) {
                        this.val$jumpListener.setListener(ServerImpl.NOOP_LISTENER);
                        this.val$stream.close(Status.fromThrowable(th), new Metadata());
                        this.val$context.cancel(null);
                        this.val$future.cancel(false);
                        throw th;
                    }
                }

                @Override
                public void runInContext() {
                    g1.e i = g1.c.i("ServerTransportListener$MethodLookup.startCall");
                    try {
                        g1.c.a(this.val$tag);
                        g1.c.f(this.val$link);
                        runInternal();
                        if (i != null) {
                            i.close();
                        }
                    } catch (Throwable th) {
                        if (i != null) {
                            try {
                                i.close();
                            } catch (Throwable th2) {
                                th.addSuppressed(th2);
                            }
                        }
                        throw th;
                    }
                }
            });
            executor.execute(new ContextRunnable(createContext, g, dVar, n, str, metadata, serverStream, jumpToApplicationThreadServerStreamListener) {
                final Context.CancellableContext val$context;
                final k val$future;
                final Metadata val$headers;
                final JumpToApplicationThreadServerStreamListener val$jumpListener;
                final g1.b val$link;
                final String val$methodName;
                final ServerStream val$stream;
                final g1.d val$tag;

                {
                    super(createContext);
                    this.val$context = createContext;
                    this.val$link = g;
                    this.val$tag = dVar;
                    this.val$future = n;
                    this.val$methodName = str;
                    this.val$headers = metadata;
                    this.val$stream = serverStream;
                    this.val$jumpListener = jumpToApplicationThreadServerStreamListener;
                }

                private void runInternal() {
                    ServerStreamListener serverStreamListener = ServerImpl.NOOP_LISTENER;
                    if (this.val$future.isCancelled()) {
                        return;
                    }
                    try {
                        this.val$jumpListener.setListener(ServerTransportListenerImpl.this.startWrappedCall(this.val$methodName, (ServerCallParameters) com.google.common.util.concurrent.d.a(this.val$future), this.val$headers));
                        this.val$context.addListener(new Context.CancellationListener() {
                            @Override
                            public void cancelled(Context context) {
                                Status statusFromCancelled = Contexts.statusFromCancelled(context);
                                if (Status.DEADLINE_EXCEEDED.getCode().equals(statusFromCancelled.getCode())) {
                                    C1HandleServerCall.this.val$stream.cancel(statusFromCancelled);
                                }
                            }
                        }, h.a());
                    } finally {
                    }
                }

                @Override
                public void runInContext() {
                    g1.e i = g1.c.i("ServerTransportListener$HandleServerCall.startCall");
                    try {
                        g1.c.f(this.val$link);
                        g1.c.a(this.val$tag);
                        runInternal();
                        if (i != null) {
                            i.close();
                        }
                    } catch (Throwable th) {
                        if (i != null) {
                            try {
                                i.close();
                            } catch (Throwable th2) {
                                th.addSuppressed(th2);
                            }
                        }
                        throw th;
                    }
                }
            });
        }

        public <ReqT, RespT> ServerMethodDefinition<?, ?> wrapMethod(ServerStream serverStream, ServerMethodDefinition<ReqT, RespT> serverMethodDefinition, StatsTraceContext statsTraceContext) {
            statsTraceContext.serverCallStarted(new ServerCallInfoImpl(serverMethodDefinition.getMethodDescriptor(), serverStream.getAttributes(), serverStream.getAuthority()));
            ServerCallHandler<ReqT, RespT> serverCallHandler = serverMethodDefinition.getServerCallHandler();
            for (ServerInterceptor serverInterceptor : ServerImpl.this.interceptors) {
                serverCallHandler = InternalServerInterceptors.interceptCallHandlerCreate(serverInterceptor, serverCallHandler);
            }
            ServerMethodDefinition<ReqT, RespT> withServerCallHandler = serverMethodDefinition.withServerCallHandler(serverCallHandler);
            return ServerImpl.this.binlog == null ? withServerCallHandler : ServerImpl.this.binlog.wrapMethodDefinition(withServerCallHandler);
        }

        public void init() {
            if (ServerImpl.this.handshakeTimeoutMillis != Long.MAX_VALUE) {
                this.handshakeTimeoutFuture = this.transport.getScheduledExecutorService().schedule(new Runnable() {
                    @Override
                    public void run() {
                        ServerTransportListenerImpl.this.transport.shutdownNow(Status.CANCELLED.withDescription("Handshake timeout exceeded"));
                    }
                }, ServerImpl.this.handshakeTimeoutMillis, TimeUnit.MILLISECONDS);
            } else {
                this.handshakeTimeoutFuture = new FutureTask(new Runnable() {
                    @Override
                    public void run() {
                    }
                }, null);
            }
            ServerImpl.this.channelz.addServerSocket(ServerImpl.this, this.transport);
        }

        @Override
        public void streamCreated(ServerStream serverStream, String str, Metadata metadata) {
            g1.d c = g1.c.c(str, serverStream.streamId());
            g1.e i = g1.c.i("ServerTransportListener.streamCreated");
            try {
                g1.c.a(c);
                streamCreatedInternal(serverStream, str, metadata, c);
                if (i != null) {
                    i.close();
                }
            } catch (Throwable th) {
                if (i != null) {
                    try {
                        i.close();
                    } catch (Throwable th2) {
                        th.addSuppressed(th2);
                    }
                }
                throw th;
            }
        }

        @Override
        public Attributes transportReady(Attributes attributes) {
            this.handshakeTimeoutFuture.cancel(false);
            this.handshakeTimeoutFuture = null;
            for (ServerTransportFilter serverTransportFilter : ServerImpl.this.transportFilters) {
                attributes = (Attributes) l.p(serverTransportFilter.transportReady(attributes), "Filter %s returned null", serverTransportFilter);
            }
            this.attributes = attributes;
            return attributes;
        }

        @Override
        public void transportTerminated() {
            Future<?> future = this.handshakeTimeoutFuture;
            if (future != null) {
                future.cancel(false);
                this.handshakeTimeoutFuture = null;
            }
            Iterator it = ServerImpl.this.transportFilters.iterator();
            while (it.hasNext()) {
                ((ServerTransportFilter) it.next()).transportTerminated(this.attributes);
            }
            ServerImpl.this.transportClosed(this.transport);
        }
    }

    ServerImpl(ServerImplBuilder serverImplBuilder, InternalServer internalServer, Context context) {
        this.executorPool = (ObjectPool) l.o(serverImplBuilder.executorPool, "executorPool");
        this.registry = (HandlerRegistry) l.o(serverImplBuilder.registryBuilder.build(), "registryBuilder");
        this.fallbackRegistry = (HandlerRegistry) l.o(serverImplBuilder.fallbackRegistry, "fallbackRegistry");
        this.transportServer = (InternalServer) l.o(internalServer, "transportServer");
        this.rootContext = ((Context) l.o(context, "rootContext")).fork();
        this.decompressorRegistry = serverImplBuilder.decompressorRegistry;
        this.compressorRegistry = serverImplBuilder.compressorRegistry;
        this.transportFilters = Collections.unmodifiableList(new ArrayList(serverImplBuilder.transportFilters));
        List<ServerInterceptor> list = serverImplBuilder.interceptors;
        this.interceptors = (ServerInterceptor[]) list.toArray(new ServerInterceptor[list.size()]);
        this.handshakeTimeoutMillis = serverImplBuilder.handshakeTimeoutMillis;
        this.binlog = serverImplBuilder.binlog;
        InternalChannelz internalChannelz = serverImplBuilder.channelz;
        this.channelz = internalChannelz;
        this.serverCallTracer = serverImplBuilder.callTracerFactory.create();
        this.ticker = (Deadline.Ticker) l.o(serverImplBuilder.ticker, "ticker");
        internalChannelz.addServer(this);
        this.executorSupplier = serverImplBuilder.executorSupplier;
    }

    public void checkForTermination() {
        synchronized (this.lock) {
            try {
                if (this.shutdown && this.transports.isEmpty() && this.transportServersTerminated) {
                    if (this.terminated) {
                        throw new AssertionError("Server already terminated");
                    }
                    this.terminated = true;
                    this.channelz.removeServer(this);
                    Executor executor = this.executor;
                    if (executor != null) {
                        this.executor = this.executorPool.returnObject(executor);
                    }
                    this.lock.notifyAll();
                }
            } catch (Throwable th) {
                throw th;
            }
        }
    }

    private List<SocketAddress> getListenSocketsIgnoringLifecycle() {
        List<SocketAddress> unmodifiableList;
        synchronized (this.lock) {
            unmodifiableList = Collections.unmodifiableList(this.transportServer.getListenSocketAddresses());
        }
        return unmodifiableList;
    }

    public void transportClosed(ServerTransport serverTransport) {
        synchronized (this.lock) {
            try {
                if (!this.transports.remove(serverTransport)) {
                    throw new AssertionError("Transport already removed");
                }
                this.channelz.removeServerSocket(this, serverTransport);
                checkForTermination();
            } catch (Throwable th) {
                throw th;
            }
        }
    }

    @Override
    public boolean awaitTermination(long j, TimeUnit timeUnit) throws InterruptedException {
        boolean z;
        synchronized (this.lock) {
            try {
                long nanoTime = System.nanoTime() + timeUnit.toNanos(j);
                while (!this.terminated) {
                    long nanoTime2 = nanoTime - System.nanoTime();
                    if (nanoTime2 <= 0) {
                        break;
                    }
                    TimeUnit.NANOSECONDS.timedWait(this.lock, nanoTime2);
                }
                z = this.terminated;
            } catch (Throwable th) {
                throw th;
            }
        }
        return z;
    }

    @Override
    public List<ServerServiceDefinition> getImmutableServices() {
        return this.registry.getServices();
    }

    @Override
    public List<SocketAddress> getListenSockets() {
        List<SocketAddress> listenSocketsIgnoringLifecycle;
        synchronized (this.lock) {
            l.u(this.started, "Not started");
            l.u(!this.terminated, "Already terminated");
            listenSocketsIgnoringLifecycle = getListenSocketsIgnoringLifecycle();
        }
        return listenSocketsIgnoringLifecycle;
    }

    @Override
    public InternalLogId getLogId() {
        return this.logId;
    }

    @Override
    public List<ServerServiceDefinition> getMutableServices() {
        return Collections.unmodifiableList(this.fallbackRegistry.getServices());
    }

    @Override
    public int getPort() {
        synchronized (this.lock) {
            try {
                l.u(this.started, "Not started");
                l.u(!this.terminated, "Already terminated");
                for (SocketAddress socketAddress : this.transportServer.getListenSocketAddresses()) {
                    if (socketAddress instanceof InetSocketAddress) {
                        return ((InetSocketAddress) socketAddress).getPort();
                    }
                }
                return -1;
            } catch (Throwable th) {
                throw th;
            }
        }
    }

    @Override
    public List<ServerServiceDefinition> getServices() {
        List<ServerServiceDefinition> services = this.fallbackRegistry.getServices();
        if (services.isEmpty()) {
            return this.registry.getServices();
        }
        List<ServerServiceDefinition> services2 = this.registry.getServices();
        ArrayList arrayList = new ArrayList(services2.size() + services.size());
        arrayList.addAll(services2);
        arrayList.addAll(services);
        return Collections.unmodifiableList(arrayList);
    }

    @Override
    public g getStats() {
        InternalChannelz.ServerStats.Builder builder = new InternalChannelz.ServerStats.Builder();
        List<InternalInstrumented<InternalChannelz.SocketStats>> listenSocketStatsList = this.transportServer.getListenSocketStatsList();
        if (listenSocketStatsList != null) {
            builder.addListenSockets(listenSocketStatsList);
        }
        this.serverCallTracer.updateBuilder(builder);
        k n = k.n();
        n.set(builder.build());
        return n;
    }

    @Override
    public boolean isShutdown() {
        boolean z;
        synchronized (this.lock) {
            z = this.shutdown;
        }
        return z;
    }

    @Override
    public boolean isTerminated() {
        boolean z;
        synchronized (this.lock) {
            z = this.terminated;
        }
        return z;
    }

    public String toString() {
        return q.g.c(this).c("logId", this.logId.getId()).d("transportServer", this.transportServer).toString();
    }

    @Override
    public ServerImpl shutdown() {
        synchronized (this.lock) {
            try {
                if (this.shutdown) {
                    return this;
                }
                this.shutdown = true;
                boolean z = this.started;
                if (!z) {
                    this.transportServersTerminated = true;
                    checkForTermination();
                }
                if (z) {
                    this.transportServer.shutdown();
                }
                return this;
            } catch (Throwable th) {
                throw th;
            }
        }
    }

    @Override
    public ServerImpl shutdownNow() {
        shutdown();
        Status withDescription = Status.UNAVAILABLE.withDescription("Server shutdownNow invoked");
        synchronized (this.lock) {
            try {
                if (this.shutdownNowStatus != null) {
                    return this;
                }
                this.shutdownNowStatus = withDescription;
                ArrayList arrayList = new ArrayList(this.transports);
                boolean z = this.serverShutdownCallbackInvoked;
                if (z) {
                    Iterator it = arrayList.iterator();
                    while (it.hasNext()) {
                        ((ServerTransport) it.next()).shutdownNow(withDescription);
                    }
                }
                return this;
            } catch (Throwable th) {
                throw th;
            }
        }
    }

    @Override
    public ServerImpl start() throws IOException {
        synchronized (this.lock) {
            l.u(!this.started, "Already started");
            l.u(!this.shutdown, "Shutting down");
            this.transportServer.start(new ServerListenerImpl());
            this.executor = (Executor) l.o(this.executorPool.getObject(), "executor");
            this.started = true;
        }
        return this;
    }

    @Override
    public void awaitTermination() throws InterruptedException {
        synchronized (this.lock) {
            while (!this.terminated) {
                try {
                    this.lock.wait();
                } catch (Throwable th) {
                    throw th;
                }
            }
        }
    }
}