// File: 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
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xf0(%rbp)
movl $0x80, -0x94(%rbp)
movl -0xc(%rbp), %edi
leaq -0x90(%rbp), %rsi
leaq -0x94(%rbp), %rdx
movl $0x80800, %ecx          # imm = 0x80800
callq 0x82d0
movl %eax, -0x98(%rbp)
cmpl $-0x1, -0x98(%rbp)
jne 0x57617
callq 0x8050
cmpl $0x4, (%rax)
je 0x57569
callq 0x8050
cmpl $0x67, (%rax)
jne 0x5756b
jmp 0x5751d
callq 0x8050
cmpl $0x18, (%rax)
je 0x5757f
callq 0x8050
cmpl $0x17, (%rax)
jne 0x575eb
leaq -0xa8(%rbp), %rdi
movq %rdi, -0xf8(%rbp)
callq 0xa600
movq -0xf8(%rbp), %rdi
leaq 0x25659(%rip), %rsi     # 0x7cbf9
callq 0x34030
jmp 0x575a7
leaq -0xa8(%rbp), %rdi
callq 0xa770
movq -0xf0(%rbp), %rsi
movq 0x8(%rsi), %rdi
callq 0x32800
jmp 0x5778c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0xa770
jmp 0x57799
callq 0x8050
cmpl $0xb, (%rax)
je 0x575ff
callq 0x8050
cmpl $0xb, (%rax)
jne 0x57604
jmp 0x5778c
callq 0x8050
movl (%rax), %edi
leaq 0x25604(%rip), %rsi     # 0x7cc16
callq 0xa320
movq -0xf0(%rbp), %rax
addq $0x58, %rax
movq %rax, -0x108(%rbp)
movl -0x98(%rbp), %eax
movl %eax, -0xfc(%rbp)
leaq -0xe0(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x2a010
jmp 0x5764a
movl -0xfc(%rbp), %edx
movq -0x108(%rbp), %rsi
leaq -0xc0(%rbp), %rdi
leaq -0xe0(%rbp), %rcx
callq 0x58500
jmp 0x5766c
leaq -0xc0(%rbp), %rdi
callq 0x58560
cmpq $0x0, %rax
jne 0x576be
movl -0x98(%rbp), %edi
callq 0x8ce0
jmp 0x5768b
jmp 0x57732
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
jmp 0x5774c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
jmp 0x57740
movq -0xf0(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x118(%rbp)
leaq -0xe8(%rbp), %rdi
movq %rdi, -0x110(%rbp)
leaq -0xc0(%rbp), %rsi
callq 0x58590
movq -0x118(%rbp), %rdi
movq -0x110(%rbp), %rsi
movl $0x5, %edx
callq 0xea00
jmp 0x57704
leaq -0xe8(%rbp), %rdi
callq 0x11290
jmp 0x57732
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0x11290
jmp 0x57740
leaq -0xc0(%rbp), %rdi
callq 0x585e0
jmp 0x57787
leaq -0xc0(%rbp), %rdi
callq 0x585e0
movq -0xb0(%rbp), %rdi
callq 0x8230
movl -0x98(%rbp), %edi
callq 0x8ce0
jmp 0x57765
callq 0x89c0
jmp 0x577ad
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
callq 0x8ae0
jmp 0x57785
jmp 0x57799
jmp 0x5751d
movb $0x1, %al
andb $0x1, %al
addq $0x120, %rsp            # imm = 0x120
popq %rbp
retq
movq -0xb0(%rbp), %rdi
callq 0x8bc0
movq %rax, %rdi
callq 0xa7e0
nopl (%rax)