// File: /workspace/github_cpp_makefile_star2_O1/cybozu[P]yrmcds/cybozu/tcp.cpp
// Function: cybozu::tcp_server_socket::on_readable(int)
bool tcp_server_socket::on_readable(int fd) {
    while( true ) {
        union {
            struct sockaddr sa;
            struct sockaddr_storage ss;
        } addr;
        socklen_t addrlen = sizeof(addr);
#ifdef _GNU_SOURCE
        int s = ::accept4(fd, &(addr.sa), &addrlen,
                          SOCK_NONBLOCK|SOCK_CLOEXEC);
#else
        int s = ::accept(m_fd, &(addr.sa), &addrlen);
        if( s != -1 ) {
            int fl = fcntl(s, F_GETFL, 0);
            if( fl == -1 ) fl = 0;
            if( fcntl(s, F_SETFL, fl | O_NONBLOCK) == -1 ) {
                ::close(s);
                throw_unix_error(errno, "fcntl(F_SETFL)");
            }
            fl = fcntl(s, F_GETFD, 0);
            if( fl == -1 ) fl = 0;
            if( fcntl(s, F_SETFD, fl | FD_CLOEXEC) == -1 ) {
                ::close(s);
                throw_unix_error(errno, "fcntl(F_SETFD)");
            }
        }
#endif
        if( s == -1 ) {
            if( errno == EINTR || errno == ECONNABORTED )
                continue;
            if( errno == EMFILE || errno == ENFILE ) {
                logger::error() << "accept: Too many open files.";
                m_reactor->add_readable(*this);
                break;
            }
            if( errno == EAGAIN || errno == EWOULDBLOCK )
                break;
            throw_unix_error(errno, "accept");
        }

        try {
            std::unique_ptr<tcp_socket> t = m_wrapper(s, ip_address(&(addr.sa)));
            if( t.get() == nullptr ) {
                ::close(s);
            } else {
                m_reactor->add_resource( std::move(t),
                                         reactor::EVENT_IN|reactor::EVENT_OUT );
            }

        } catch( ... ) {
            ::close(s);
            throw;
        }
    }
    return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
movl %esi, %r14d
movq %rdi, %rbx
leaq 0x58(%rdi), %r15
leaq 0x38(%rsp), %r12
leaq 0x18(%rsp), %r13
movl $0x80, 0x10(%rsp)
movl %r14d, %edi
movq %r12, %rsi
leaq 0x10(%rsp), %rdx
movl $0x80800, %ecx          # imm = 0x80800
callq 0x71f0
cmpl $-0x1, %eax
je 0x21a6f
movl %eax, %ebp
movq %r13, %rdi
movq %r12, %rsi
callq 0x12120
movl %ebp, 0x14(%rsp)
cmpq $0x0, 0x68(%rbx)
je 0x21b51
leaq 0x8(%rsp), %rdi
movq %r15, %rsi
leaq 0x14(%rsp), %rdx
movq %r13, %rcx
callq *0x70(%rbx)
movq 0x8(%rsp), %rax
testq %rax, %rax
je 0x21a86
movq 0x8(%rbx), %rdi
movq $0x0, 0x8(%rsp)
movq %rax, (%rsp)
movq %rsp, %rsi
movl $0x5, %edx
callq 0xa33e
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x21a65
movq (%rdi), %rax
callq *0x8(%rax)
movq $0x0, (%rsp)
jmp 0x21a8d
callq 0x7040
movl (%rax), %edi
cmpl $0x16, %edi
jle 0x21aa6
cmpl $0x67, %edi
je 0x219dd
jmp 0x21abd
movl %ebp, %edi
callq 0x7a90
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x219dd
movq (%rdi), %rax
callq *0x8(%rax)
jmp 0x219dd
cmpl $0x4, %edi
je 0x219dd
cmpl $0xb, %edi
je 0x21b3d
jmp 0x21b56
leal -0x17(%rdi), %eax
cmpl $0x1, %eax
ja 0x21b56
leaq 0x24fc8(%rip), %rax     # 0x46a98
movl (%rax), %esi
notl %esi
shrl $0x1f, %esi
leaq 0x126e8(%rip), %rdx     # 0x341c6
leaq 0x18(%rsp), %r14
movq %r14, %rdi
callq 0x9718
cmpb $0x1, (%r14)
jne 0x21b07
movq 0x20(%rsp), %rdi
leaq 0x14d91(%rip), %rsi     # 0x3688e
movl $0x1c, %edx
callq 0x7580
leaq 0x18(%rsp), %rdi
callq 0x8f94
movq 0x8(%rbx), %rdi
addq $0x50, %rbx
movq 0x48(%rdi), %rsi
cmpq 0x50(%rdi), %rsi
je 0x21b31
movl (%rbx), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x48(%rdi)
jmp 0x21b3d
addq $0x40, %rdi
movq %rbx, %rdx
callq 0xaac6
movb $0x1, %al
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x7170
leaq 0x14d4e(%rip), %rsi     # 0x368ab
callq 0x8dd3
movq %rax, %rbx
leaq 0x18(%rsp), %rdi
callq 0x8f94
jmp 0x21bcc
movq %rax, %rbx
jmp 0x21b90
movq %rax, %rbx
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x21b88
movq (%rdi), %rax
callq *0x8(%rax)
movq $0x0, (%rsp)
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x21ba0
movq (%rdi), %rax
callq *0x8(%rax)
movq $0x0, 0x8(%rsp)
jmp 0x21bb0
jmp 0x21bad
movq %rax, %rbx
movq %rbx, %rdi
callq 0x71a0
movl %ebp, %edi
callq 0x7a90
callq 0x77c0
movq %rax, %rbx
callq 0x78f0
movq %rbx, %rdi
callq 0x79b0
movq %rax, %rdi
callq 0x8fc6