Tomcat 源码学习 之 Http11ConnectionHandler

 

Class Nameorg.apache.coyote.http11.Http11ConnectionHandler
Inheritance

Handler

Related Classes

Http11Protocol

RequestGroupInfo

Http11Processor

FunctionalityMaitainance processor list,assign cooresponding processor to input requests.

 

 

Analysis

Http11ConnectionHandler is a static class been defined in Http11Protocal.java file, it's very strange design that it actually inherited from Handler interface which was defined in  JIoEndpoint. Not sure why Tomcat design the connector this way, but there must be a reason.

 

Recalling to blog about JIoEndpoint, Http11ConnectionHandler will be used by cocurrent threads in SocketProcessor.run() method, which means, Http11ConnectionHandler need to be working file in multiple thread. That's why thread safe was considered highest priority when desin this class.

 

Fields

There are five instance fields defined in this class:

 

  • Http11Protocal proto, reference to the protocal instace, this instance was readonly in this class.
  • AtomicLong registerCount, this field count the number of processors been registered in JMX by handler. As you can see, AtomicLong type was used to ensure the atomic access to this value in the multiple threads environment.
  • RequestGroupInfo global, it is currently used only as a JMX artifact, to aggregate the data collected from each RequestProcessor thread.
  • ConcurrentHashMap<SocketWrapper<Socket>, Http11Processor> connections, each socket will be assigned one Http11Processor, we need to make sure this map is thread safe.
  • ConcurrentLinkedQueue<Http11Processor> recycledProcessors, idle processors could be used to assign to new socket. because of the default implimentation of ConcurrentLinkedQueue is unbounded, Http11ConnectionHandler inherited it and implements as bounded.
Methods

The key method of Http11ConnectionHandler is the "process" method:

 

        public SocketState process(SocketWrapper<Socket> socket, SocketStatus status) {
            Http11Processor processor = connections.remove(socket);
            try {
                if (processor == null) {
                    processor = recycledProcessors.poll();
                }
                if (processor == null) {
                    processor = createProcessor();
                }

                if (proto.isSSLEnabled() && (proto.sslImplementation != null)) {
                    processor.setSSLSupport(
                            proto.sslImplementation.getSSLSupport(
                                    socket.getSocket()));
                } else {
                    processor.setSSLSupport(null);
                }
                
                SocketState state = socket.isAsync()?processor.asyncDispatch(status):processor.process(socket);
                if (state == SocketState.LONG) {
                    connections.put(socket, processor);
                    socket.setAsync(true);
                    // longPoll may change socket state (e.g. to trigger a
                    // complete or dispatch)
                    return processor.asyncPostProcess();
                } else {
                    socket.setAsync(false);
                    recycledProcessors.offer(processor);
                }
                return state;
            } catch(java.net.SocketException e) {
                // SocketExceptions are normal
                log.debug(sm.getString(
                        "http11protocol.proto.socketexception.debug"), e);
            } catch (java.io.IOException e) {
                // IOExceptions are normal
                log.debug(sm.getString(
                        "http11protocol.proto.ioexception.debug"), e);
            }
            // Future developers: if you discover any other
            // rare-but-nonfatal exceptions, catch them here, and log as
            // above.
            catch (Throwable e) {
                ExceptionUtils.handleThrowable(e);
                // any other exception or error is odd. Here we log it
                // with "ERROR" level, so it will show up even on
                // less-than-verbose logs.
                log.error(sm.getString("http11protocol.proto.error"), e);
            }
            recycledProcessors.offer(processor);
            return SocketState.CLOSED;
        }

 

The method will first check if an existing processor been assign to current socket, use the existing processor if has, otherwise a new one will be created.

 

Processor will set it's SSL support based on the setting in ProtocalHandler, we will leave this part in future discussion.

 

After that, the socket will be processed by the processor differently according to if the socket is an asynchronized. 

 

  • If it's an asynchronized socket, it will call processor's asyncDispatch method. A LONG status will return if process succesufully, and processor's asyncPostProcess method will be called.
  • If it's not an asynchronized socket, it will call processor's process method.

The processor will be recyled once finished process, and the socket status will be set to CLOSED.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值