// File: /workspace/github_c_makefile_star2_O0/nilyang[P]redis-tdd-annotation/src/networking.c
// Function: processInputBuffer
void processInputBuffer(redisClient *c) {

    /* Keep processing while there is something in the input buffer */
    // 尽可能地处理查询缓冲区中的内容
    // 如果读取出现 short read ，那么可能会有内容滞留在读取缓冲区里面
    // 这些滞留内容也许不能完整构成一个符合协议的命令，
    // 需要等待下次读事件的就绪
    while(sdslen(c->querybuf)) {

        /* Return if clients are paused. */
        // 如果客户端正处于暂停状态，那么直接返回
        if (!(c->flags & REDIS_SLAVE) && clientsArePaused()) return;

        /* Immediately abort if the client is in the middle of something. */
        // REDIS_BLOCKED 状态表示客户端正在被阻塞
        if (c->flags & REDIS_BLOCKED) return;

        /* REDIS_CLOSE_AFTER_REPLY closes the connection once the reply is
         * written to the client. Make sure to not let the reply grow after
         * this flag has been set (i.e. don't process more commands). */
        // 客户端已经设置了关闭 FLAG ，没有必要处理命令了
        if (c->flags & REDIS_CLOSE_AFTER_REPLY) return;

        /* Determine request type when unknown. */
        // 判断请求的类型
        // 两种类型的区别可以在 Redis 的通讯协议上查到：
        // http://redis.readthedocs.org/en/latest/topic/protocol.html
        // 简单来说，多条查询是一般客户端发送来的，
        // 而内联查询则是 TELNET 发送来的
        if (!c->reqtype) {
            if (c->querybuf[0] == '*') {
                // 多条查询
                c->reqtype = REDIS_REQ_MULTIBULK;
            } else {
                // 内联查询
                c->reqtype = REDIS_REQ_INLINE;
            }
        }

        // 将缓冲区中的内容转换成命令，以及命令参数
        if (c->reqtype == REDIS_REQ_INLINE) {
            if (processInlineBuffer(c) != REDIS_OK) break;
        } else if (c->reqtype == REDIS_REQ_MULTIBULK) {
            if (processMultibulkBuffer(c) != REDIS_OK) break;
        } else {
            redisPanic("Unknown request type");
        }

        /* Multibulk processing could see a <= 0 length. */
        if (c->argc == 0) {
            resetClient(c);
        } else {
            /* Only reset the client when the command was executed. */
            // 执行命令，并重置客户端
            if (processCommand(c) == REDIS_OK)
                resetClient(c);
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x10, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x34800
cmpq $0x0, %rax
je 0x37b85
movq -0x8(%rbp), %rax
movl 0x90(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x37a94
callq 0x37b90
cmpl $0x0, %eax
je 0x37a94
jmp 0x37b85
movq -0x8(%rbp), %rax
movl 0x90(%rax), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x37aab
jmp 0x37b85
movq -0x8(%rbp), %rax
movl 0x90(%rax), %eax
andl $0x40, %eax
cmpl $0x0, %eax
je 0x37ac2
jmp 0x37b85
movq -0x8(%rbp), %rax
cmpl $0x0, 0x50(%rax)
jne 0x37af6
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movsbl (%rax), %eax
cmpl $0x2a, %eax
jne 0x37ae9
movq -0x8(%rbp), %rax
movl $0x2, 0x50(%rax)
jmp 0x37af4
movq -0x8(%rbp), %rax
movl $0x1, 0x50(%rax)
jmp 0x37af6
movq -0x8(%rbp), %rax
cmpl $0x1, 0x50(%rax)
jne 0x37b12
movq -0x8(%rbp), %rdi
callq 0x37180
cmpl $0x0, %eax
je 0x37b10
jmp 0x37b85
jmp 0x37b52
movq -0x8(%rbp), %rax
cmpl $0x2, 0x50(%rax)
jne 0x37b2e
movq -0x8(%rbp), %rdi
callq 0x37440
cmpl $0x0, %eax
je 0x37b2c
jmp 0x37b85
jmp 0x37b50
leaq 0xa958a(%rip), %rdi     # 0xe10bf
leaq 0xa932c(%rip), %rsi     # 0xe0e68
movl $0x5fa, %edx            # imm = 0x5FA
callq 0x63d40
movl $0x1, %edi
callq 0x1f3b0
jmp 0x37b52
movq -0x8(%rbp), %rax
cmpl $0x0, 0x30(%rax)
jne 0x37b67
movq -0x8(%rbp), %rdi
callq 0x370e0
jmp 0x37b80
movq -0x8(%rbp), %rdi
callq 0x28be0
cmpl $0x0, %eax
jne 0x37b7e
movq -0x8(%rbp), %rdi
callq 0x370e0
jmp 0x37b80
jmp 0x37a5c
addq $0x10, %rsp
popq %rbp
retq
nopl (%rax,%rax)