// File: /workspace/github_c_makefile_star2_O0/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelReconnectInstance
void sentinelReconnectInstance(sentinelRedisInstance *ri) {

    // 示例未断线（已连接），返回
    if (!(ri->flags & SRI_DISCONNECTED)) return;

    /* Commands connection. */
    // 对所有实例创建一个用于发送 Redis 命令的连接
    if (ri->cc == NULL) {

        // 连接实例
        ri->cc = redisAsyncConnect(ri->addr->ip,ri->addr->port);

        // 连接出错
        if (ri->cc->err) {
            sentinelEvent(REDIS_DEBUG,"-cmd-link-reconnection",ri,"%@ #%s",
                ri->cc->errstr);
            sentinelKillLink(ri,ri->cc);

        // 连接成功
        } else {
            // 设置连接属性
            ri->cc_conn_time = mstime();
            ri->cc->data = ri;
            redisAeAttach(server.el,ri->cc);
            // 设置连线 callback
            redisAsyncSetConnectCallback(ri->cc,
                                            sentinelLinkEstablishedCallback);
            // 设置断线 callback
            redisAsyncSetDisconnectCallback(ri->cc,
                                            sentinelDisconnectCallback);
            // 发送 AUTH 命令，验证身份
            sentinelSendAuthIfNeeded(ri,ri->cc);
            sentinelSetClientName(ri,ri->cc,"cmd");

            /* Send a PING ASAP when reconnecting. */
            sentinelSendPing(ri);
        }
    }

    /* Pub / Sub */
    // 对主服务器和从服务器，创建一个用于订阅频道的连接
    if ((ri->flags & (SRI_MASTER|SRI_SLAVE)) && ri->pc == NULL) {

        // 连接实例
        ri->pc = redisAsyncConnect(ri->addr->ip,ri->addr->port);

        // 连接出错
        if (ri->pc->err) {
            sentinelEvent(REDIS_DEBUG,"-pubsub-link-reconnection",ri,"%@ #%s",
                ri->pc->errstr);
            sentinelKillLink(ri,ri->pc);

        // 连接成功
        } else {
            int retval;

            // 设置连接属性
            ri->pc_conn_time = mstime();
            ri->pc->data = ri;
            redisAeAttach(server.el,ri->pc);
            // 设置连接 callback
            redisAsyncSetConnectCallback(ri->pc,
                                            sentinelLinkEstablishedCallback);
            // 设置断线 callback
            redisAsyncSetDisconnectCallback(ri->pc,
                                            sentinelDisconnectCallback);
            // 发送 AUTH 命令，验证身份
            sentinelSendAuthIfNeeded(ri,ri->pc);

            // 为客户但设置名字 "pubsub"
            sentinelSetClientName(ri,ri->pc,"pubsub");

            /* Now we subscribe to the Sentinels "Hello" channel. */
            // 发送 SUBSCRIBE __sentinel__:hello 命令，订阅频道
            retval = redisAsyncCommand(ri->pc,
                sentinelReceiveHelloMessages, NULL, "SUBSCRIBE %s",
                    SENTINEL_HELLO_CHANNEL);
            
            // 订阅出错，断开连接
            if (retval != REDIS_OK) {
                /* If we can't subscribe, the Pub/Sub connection is useless
                 * and we can simply disconnect it and try again. */
                sentinelKillLink(ri,ri->pc);
                return;
            }
        }
    }

    /* Clear the DISCONNECTED flags only if we have both the connections
     * (or just the commands connection if this is a sentinel instance). */
    // 如果实例是主服务器或者从服务器，那么当 cc 和 pc 两个连接都创建成功时，关闭 DISCONNECTED 标识
    // 如果实例是 Sentinel ，那么当 cc 连接创建成功时，关闭 DISCONNECTED 标识
    if (ri->cc && (ri->flags & SRI_SENTINEL || ri->pc))
        ri->flags &= ~SRI_DISCONNECTED;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x10, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movl (%rax), %eax
andl $0x8, %eax
cmpl $0x0, %eax
jne 0x7c96f
jmp 0x7cc27
movq -0x8(%rbp), %rax
cmpq $0x0, 0x28(%rax)
jne 0x7ca8c
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq (%rax), %rdi
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movl 0x8(%rax), %esi
callq 0x855f0
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
cmpl $0x0, 0xa0(%rax)
je 0x7c9f5
movq -0x8(%rbp), %rdx
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq 0xa8(%rax), %r8
xorl %edi, %edi
leaq 0x6cad8(%rip), %rsi     # 0xe94a9
leaq 0x6ca88(%rip), %rcx     # 0xe9460
movb $0x0, %al
callq 0x79b10
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rsi
callq 0x7aee0
jmp 0x7ca8a
callq 0x252e0
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x40(%rax)
movq -0x8(%rbp), %rcx
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq %rcx, 0xb0(%rax)
leaq 0x96ed9(%rip), %rax     # 0x1138f8
movq 0x28(%rax), %rdi
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rsi
callq 0x7cc30
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rdi
leaq -0x2df(%rip), %rsi      # 0x7c760
callq 0x85810
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rdi
leaq -0x273(%rip), %rsi      # 0x7c7e0
callq 0x85880
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rsi
callq 0x7c800
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rsi
leaq 0x6ca44(%rip), %rdx     # 0xe94c0
callq 0x7c8d0
movq -0x8(%rbp), %rdi
callq 0x7cd30
jmp 0x7ca8c
movq -0x8(%rbp), %rax
movl (%rax), %eax
andl $0x3, %eax
cmpl $0x0, %eax
je 0x7cbf8
movq -0x8(%rbp), %rax
cmpq $0x0, 0x30(%rax)
jne 0x7cbf8
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq (%rax), %rdi
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movl 0x8(%rax), %esi
callq 0x855f0
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
cmpl $0x0, 0xa0(%rax)
je 0x7cb24
movq -0x8(%rbp), %rdx
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movq 0xa8(%rax), %r8
xorl %edi, %edi
leaq 0x6c9c4(%rip), %rsi     # 0xe94c4
leaq 0x6c959(%rip), %rcx     # 0xe9460
movb $0x0, %al
callq 0x79b10
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rsi
callq 0x7aee0
jmp 0x7cbf6
callq 0x252e0
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x48(%rax)
movq -0x8(%rbp), %rcx
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movq %rcx, 0xb0(%rax)
leaq 0x96daa(%rip), %rax     # 0x1138f8
movq 0x28(%rax), %rdi
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rsi
callq 0x7cc30
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rdi
leaq -0x40e(%rip), %rsi      # 0x7c760
callq 0x85810
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rdi
leaq -0x3a2(%rip), %rsi      # 0x7c7e0
callq 0x85880
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rsi
callq 0x7c800
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rsi
leaq 0x61a8f(%rip), %rdx     # 0xde63a
callq 0x7c8d0
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rdi
leaq 0x1f1(%rip), %rsi       # 0x7cdb0
xorl %eax, %eax
movl %eax, %edx
leaq 0x6c914(%rip), %rcx     # 0xe94de
leaq 0x6c91a(%rip), %r8      # 0xe94eb
movb $0x0, %al
callq 0x86730
movl %eax, -0xc(%rbp)
cmpl $0x0, -0xc(%rbp)
je 0x7cbf4
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rsi
callq 0x7aee0
jmp 0x7cc27
jmp 0x7cbf6
jmp 0x7cbf8
movq -0x8(%rbp), %rax
cmpq $0x0, 0x28(%rax)
je 0x7cc27
movq -0x8(%rbp), %rax
movl (%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
jne 0x7cc1c
movq -0x8(%rbp), %rax
cmpq $0x0, 0x30(%rax)
je 0x7cc27
movq -0x8(%rbp), %rax
movl (%rax), %ecx
andl $-0x9, %ecx
movl %ecx, (%rax)
addq $0x10, %rsp
popq %rbp
retq
nopl (%rax)