// File: /workspace/github_c_makefile_star2_O0/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterReadHandler
void clusterReadHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
    char buf[sizeof(clusterMsg)];
    ssize_t nread;
    clusterMsg *hdr;
    clusterLink *link = (clusterLink*) privdata;
    int readlen, rcvbuflen;
    REDIS_NOTUSED(el);
    REDIS_NOTUSED(mask);

    // 尽可能地多读数据
    while(1) { /* Read as long as there is data to read. */

        // 检查输入缓冲区的长度
        rcvbuflen = sdslen(link->rcvbuf);
        // 头信息（8 字节）未读入完
        if (rcvbuflen < 8) {
            /* First, obtain the first 8 bytes to get the full message
             * length. */
            readlen = 8 - rcvbuflen;
        // 已读入完整的信息
        } else {
            /* Finally read the full message. */
            hdr = (clusterMsg*) link->rcvbuf;
            if (rcvbuflen == 8) {
                /* Perform some sanity check on the message signature
                 * and length. */
                if (memcmp(hdr->sig,"RCmb",4) != 0 ||
                    ntohl(hdr->totlen) < CLUSTERMSG_MIN_LEN)
                {
                    redisLog(REDIS_WARNING,
                        "Bad message length or signature received "
                        "from Cluster bus.");
                    handleLinkIOError(link);
                    return;
                }
            }
            // 记录已读入内容长度
            readlen = ntohl(hdr->totlen) - rcvbuflen;
            if (readlen > sizeof(buf)) readlen = sizeof(buf);
        }

        // 读入内容
        nread = read(fd,buf,readlen);

        // 没有内容可读
        if (nread == -1 && errno == EAGAIN) return; /* No more data ready. */

        // 处理读入错误
        if (nread <= 0) {
            /* I/O error... */
            redisLog(REDIS_DEBUG,"I/O error reading from node link: %s",
                (nread == 0) ? "connection closed" : strerror(errno));
            handleLinkIOError(link);
            return;
        } else {
            /* Read data and recast the pointer to the new buffer. */
            // 将读入的内容追加进输入缓冲区里面
            link->rcvbuf = sdscatlen(link->rcvbuf,buf,nread);
            hdr = (clusterMsg*) link->rcvbuf;
            rcvbuflen += nread;
        }

        /* Total length obtained? Process this packet. */
        // 检查已读入内容的长度，看是否整条信息已经被读入了
        if (rcvbuflen >= 8 && rcvbuflen == ntohl(hdr->totlen)) {
            // 如果是的话，执行处理信息的函数
            if (clusterProcessPacket(link)) {
                sdsfree(link->rcvbuf);
                link->rcvbuf = sdsempty();
            } else {
                return; /* Link no longer valid. */
            }
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1120, %rsp           # imm = 0x1120
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x1108(%rbp)
movq -0x1108(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x67ee0
movl %eax, -0x1110(%rbp)
cmpl $0x8, -0x1110(%rbp)
jge 0x69ca9
movl $0x8, %eax
subl -0x1110(%rbp), %eax
movl %eax, -0x110c(%rbp)
jmp 0x69d52
movq -0x1108(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x1100(%rbp)
cmpl $0x8, -0x1110(%rbp)
jne 0x69d1c
movq -0x1100(%rbp), %rax
movl (%rax), %eax
subl $0x626d4352, %eax       # imm = 0x626D4352
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x69cf6
movq -0x1100(%rbp), %rax
movl 0x4(%rax), %edi
callq 0x1f5a0
movl %eax, %eax
cmpq $0x8a0, %rax            # imm = 0x8A0
jae 0x69d1a
movl $0x3, %edi
leaq 0x7c83d(%rip), %rsi     # 0xe653f
movb $0x0, %al
callq 0x24fb0
movq -0x1108(%rbp), %rdi
callq 0x6caf0
jmp 0x69eab
jmp 0x69d1c
movq -0x1100(%rbp), %rax
movl 0x4(%rax), %edi
callq 0x1f5a0
subl -0x1110(%rbp), %eax
movl %eax, -0x110c(%rbp)
movslq -0x110c(%rbp), %rax
cmpq $0x10d0, %rax           # imm = 0x10D0
jbe 0x69d50
movl $0x10d0, -0x110c(%rbp)  # imm = 0x10D0
jmp 0x69d52
movl -0xc(%rbp), %edi
leaq -0x10f0(%rbp), %rsi
movslq -0x110c(%rbp), %rdx
callq 0x1f330
movq %rax, -0x10f8(%rbp)
cmpq $-0x1, -0x10f8(%rbp)
jne 0x69d88
callq 0x1f820
cmpl $0xb, (%rax)
jne 0x69d88
jmp 0x69eab
cmpq $0x0, -0x10f8(%rbp)
jg 0x69de7
cmpq $0x0, -0x10f8(%rbp)
jne 0x69dac
leaq 0x7c7fc(%rip), %rax     # 0xe659f
movq %rax, -0x1118(%rbp)
jmp 0x69dbf
callq 0x1f820
movl (%rax), %edi
callq 0x1f630
movq %rax, -0x1118(%rbp)
movq -0x1118(%rbp), %rdx
xorl %edi, %edi
leaq 0x7c7ab(%rip), %rsi     # 0xe657a
movb $0x0, %al
callq 0x24fb0
movq -0x1108(%rbp), %rdi
callq 0x6caf0
jmp 0x69eab
movq -0x1108(%rbp), %rax
movq 0x18(%rax), %rdi
leaq -0x10f0(%rbp), %rsi
movq -0x10f8(%rbp), %rdx
callq 0x2c500
movq %rax, %rcx
movq -0x1108(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x1108(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x1100(%rbp)
movq -0x10f8(%rbp), %rcx
movslq -0x1110(%rbp), %rax
addq %rcx, %rax
movl %eax, -0x1110(%rbp)
cmpl $0x8, -0x1110(%rbp)
jl 0x69ea6
movl -0x1110(%rbp), %eax
movl %eax, -0x111c(%rbp)
movq -0x1100(%rbp), %rax
movl 0x4(%rax), %edi
callq 0x1f5a0
movl %eax, %ecx
movl -0x111c(%rbp), %eax
cmpl %ecx, %eax
jne 0x69ea6
movq -0x1108(%rbp), %rdi
callq 0x6b560
cmpl $0x0, %eax
je 0x69ea2
movq -0x1108(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x2c160
callq 0x2c0c0
movq %rax, %rcx
movq -0x1108(%rbp), %rax
movq %rcx, 0x18(%rax)
jmp 0x69ea4
jmp 0x69eab
jmp 0x69ea6
jmp 0x69c74
addq $0x1120, %rsp           # imm = 0x1120
popq %rbp
retq
nopw %cs:(%rax,%rax)