// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/bio.c
// Function: bioProcessBackgroundJobs
void *bioProcessBackgroundJobs(void *arg) {
    struct bio_job *job;
    unsigned long type = (unsigned long) arg;
    sigset_t sigset;

    /* Make the thread killable at any time, so that bioKillThreads()
     * can work reliably. */
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

    pthread_mutex_lock(&bio_mutex[type]);
    /* Block SIGALRM so we are sure that only the main thread will
     * receive the watchdog signal. */
    sigemptyset(&sigset);
    sigaddset(&sigset, SIGALRM);
    if (pthread_sigmask(SIG_BLOCK, &sigset, NULL))
        redisLog(REDIS_WARNING,
            "Warning: can't mask SIGALRM in bio.c thread: %s", strerror(errno));

    while(1) {
        listNode *ln;

        /* The loop always starts with the lock hold. */
        if (listLength(bio_jobs[type]) == 0) {
            pthread_cond_wait(&bio_condvar[type],&bio_mutex[type]);
            continue;
        }

        /* Pop the job from the queue. 
         *
         * 取出（但不删除）队列中的首个任务
         */
        ln = listFirst(bio_jobs[type]);
        job = ln->value;

        /* It is now possible to unlock the background system as we know have
         * a stand alone job structure to process.*/
        pthread_mutex_unlock(&bio_mutex[type]);

        /* Process the job accordingly to its type. */
        // 执行任务
        if (type == REDIS_BIO_CLOSE_FILE) {
            close((long)job->arg1);

        } else if (type == REDIS_BIO_AOF_FSYNC) {
            aof_fsync((long)job->arg1);

        } else {
            redisPanic("Wrong job type in bioProcessBackgroundJobs().");
        }

        zfree(job);

        /* Lock again before reiterating the loop, if there are no longer
         * jobs to process we'll block again in pthread_cond_wait(). */
        pthread_mutex_lock(&bio_mutex[type]);
        // 将执行完成的任务从队列中删除，并减少任务计数器
        listDelNode(bio_jobs[type],ln);
        bio_pending[type]--;
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %rdi, %rbx
xorl %edi, %edi
xorl %esi, %esi
callq 0x1f050
movl $0x1, %edi
xorl %esi, %esi
callq 0x1f5e0
leaq (%rbx,%rbx,4), %rax
leaq 0x85c2b(%rip), %rcx     # 0xde7f0
leaq (%rcx,%rax,8), %r14
movq %r14, %rdi
callq 0x1faa0
leaq 0x8(%rsp), %r15
movq %r15, %rdi
callq 0x1fa40
movq %r15, %rdi
movl $0xe, %esi
callq 0x1f850
xorl %edi, %edi
movq %r15, %rsi
xorl %edx, %edx
callq 0x1f160
testl %eax, %eax
je 0x58c1d
callq 0x1f810
movl (%rax), %edi
callq 0x1f630
leaq 0x45365(%rip), %rsi     # 0x9df73
movl $0x3, %edi
movq %rax, %rdx
xorl %eax, %eax
callq 0x23064
leaq (%rbx,%rbx,2), %rax
shlq $0x4, %rax
leaq 0x85c14(%rip), %r15     # 0xde840
addq %rax, %r15
leaq 0x85c6a(%rip), %rbp     # 0xde8a0
movq (%rbp,%rbx,8), %rax
cmpq $0x0, 0x28(%rax)
je 0x58c68
movq (%rax), %r12
movq 0x10(%r12), %r13
movq %r14, %rdi
callq 0x1fbb0
cmpq $0x1, %rbx
je 0x58c75
testq %rbx, %rbx
jne 0x58ca8
movl 0x8(%r13), %edi
callq 0x1f170
jmp 0x58c7e
movq %r15, %rdi
movq %r14, %rsi
callq 0x1f910
jmp 0x58c36
movl 0x8(%r13), %edi
callq 0x1f560
movq %r13, %rdi
callq 0x2984b
movq %r14, %rdi
callq 0x1faa0
movq (%rbp,%rbx,8), %rdi
movq %r12, %rsi
callq 0x20544
leaq 0x85c0e(%rip), %rax     # 0xde8b0
decq (%rax,%rbx,8)
jmp 0x58c36
leaq 0x452f4(%rip), %rdi     # 0x9dfa3
leaq 0x4531d(%rip), %rsi     # 0x9dfd3
movl $0xff, %edx
callq 0x4d0e5
movl $0x1, %edi
callq 0x1f3b0