// File: /workspace/github_c_makefile_star2_O0/nilyang[P]redis-tdd-annotation/src/redis.c
// Function: initServer
void initServer() {
    int j;

    // 设置信号处理函数
    signal(SIGHUP, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);
    setupSignalHandlers();

    // 设置 syslog
    if (server.syslog_enabled) {
        openlog(server.syslog_ident, LOG_PID | LOG_NDELAY | LOG_NOWAIT,
            server.syslog_facility);
    }

    // 初始化并创建数据结构
    server.current_client = NULL;
    server.clients = listCreate();
    server.clients_to_close = listCreate();
    server.slaves = listCreate();
    server.monitors = listCreate();
    server.slaveseldb = -1; /* Force to emit the first SELECT command. */
    server.unblocked_clients = listCreate();
    server.ready_keys = listCreate();
    server.clients_waiting_acks = listCreate();
    server.get_ack_from_slaves = 0;
    server.clients_paused = 0;

    // 创建共享对象
    createSharedObjects();
    adjustOpenFilesLimit();
    server.el = aeCreateEventLoop(server.maxclients+REDIS_EVENTLOOP_FDSET_INCR);
    server.db = zmalloc(sizeof(redisDb)*server.dbnum);

    /* Open the TCP listening socket for the user commands. */
    // 打开 TCP 监听端口，用于等待客户端的命令请求
    if (server.port != 0 &&
        listenToPort(server.port,server.ipfd,&server.ipfd_count) == REDIS_ERR)
        exit(1);

    /* Open the listening Unix domain socket. */
    // 打开 UNIX 本地端口
    if (server.unixsocket != NULL) {
        unlink(server.unixsocket); /* don't care if this fails */
        server.sofd = anetUnixServer(server.neterr,server.unixsocket,
            server.unixsocketperm, server.tcp_backlog);
        if (server.sofd == ANET_ERR) {
            redisLog(REDIS_WARNING, "Opening socket: %s", server.neterr);
            exit(1);
        }
        anetNonBlock(NULL,server.sofd);
    }

    /* Abort if there are no listening sockets at all. */
    if (server.ipfd_count == 0 && server.sofd < 0) {
        redisLog(REDIS_WARNING, "Configured to not listen anywhere, exiting.");
        exit(1);
    }

    /* Create the Redis databases, and initialize other internal state. */
    // 创建并初始化数据库结构
    for (j = 0; j < server.dbnum; j++) {
        server.db[j].dict = dictCreate(&dbDictType,NULL);
        server.db[j].expires = dictCreate(&keyptrDictType,NULL);
        server.db[j].blocking_keys = dictCreate(&keylistDictType,NULL);
        server.db[j].ready_keys = dictCreate(&setDictType,NULL);
        server.db[j].watched_keys = dictCreate(&keylistDictType,NULL);
        server.db[j].eviction_pool = evictionPoolAlloc();
        server.db[j].id = j;
        server.db[j].avg_ttl = 0;
    }

    // 创建 PUBSUB 相关结构
    server.pubsub_channels = dictCreate(&keylistDictType,NULL);
    server.pubsub_patterns = listCreate();
    listSetFreeMethod(server.pubsub_patterns,freePubsubPattern);
    listSetMatchMethod(server.pubsub_patterns,listMatchPubsubPattern);

    server.cronloops = 0;
    server.rdb_child_pid = -1;
    server.aof_child_pid = -1;
    aofRewriteBufferReset();
    server.aof_buf = sdsempty();
    server.lastsave = time(NULL); /* At startup we consider the DB saved. */
    server.lastbgsave_try = 0;    /* At startup we never tried to BGSAVE. */
    server.rdb_save_time_last = -1;
    server.rdb_save_time_start = -1;
    server.dirty = 0;
    resetServerStats();
    /* A few stats we don't want to reset: server startup time, and peak mem. */
    server.stat_starttime = time(NULL);
    server.stat_peak_memory = 0;
    server.resident_set_size = 0;
    server.lastbgsave_status = REDIS_OK;
    server.aof_last_write_status = REDIS_OK;
    server.aof_last_write_errno = 0;
    server.repl_good_slaves_count = 0;
    updateCachedTime();

    /* Create the serverCron() time event, that's our main way to process
     * background operations. */
    // 为 serverCron() 创建时间事件
    if(aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL) == AE_ERR) {
        redisPanic("Can't create the serverCron time event.");
        exit(1);
    }

    /* Create an event handler for accepting new connections in TCP and Unix
     * domain sockets. */
    // 为 TCP 连接关联连接应答（accept）处理器
    // 用于接受并应答客户端的 connect() 调用
    for (j = 0; j < server.ipfd_count; j++) {
        if (aeCreateFileEvent(server.el, server.ipfd[j], AE_READABLE,
            acceptTcpHandler,NULL) == AE_ERR)
            {
                redisPanic(
                    "Unrecoverable error creating server.ipfd file event.");
            }
    }

    // 为本地套接字关联应答处理器
    if (server.sofd > 0 && aeCreateFileEvent(server.el,server.sofd,AE_READABLE,
        acceptUnixHandler,NULL) == AE_ERR) redisPanic("Unrecoverable error creating server.sofd file event.");

    /* Open the AOF file if needed. */
    // 如果 AOF 持久化功能已经打开，那么打开或创建一个 AOF 文件
    if (server.aof_state == REDIS_AOF_ON) {
        server.aof_fd = open(server.aof_filename,
                               O_WRONLY|O_APPEND|O_CREAT,0644);
        if (server.aof_fd == -1) {
            redisLog(REDIS_WARNING, "Can't open the append-only file: %s",
                strerror(errno));
            exit(1);
        }
    }

    /* 32 bit instances are limited to 4GB of address space, so if there is
     * no explicit limit in the user provided configuration we set a limit
     * at 3 GB using maxmemory with 'noeviction' policy'. This avoids
     * useless crashes of the Redis instance for out of memory. */
    // 对于 32 位实例来说，默认将最大可用内存限制在 3 GB
    if (server.arch_bits == 32 && server.maxmemory == 0) {
        redisLog(REDIS_WARNING,"Warning: 32 bit instance detected but no memory limit set. Setting 3 GB maxmemory limit with 'noeviction' policy now.");
        server.maxmemory = 3072LL*(1024*1024); /* 3 GB */
        server.maxmemory_policy = REDIS_MAXMEMORY_NO_EVICTION;
    }

    // 如果服务器以 cluster 模式打开，那么初始化 cluster
    if (server.cluster_enabled) clusterInit();

    // 初始化复制功能有关的脚本缓存
    replicationScriptCacheInit();

    // 初始化脚本系统
    scriptingInit();

    // 初始化慢查询功能
    slowlogInit();

    // 初始化 BIO 系统
    bioInit();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x10, %rsp
movl $0x1, %edi
movl $0x1, %esi
callq 0x1f770
movl $0xd, %edi
movl $0x1, %esi
callq 0x1f770
callq 0x28410
cmpl $0x0, 0xec09e(%rip)     # 0x113ed0
je 0x27e4b
movq 0xec09d(%rip), %rdi     # 0x113ed8
movl 0xec09f(%rip), %edx     # 0x113ee0
movl $0x19, %esi
callq 0x1f2a0
movq $0x0, 0xebc72(%rip) # 0x113ac8
callq 0x1fdb0
movq %rax, 0xebc46(%rip)     # 0x113aa8
callq 0x1fdb0
movq %rax, 0xebc42(%rip)     # 0x113ab0
callq 0x1fdb0
movq %rax, 0xebc3e(%rip)     # 0x113ab8
callq 0x1fdb0
movq %rax, 0xebc3a(%rip)     # 0x113ac0
movl $0xffffffff, 0xec054(%rip) # imm = 0xFFFFFFFF
callq 0x1fdb0
movq %rax, 0xec194(%rip)     # 0x114030
callq 0x1fdb0
movq %rax, 0xec190(%rip)     # 0x114038
callq 0x1fdb0
movq %rax, 0xec154(%rip)     # 0x114008
movl $0x0, 0xec152(%rip)     # 0x114010
movl $0x0, 0xebc08(%rip)     # 0x113ad0
callq 0x269d0
callq 0x278c0
movl 0xec13c(%rip), %edi     # 0x114014
addl $0x80, %edi
callq 0x20670
movq %rax, 0xeba36(%rip)     # 0x113920
movslq 0xebe87(%rip), %rdi     # 0x113d78
shlq $0x6, %rdi
callq 0x2e130
movq %rax, 0xeba07(%rip)     # 0x113908
cmpl $0x0, 0xeba78(%rip)     # 0x113980
je 0x27f3c
movl 0xeba70(%rip), %edi     # 0x113980
leaq 0xeb9e1(%rip), %rdx     # 0x1138f8
movq %rdx, %rsi
addq $0x124, %rsi            # imm = 0x124
addq $0x164, %rdx            # imm = 0x164
callq 0x27a90
cmpl $-0x1, %eax
jne 0x27f3c
movl $0x1, %edi
callq 0x1f2c0
cmpq $0x0, 0xebacc(%rip)     # 0x113a10
je 0x27fc1
movq 0xebac3(%rip), %rdi     # 0x113a10
callq 0x1f3a0
movq 0xebab7(%rip), %rsi     # 0x113a10
movl 0xebab9(%rip), %edx     # 0x113a18
movl 0xeba1f(%rip), %ecx     # 0x113984
leaq 0xeb98c(%rip), %rdi     # 0x1138f8
addq $0x1e8, %rdi            # imm = 0x1E8
callq 0x22830
movl %eax, 0xebae2(%rip)     # 0x113a60
cmpl $-0x1, 0xebadb(%rip)    # 0x113a60
jne 0x27fb2
movl $0x3, %edi
leaq 0xb70e2(%rip), %rsi     # 0xdf075
leaq 0xeb95e(%rip), %rdx     # 0x1138f8
addq $0x1e8, %rdx            # imm = 0x1E8
movb $0x0, %al
callq 0x24fb0
movl $0x1, %edi
callq 0x1f2c0
movl 0xebaa8(%rip), %esi     # 0x113a60
xorl %eax, %eax
movl %eax, %edi
callq 0x21890
cmpl $0x0, 0xeba94(%rip)     # 0x113a5c
jne 0x27ff0
cmpl $0x0, 0xeba8f(%rip)     # 0x113a60
jge 0x27ff0
movl $0x3, %edi
leaq 0xb70a9(%rip), %rsi     # 0xdf088
movb $0x0, %al
callq 0x24fb0
movl $0x1, %edi
callq 0x1f2c0
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
cmpl 0xebd78(%rip), %eax     # 0x113d78
jge 0x28130
leaq 0xea8d3(%rip), %rdi     # 0x1128e0
xorl %eax, %eax
movl %eax, %esi
callq 0x231a0
movq %rax, %rcx
movq 0xeb8e8(%rip), %rax     # 0x113908
movslq -0x4(%rbp), %rdx
shlq $0x6, %rdx
addq %rdx, %rax
movq %rcx, (%rax)
leaq 0xea90b(%rip), %rdi     # 0x112940
xorl %eax, %eax
movl %eax, %esi
callq 0x231a0
movq %rax, %rcx
movq 0xeb8c0(%rip), %rax     # 0x113908
movslq -0x4(%rbp), %rdx
shlq $0x6, %rdx
addq %rdx, %rax
movq %rcx, 0x8(%rax)
leaq 0xea972(%rip), %rdi     # 0x1129d0
xorl %eax, %eax
movl %eax, %esi
callq 0x231a0
movq %rax, %rcx
movq 0xeb897(%rip), %rax     # 0x113908
movslq -0x4(%rbp), %rdx
shlq $0x6, %rdx
addq %rdx, %rax
movq %rcx, 0x10(%rax)
leaq 0xea7f9(%rip), %rdi     # 0x112880
xorl %eax, %eax
movl %eax, %esi
callq 0x231a0
movq %rax, %rcx
movq 0xeb86e(%rip), %rax     # 0x113908
movslq -0x4(%rbp), %rdx
shlq $0x6, %rdx
addq %rdx, %rax
movq %rcx, 0x18(%rax)
leaq 0xea920(%rip), %rdi     # 0x1129d0
xorl %eax, %eax
movl %eax, %esi
callq 0x231a0
movq %rax, %rcx
movq 0xeb845(%rip), %rax     # 0x113908
movslq -0x4(%rbp), %rdx
shlq $0x6, %rdx
addq %rdx, %rax
movq %rcx, 0x20(%rax)
callq 0x284e0
movq %rax, %rcx
movq 0xeb827(%rip), %rax     # 0x113908
movslq -0x4(%rbp), %rdx
shlq $0x6, %rdx
addq %rdx, %rax
movq %rcx, 0x28(%rax)
movl -0x4(%rbp), %ecx
movq 0xeb80e(%rip), %rax     # 0x113908
movslq -0x4(%rbp), %rdx
shlq $0x6, %rdx
addq %rdx, %rax
movl %ecx, 0x30(%rax)
movq 0xeb7f9(%rip), %rax     # 0x113908
movslq -0x4(%rbp), %rcx
shlq $0x6, %rcx
addq %rcx, %rax
movq $0x0, 0x38(%rax)
movl -0x4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4(%rbp)
jmp 0x27ff7
leaq 0xea899(%rip), %rdi     # 0x1129d0
xorl %eax, %eax
movl %eax, %esi
callq 0x231a0
movq %rax, 0xebf59(%rip)     # 0x1140a0
callq 0x1fdb0
movq %rax, 0xebf55(%rip)     # 0x1140a8
movq 0xebf4e(%rip), %rax     # 0x1140a8
leaq 0x3973f(%rip), %rcx     # 0x618a0
movq %rcx, 0x18(%rax)
movq 0xebf3c(%rip), %rax     # 0x1140a8
leaq 0x3975d(%rip), %rcx     # 0x618d0
movq %rcx, 0x20(%rax)
movl $0x0, 0xeb7cb(%rip)     # 0x11394c
movl $0xffffffff, 0xebcdd(%rip) # imm = 0xFFFFFFFF
movl $0xffffffff, 0xebc67(%rip) # imm = 0xFFFFFFFF
callq 0x5e760
callq 0x2c0c0
movq %rax, 0xebc62(%rip)     # 0x113e08
xorl %eax, %eax
movl %eax, %edi
callq 0x1fc70
movq %rax, 0xebcda(%rip)     # 0x113e90
movq $0x0, 0xebcd7(%rip) # 0x113e98
movq $-0x1, 0xebcd4(%rip) # 0x113ea0
movq $-0x1, 0xebcd1(%rip) # 0x113ea8
movq $0x0, 0xebc76(%rip) # 0x113e58
callq 0x27d40
xorl %eax, %eax
movl %eax, %edi
callq 0x1fc70
movq %rax, 0xeba41(%rip)     # 0x113c38
movq $0x0, 0xeba6e(%rip) # 0x113c70
movq $0x0, 0xebab3(%rip) # 0x113cc0
movl $0x0, 0xebc99(%rip)     # 0x113eb0
movl $0x0, 0xebc2b(%rip)     # 0x113e4c
movl $0x0, 0xebc25(%rip)     # 0x113e50
movl $0x0, 0xebd03(%rip)     # 0x113f38
callq 0x26190
movq 0xeb6df(%rip), %rdi     # 0x113920
movl $0x1, %esi
leaq -0x208d(%rip), %rdx     # 0x261c0
xorl %eax, %eax
movl %eax, %r8d
movq %r8, %rcx
callq 0x20e40
cmpq $-0x1, %rax
jne 0x28282
leaq 0xb6e4d(%rip), %rdi     # 0xdf0b4
leaq 0xc25e6(%rip), %rsi     # 0xea854
movl $0x868, %edx            # imm = 0x868
callq 0x63d40
movl $0x1, %edi
callq 0x1f3b0
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
cmpl 0xeb7ca(%rip), %eax     # 0x113a5c
jge 0x282f7
movq 0xeb685(%rip), %rdi     # 0x113920
movslq -0x4(%rbp), %rcx
leaq 0xeb652(%rip), %rax     # 0x1138f8
movl 0x124(%rax,%rcx,4), %esi
movl $0x1, %edx
leaq 0xe4d7(%rip), %rcx      # 0x36790
xorl %eax, %eax
movl %eax, %r8d
callq 0x20a80
cmpl $-0x1, %eax
jne 0x282ea
leaq 0xb6e0f(%rip), %rdi     # 0xdf0de
leaq 0xc257e(%rip), %rsi     # 0xea854
movl $0x875, %edx            # imm = 0x875
callq 0x63d40
movl $0x1, %edi
callq 0x1f3b0
jmp 0x282ec
movl -0x4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4(%rbp)
jmp 0x28289
cmpl $0x0, 0xeb762(%rip)     # 0x113a60
jle 0x2834a
movq 0xeb619(%rip), %rdi     # 0x113920
movl 0xeb753(%rip), %esi     # 0x113a60
movl $0x1, %edx
leaq 0xe657(%rip), %rcx      # 0x36970
xorl %eax, %eax
movl %eax, %r8d
callq 0x20a80
cmpl $-0x1, %eax
jne 0x2834a
leaq 0xb6de6(%rip), %rdi     # 0xdf115
leaq 0xc251e(%rip), %rsi     # 0xea854
movl $0x87b, %edx            # imm = 0x87B
callq 0x63d40
movl $0x1, %edi
callq 0x1f3b0
cmpl $0x1, 0xeba77(%rip)     # 0x113dc8
jne 0x283a8
movq 0xeba76(%rip), %rdi     # 0x113dd0
movl $0x441, %esi            # imm = 0x441
movl $0x1a4, %edx            # imm = 0x1A4
movb $0x0, %al
callq 0x1f640
movl %eax, 0xeba9f(%rip)     # 0x113e10
cmpl $-0x1, 0xeba98(%rip)    # 0x113e10
jne 0x283a6
callq 0x1f820
movl (%rax), %edi
callq 0x1f630
movq %rax, %rdx
movl $0x3, %edi
leaq 0xb6db7(%rip), %rsi     # 0xdf14c
movb $0x0, %al
callq 0x24fb0
movl $0x1, %edi
callq 0x1f2c0
jmp 0x283a8
cmpl $0x20, 0xeb599(%rip)    # 0x113948
jne 0x283e4
cmpq $0x0, 0xebc5f(%rip)     # 0x114018
jne 0x283e4
movl $0x3, %edi
leaq 0xb6da9(%rip), %rsi     # 0xdf170
movb $0x0, %al
callq 0x24fb0
movl $0xc0000000, %eax       # imm = 0xC0000000
movq %rax, 0xebc3e(%rip)     # 0x114018
movl $0x5, 0xebc3c(%rip)     # 0x114020
cmpl $0x0, 0xebcc9(%rip)     # 0x1140b4
je 0x283f2
callq 0x69150
callq 0x424a0
callq 0x74220
callq 0x727b0
callq 0x75830
addq $0x10, %rsp
popq %rbp
retq
nopl (%rax)