// File: cybozu[P]yrmcds/src/memcache/sockets.cpp
// Function: yrmcds::memcache::repl_client_socket::on_readable(int)
bool repl_client_socket::on_readable(int fd) {
    // This function is executed in the same thread as the function that sends
    // heartbeats. If this function takes a very long time, no heartbeats will
    // be sent, and this process will be judged dead by the master. To prevent
    // this misjudgment, set an upper limit on the number of iterations.
    static const size_t MAX_ITER = 50;

    size_t n_iter = 0;
    while( true ) {
        char* p = m_recvbuf.prepare(MAX_RECVSIZE);
        ssize_t n = ::recv(fd, p, MAX_RECVSIZE, 0);
        if( n == -1 ) {
            if( errno == EAGAIN || errno == EWOULDBLOCK )
                break;
            if( errno == EINTR )
                continue;
            if( errno == ECONNRESET ) {
                cybozu::logger::warning() << "The connection to master has been reset.";
                m_reactor->quit();
                return invalidate();
            }
            cybozu::throw_unix_error(errno, "recv");
        }
        if( n == 0 ) {
            cybozu::logger::info() << "The connection to master has been closed.";
            m_reactor->quit();
            return invalidate();
        }
        m_recvbuf.consume(n);

        std::size_t c = repl_recv(m_recvbuf.data(), m_recvbuf.size(), m_hash);
        m_recvbuf.erase(c);

        n_iter++;
        if (n_iter >= MAX_ITER) {
            m_reactor->add_readable(*this);
            return true;
        }
    }
    return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x70(%rbp)
movq $0x0, -0x20(%rbp)
movq -0x70(%rbp), %rdi
addq $0x108, %rdi            # imm = 0x108
movl $0x200000, %esi         # imm = 0x200000
callq 0x343b0
movq %rax, -0x28(%rbp)
movl -0x14(%rbp), %edi
movq -0x28(%rbp), %rsi
movl $0x200000, %edx         # imm = 0x200000
xorl %ecx, %ecx
callq 0x81b0
movq %rax, -0x30(%rbp)
cmpq $-0x1, -0x30(%rbp)
jne 0x45911
callq 0x8050
cmpl $0xb, (%rax)
je 0x45881
callq 0x8050
cmpl $0xb, (%rax)
jne 0x45886
jmp 0x45a12
callq 0x8050
cmpl $0x4, (%rax)
jne 0x45892
jmp 0x45832
callq 0x8050
cmpl $0x68, (%rax)
jne 0x458fe
leaq -0x40(%rbp), %rdi
movq %rdi, -0x78(%rbp)
callq 0x1b6e0
movq -0x78(%rbp), %rdi
leaq 0x36eff(%rip), %rsi     # 0x7c7b3
callq 0x51580
jmp 0x458bb
leaq -0x40(%rbp), %rdi
callq 0xa770
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x24670
movq -0x70(%rbp), %rdi
callq 0x23290
andb $0x1, %al
movb %al, -0x1(%rbp)
jmp 0x45a16
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x40(%rbp), %rdi
callq 0xa770
jmp 0x45a24
callq 0x8050
movl (%rax), %edi
leaq 0x35a99(%rip), %rsi     # 0x7b3a5
callq 0xa320
cmpq $0x0, -0x30(%rbp)
jne 0x4597a
leaq -0x60(%rbp), %rdi
movq %rdi, -0x80(%rbp)
callq 0x22390
movq -0x80(%rbp), %rdi
leaq 0x36eac(%rip), %rsi     # 0x7c7dc
callq 0x515c0
jmp 0x45937
leaq -0x60(%rbp), %rdi
callq 0xa770
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x24670
movq -0x70(%rbp), %rdi
callq 0x23290
andb $0x1, %al
movb %al, -0x1(%rbp)
jmp 0x45a16
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x60(%rbp), %rdi
callq 0xa770
jmp 0x45a24
movq -0x70(%rbp), %rdi
addq $0x108, %rdi            # imm = 0x108
movq -0x30(%rbp), %rsi
callq 0x344c0
movq -0x70(%rbp), %rdi
addq $0x108, %rdi            # imm = 0x108
callq 0x33dd0
movq -0x70(%rbp), %rdi
movq %rax, -0x88(%rbp)
addq $0x108, %rdi            # imm = 0x108
callq 0x33df0
movq -0x88(%rbp), %rdi
movq %rax, %rsi
movq -0x70(%rbp), %rax
movq 0x100(%rax), %rdx
callq 0x775f0
movq -0x70(%rbp), %rdi
movq %rax, -0x68(%rbp)
addq $0x108, %rdi            # imm = 0x108
movq -0x68(%rbp), %rsi
callq 0x34090
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
cmpq $0x32, -0x20(%rbp)
jb 0x45a0d
movq -0x70(%rbp), %rsi
movq 0x8(%rsi), %rdi
callq 0x32800
movb $0x1, -0x1(%rbp)
jmp 0x45a16
jmp 0x45832
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x90, %rsp
popq %rbp
retq
movq -0x48(%rbp), %rdi
callq 0x8bc0
nopl (%rax)