// File: /workspace/github_cpp_makefile_star2_O2/guoxuanhan[P]NetServer/tcpserver.cpp
// Function: TcpServer::OnNewConnection()
void TcpServer::OnNewConnection()
{
    //循环调用accept，获取所有的建立好连接的客户端fd
    struct sockaddr_in clientaddr;
    int clientfd;
    while( (clientfd = serversocket_.Accept(clientaddr)) > 0)
    {
        std::cout << "New client from IP:" << inet_ntoa(clientaddr.sin_addr)
            << ":" << ntohs(clientaddr.sin_port) << std::endl;

        if(++conncount_ >= MAXCONNECTION)
        {
            close(clientfd);
            continue;
        }
        Setnonblocking(clientfd);

        //选择IO线程loop
        EventLoop *loop = eventloopthreadpool.GetNextLoop();

        //创建连接，注册业务函数
        std::shared_ptr<TcpConnection> sptcpconnection = std::make_shared<TcpConnection>(loop, clientfd, clientaddr);
        sptcpconnection->SetMessaeCallback(messagecallback_);
        sptcpconnection->SetSendCompleteCallback(sendcompletecallback_);
        sptcpconnection->SetCloseCallback(closecallback_);
        sptcpconnection->SetErrorCallback(errorcallback_);
        sptcpconnection->SetConnectionCleanUp(std::bind(&TcpServer::RemoveConnection, this, std::placeholders::_1));
        {
            std::lock_guard<std::mutex> lock(mutex_);
            tcpconnlist_[clientfd] = sptcpconnection;
        }


        newconnectioncallback_(sptcpconnection);
        //Bug，应该把事件添加的操作放到最后,否则bug segement fault,导致HandleMessage中的phttpsession==NULL
        //总之就是做好一切准备工作再添加事件到epoll！！！
        sptcpconnection->AddChannelToLoop();
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq %rdi, %r14
leaq 0xf8(%rdi), %rax
movq %rax, 0x50(%rsp)
leaq 0x148(%rdi), %rax
movq %rax, 0x48(%rsp)
leaq 0x168(%rdi), %rax
movq %rax, 0x40(%rsp)
leaq 0x188(%rdi), %rax
movq %rax, 0x38(%rsp)
leaq 0x1a8(%rdi), %rax
movq %rax, 0x30(%rsp)
leaq 0xd0(%rdi), %r15
leaq 0xa0(%rdi), %rax
movq %rax, 0x28(%rsp)
leaq 0x128(%rdi), %rax
movq %rax, 0x20(%rsp)
leaq 0x60(%rsp), %rbx
leaq 0x10(%rsp), %r12
leaq 0x88(%rsp), %rbp
movq %r14, %rdi
movq %rbx, %rsi
callq 0xa8da
movl %eax, 0xc(%rsp)
testl %eax, %eax
jle 0xbf5e
movq 0xc1e5(%rip), %rdi      # 0x17fb8
leaq 0x360e(%rip), %rsi      # 0xf3e8
callq 0x4300
movq %rax, %r13
movl 0x64(%rsp), %edi
callq 0x4160
movq %r13, %rdi
movq %rax, %rsi
callq 0x4300
movq %rax, %rdi
leaq 0x35fa(%rip), %rsi      # 0xf3fa
callq 0x4300
movzwl 0x62(%rsp), %ecx
rolw $0x8, %cx
movzwl %cx, %esi
movq %rax, %rdi
callq 0x4520
movq %rax, %rdi
callq 0x41a0
movl 0x98(%r14), %eax
leal 0x1(%rax), %ecx
movl %ecx, 0x98(%r14)
movl 0xc(%rsp), %edi
cmpl $0x4e1f, %eax           # imm = 0x4E1F
jl 0xbe47
callq 0x45e0
jmp 0xbdb5
callq 0xc071
movq 0x50(%rsp), %rdi
callq 0x5d8e
movq %rax, 0x58(%rsp)
movq %r12, %rdi
leaq 0x58(%rsp), %rsi
leaq 0xc(%rsp), %rdx
movq %rbx, %rcx
callq 0xc165
movq 0x10(%rsp), %rdi
addq $0x78, %rdi
movq 0x48(%rsp), %rsi
callq 0x4e82
movq 0x10(%rsp), %rdi
movl $0x98, %eax
addq %rax, %rdi
movq 0x40(%rsp), %rsi
callq 0x4dee
movq 0x10(%rsp), %rdi
movl $0xb8, %eax
addq %rax, %rdi
movq 0x38(%rsp), %rsi
callq 0x4dee
movq 0x10(%rsp), %rdi
movl $0xd8, %eax
addq %rax, %rdi
movq 0x30(%rsp), %rsi
callq 0x4dee
movq 0x10(%rsp), %r13
leaq 0x1e4(%rip), %rax       # 0xc0b8
movq %rax, 0x70(%rsp)
andq $0x0, 0x78(%rsp)
movq %r14, 0x80(%rsp)
movq %rbp, %rdi
leaq 0x70(%rsp), %rsi
callq 0xc18a
addq $0xf8, %r13
movq %r13, %rdi
movq %rbp, %rsi
callq 0x4dee
movq %rbp, %rdi
callq 0x4a60
movq %r15, %rdi
callq 0x56bc
movq 0x28(%rsp), %rdi
leaq 0xc(%rsp), %rsi
callq 0xc1d2
movq %rax, %rdi
movq %r12, %rsi
callq 0xc280
movq %r15, %rdi
callq 0x4280
movq 0x20(%rsp), %rdi
movq %r12, %rsi
callq 0xb638
movq 0x10(%rsp), %rdi
callq 0xafd2
leaq 0x18(%rsp), %rdi
callq 0x6c7a
jmp 0xbdb5
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x4a60
jmp 0xbf96
movq %rax, %rbx
movq %r15, %rdi
callq 0x4280
jmp 0xbf96
jmp 0xbf93
jmp 0xbf93
movq %rax, %rbx
leaq 0x18(%rsp), %rdi
callq 0x6c7a
movq %rbx, %rdi
callq 0x4570