// File: /workspace/github_c_makefile_star2_O0/nilyang[P]redis-tdd-annotation/src/replication.c
// Function: sendBulkToSlave
void sendBulkToSlave(aeEventLoop *el, int fd, void *privdata, int mask) {
    redisClient *slave = privdata;
    REDIS_NOTUSED(el);
    REDIS_NOTUSED(mask);
    char buf[REDIS_IOBUF_LEN];
    ssize_t nwritten, buflen;

    /* Before sending the RDB file, we send the preamble as configured by the
     * replication process. Currently the preamble is just the bulk count of
     * the file in the form "$<length>\r\n". */
    if (slave->replpreamble) {
        nwritten = write(fd,slave->replpreamble,sdslen(slave->replpreamble));
        if (nwritten == -1) {
            redisLog(REDIS_VERBOSE,"Write error sending RDB preamble to slave: %s",
                strerror(errno));
            freeClient(slave);
            return;
        }
        sdsrange(slave->replpreamble,nwritten,-1);
        if (sdslen(slave->replpreamble) == 0) {
            sdsfree(slave->replpreamble);
            slave->replpreamble = NULL;
            /* fall through sending data. */
        } else {
            return;
        }
    }

    /* If the preamble was already transfered, send the RDB bulk data. */
    lseek(slave->repldbfd,slave->repldboff,SEEK_SET);
    // 读取 RDB 数据
    buflen = read(slave->repldbfd,buf,REDIS_IOBUF_LEN);
    if (buflen <= 0) {
        redisLog(REDIS_WARNING,"Read error sending DB to slave: %s",
            (buflen == 0) ? "premature EOF" : strerror(errno));
        freeClient(slave);
        return;
    }
    // 写入数据到 slave
    if ((nwritten = write(fd,buf,buflen)) == -1) {
        if (errno != EAGAIN) {
            redisLog(REDIS_WARNING,"Write error sending DB to slave: %s",
                strerror(errno));
            freeClient(slave);
        }
        return;
    }

    // 如果写入成功，那么更新写入字节数到 repldboff ，等待下次继续写入
    slave->repldboff += nwritten;

    // 如果写入已经完成
    if (slave->repldboff == slave->repldbsize) {
        // 关闭 RDB 文件描述符
        close(slave->repldbfd);
        slave->repldbfd = -1;
        // 删除之前绑定的写事件处理器
        aeDeleteFileEvent(server.el,slave->fd,AE_WRITABLE);
        // 将状态更新为 REDIS_REPL_ONLINE
        slave->replstate = REDIS_REPL_ONLINE;
        // 更新响应时间
        slave->repl_ack_time = server.unixtime;
        // 创建向从服务器发送命令的写事件处理器
        // 将保存并发送 RDB 期间的回复全部发送给从服务器
        if (aeCreateFileEvent(server.el, slave->fd, AE_WRITABLE,
            sendReplyToClient, slave) == AE_ERR) {
            redisLog(REDIS_WARNING,"Unable to register writable event for slave bulk transfer: %s", strerror(errno));
            freeClient(slave);
            return;
        }
        // 刷新低延迟 slave 数量
        refreshGoodSlavesCount();
        redisLog(REDIS_NOTICE,"Synchronization with slave succeeded");
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x4060, %rsp           # imm = 0x4060
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpq $0x0, 0xb0(%rax)
je 0x40430
movl -0xc(%rbp), %eax
movl %eax, -0x404c(%rbp)
movq -0x28(%rbp), %rax
movq 0xb0(%rax), %rax
movq %rax, -0x4048(%rbp)
movq -0x28(%rbp), %rax
movq 0xb0(%rax), %rdi
callq 0x3ed00
movl -0x404c(%rbp), %edi
movq -0x4048(%rbp), %rsi
movq %rax, %rdx
callq 0x1fb50
movq %rax, -0x4038(%rbp)
cmpq $-0x1, -0x4038(%rbp)
jne 0x403d4
callq 0x1f820
movl (%rax), %edi
callq 0x1f630
movq %rax, %rdx
movl $0x1, %edi
leaq 0xa1976(%rip), %rsi     # 0xe1d35
movb $0x0, %al
callq 0x24fb0
movq -0x28(%rbp), %rdi
callq 0x36a80
jmp 0x4062e
movq -0x28(%rbp), %rax
movq 0xb0(%rax), %rdi
movq -0x4038(%rbp), %rax
movl %eax, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x2d2e0
movq -0x28(%rbp), %rax
movq 0xb0(%rax), %rdi
callq 0x3ed00
cmpq $0x0, %rax
jne 0x40429
movq -0x28(%rbp), %rax
movq 0xb0(%rax), %rdi
callq 0x2c160
movq -0x28(%rbp), %rax
movq $0x0, 0xb0(%rax)
jmp 0x4042e
jmp 0x4062e
jmp 0x40430
movq -0x28(%rbp), %rax
movl 0x9c(%rax), %edi
movq -0x28(%rbp), %rax
movq 0xa0(%rax), %rsi
xorl %edx, %edx
callq 0x1fa00
movq -0x28(%rbp), %rax
movl 0x9c(%rax), %edi
leaq -0x4030(%rbp), %rsi
movl $0x4000, %edx           # imm = 0x4000
callq 0x1f330
movq %rax, -0x4040(%rbp)
cmpq $0x0, -0x4040(%rbp)
jg 0x404cd
cmpq $0x0, -0x4040(%rbp)
jne 0x40492
leaq 0xa18fd(%rip), %rax     # 0xe1d86
movq %rax, -0x4058(%rbp)
jmp 0x404a5
callq 0x1f820
movl (%rax), %edi
callq 0x1f630
movq %rax, -0x4058(%rbp)
movq -0x4058(%rbp), %rdx
movl $0x3, %edi
leaq 0xa18ab(%rip), %rsi     # 0xe1d63
movb $0x0, %al
callq 0x24fb0
movq -0x28(%rbp), %rdi
callq 0x36a80
jmp 0x4062e
movl -0xc(%rbp), %edi
leaq -0x4030(%rbp), %rsi
movq -0x4040(%rbp), %rdx
callq 0x1fb50
movq %rax, -0x4038(%rbp)
cmpq $-0x1, %rax
jne 0x4052a
callq 0x1f820
cmpl $0xb, (%rax)
je 0x40525
callq 0x1f820
movl (%rax), %edi
callq 0x1f630
movq %rax, %rdx
movl $0x3, %edi
leaq 0xa187f(%rip), %rsi     # 0xe1d94
movb $0x0, %al
callq 0x24fb0
movq -0x28(%rbp), %rdi
callq 0x36a80
jmp 0x4062e
movq -0x4038(%rbp), %rcx
movq -0x28(%rbp), %rax
addq 0xa0(%rax), %rcx
movq %rcx, 0xa0(%rax)
movq -0x28(%rbp), %rax
movq 0xa0(%rax), %rax
movq -0x28(%rbp), %rcx
cmpq 0xa8(%rcx), %rax
jne 0x4062e
movq -0x28(%rbp), %rax
movl 0x9c(%rax), %edi
callq 0x1f170
movq -0x28(%rbp), %rax
movl $0xffffffff, 0x9c(%rax) # imm = 0xFFFFFFFF
leaq 0xd3375(%rip), %rax     # 0x1138f8
movq 0x28(%rax), %rdi
movq -0x28(%rbp), %rax
movl (%rax), %esi
movl $0x2, %edx
callq 0x20c60
movq -0x28(%rbp), %rax
movl $0x9, 0x98(%rax)
leaq 0xd334c(%rip), %rax     # 0x1138f8
movq 0x798(%rax), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0xc8(%rax)
leaq 0xd3333(%rip), %rax     # 0x1138f8
movq 0x28(%rax), %rdi
movq -0x28(%rbp), %rax
movl (%rax), %esi
movq -0x28(%rbp), %r8
movl $0x2, %edx
leaq -0xb59f(%rip), %rcx     # 0x35040
callq 0x20a80
cmpl $-0x1, %eax
jne 0x40616
callq 0x1f820
movl (%rax), %edi
callq 0x1f630
movq %rax, %rdx
movl $0x3, %edi
leaq 0xa17b4(%rip), %rsi     # 0xe1db8
movb $0x0, %al
callq 0x24fb0
movq -0x28(%rbp), %rdi
callq 0x36a80
jmp 0x4062e
callq 0x3fc30
movl $0x2, %edi
leaq 0xa17cf(%rip), %rsi     # 0xe1df6
movb $0x0, %al
callq 0x24fb0
addq $0x4060, %rsp           # imm = 0x4060
popq %rbp
retq
nopw (%rax,%rax)