// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelAskMasterStateToOtherSentinels
void sentinelAskMasterStateToOtherSentinels(sentinelRedisInstance *master, int flags) {
    dictIterator *di;
    dictEntry *de;

    // 遍历正在监视相同 master 的所有 sentinel
    // 向它们发送 SENTINEL is-master-down-by-addr 命令
    di = dictGetIterator(master->sentinels);
    while((de = dictNext(di)) != NULL) {
        sentinelRedisInstance *ri = dictGetVal(de);

        // 距离该 sentinel 最后一次回复 SENTINEL master-down-by-addr 命令已经过了多久
        mstime_t elapsed = mstime() - ri->last_master_down_reply_time;

        char port[32];
        int retval;

        /* If the master state from other sentinel is too old, we clear it. */
        // 如果目标 Sentinel 关于主服务器的信息已经太久没更新，那么我们清除它
        if (elapsed > SENTINEL_ASK_PERIOD*5) {
            ri->flags &= ~SRI_MASTER_DOWN;
            sdsfree(ri->leader);
            ri->leader = NULL;
        }

        /* Only ask if master is down to other sentinels if:
         *
         * 只在以下情况满足时，才向其他 sentinel 询问主服务器是否已下线
         *
         * 1) We believe it is down, or there is a failover in progress.
         *    本 sentinel 相信服务器已经下线，或者针对该主服务器的故障转移操作正在执行
         * 2) Sentinel is connected.
         *    目标 Sentinel 与本 Sentinel 已连接
         * 3) We did not received the info within SENTINEL_ASK_PERIOD ms. 
         *    当前 Sentinel 在 SENTINEL_ASK_PERIOD 毫秒内没有获得过目标 Sentinel 发来的信息
         * 4) 条件 1 和条件 2 满足而条件 3 不满足，但是 flags 参数给定了 SENTINEL_ASK_FORCED 标识
         */
        if ((master->flags & SRI_S_DOWN) == 0) continue;
        if (ri->flags & SRI_DISCONNECTED) continue;
        if (!(flags & SENTINEL_ASK_FORCED) &&
            mstime() - ri->last_master_down_reply_time < SENTINEL_ASK_PERIOD)
            continue;

        /* Ask */
        // 发送 SENTINEL is-master-down-by-addr 命令
        ll2string(port,sizeof(port),master->addr->port);
        retval = redisAsyncCommand(ri->cc,
                    sentinelReceiveIsMasterDownReply, NULL,
                    "SENTINEL is-master-down-by-addr %s %s %llu %s",
                    master->addr->ip, port,
                    sentinel.current_epoch,
                    // 如果本 Sentinel 已经检测到 master 进入 ODOWN 
                    // 并且要开始一次故障转移，那么向其他 Sentinel 发送自己的运行 ID
                    // 让对方将给自己投一票（如果对方在这个纪元内还没有投票的话）
                    (master->failover_state > SENTINEL_FAILOVER_STATE_NONE) ?
                    server.runid : "*");
        if (retval == REDIS_OK) ri->pending_commands++;
    }
    dictReleaseIterator(di);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movl %esi, %ebx
movq %rdi, %r14
movq 0xc0(%rdi), %rdi
callq 0x22a71
movq %rax, %r15
movq %rax, %rdi
callq 0x22acf
testq %rax, %rax
je 0x5f471
movq %rsp, %r12
leaq 0x6ac04(%rip), %r13     # 0xc9fa8
addq $0x58, %r13
movq 0x8(%rax), %rbp
callq 0x23461
subq 0x80(%rbp), %rax
cmpq $0x1389, %rax           # imm = 0x1389
jl 0x5f3db
andb $-0x41, (%rbp)
movq 0x118(%rbp), %rdi
callq 0x2850d
movq $0x0, 0x118(%rbp)
testb $0x10, (%r14)
je 0x5f460
testb $0x8, (%rbp)
jne 0x5f460
testb $0x1, %bl
jne 0x5f400
callq 0x23461
subq 0x80(%rbp), %rax
cmpq $0x3e8, %rax            # imm = 0x3E8
jl 0x5f460
movq 0x20(%r14), %rax
movslq 0x8(%rax), %rdx
movl $0x20, %esi
movq %r12, %rdi
callq 0x300c7
movq 0x28(%rbp), %rdi
movq 0x20(%r14), %rax
cmpl $0x0, 0x130(%r14)
movq (%rax), %r8
leaq 0x35455(%rip), %r10     # 0x94884
cmovgq %r13, %r10
leaq -0x1e6(%rip), %rsi      # 0x5f254
xorl %edx, %edx
leaq 0x408d1(%rip), %rcx     # 0x9fd14
movq %r12, %r9
xorl %eax, %eax
pushq %r10
pushq 0x7f498(%rip)           # 0xde8e8
callq 0x630fd
addq $0x10, %rsp
testl %eax, %eax
jne 0x5f460
incl 0x38(%rbp)
movq %r15, %rdi
callq 0x22acf
testq %rax, %rax
jne 0x5f3a8
movq %r15, %rdi
callq 0x22b86
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq