// File: /workspace/github_c_makefile_star2_O2/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
pushq $0x1
popq %rdi
xorl %esi, %esi
callq 0x1f5e0
imulq $0x28, %rbx, %rax
leaq 0x87851(%rip), %r14     # 0xdb7f0
addq %rax, %r14
movq %r14, %rdi
callq 0x1faa0
leaq 0x8(%rsp), %r15
movq %r15, %rdi
callq 0x1fa40
pushq $0xe
popq %rsi
movq %r15, %rdi
callq 0x1f850
xorl %edi, %edi
movq %r15, %rsi
xorl %edx, %edx
callq 0x1f160
testl %eax, %eax
je 0x53ff2
callq 0x1f810
movl (%rax), %edi
callq 0x1f630
leaq 0x3ff8e(%rip), %rsi     # 0x93f73
pushq $0x3
popq %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x22613
imulq $0x30, %rbx, %rax
leaq 0x87843(%rip), %r15     # 0xdb840
addq %rax, %r15
leaq 0x87899(%rip), %rbp     # 0xdb8a0
movq (%rbp,%rbx,8), %rax
cmpq $0x0, 0x28(%rax)
je 0x54039
movq (%rax), %r12
movq 0x10(%r12), %r13
movq %r14, %rdi
callq 0x1fbb0
cmpq $0x1, %rbx
je 0x54046
testq %rbx, %rbx
jne 0x54079
movl 0x8(%r13), %edi
callq 0x1f170
jmp 0x5404f
movq %r15, %rdi
movq %r14, %rsi
callq 0x1f910
jmp 0x54007
movl 0x8(%r13), %edi
callq 0x1f560
movq %r13, %rdi
callq 0x283cd
movq %r14, %rdi
callq 0x1faa0
movq (%rbp,%rbx,8), %rdi
movq %r12, %rsi
callq 0x1ff28
leaq 0x8783d(%rip), %rax     # 0xdb8b0
decq (%rax,%rbx,8)
jmp 0x54007
leaq 0x3ff23(%rip), %rdi     # 0x93fa3
leaq 0x3ff4c(%rip), %rsi     # 0x93fd3
movl $0xff, %edx
callq 0x490e8
pushq $0x1
popq %rdi
callq 0x1f3b0