// File: /workspace/github_c_makefile_star2_O0/sszllzss[P]webSocket_Libevent_ThreadPool/Threadpool.cpp
// Function: threadpool_thread(void*)
void *threadpool_thread(void *threadpool)
{
    threadpool_t *pool = (threadpool_t *)threadpool;
    threadpool_task_t task;

    while (true) {
        /*刚创建出线程，等待任务队列里有任务，否则阻塞等待任务队列里有任务后再唤醒接收任务*/
        pthread_mutex_lock(&(pool->lock));

        /*queue_size == 0 说明没有任务，调 wait 阻塞在条件变量上, 若有任务，跳过该while*/
        while ((pool->threadpool_task_queue->size() == 0) && (!pool->shutdown)) {  
            /* De_printf("thread 0x%x is waiting\n", (unsigned int)pthread_self()); */
            pthread_cond_wait(&(pool->queue_not_empty), &(pool->lock));

            /*清除指定数目的空闲线程，如果要结束的线程个数大于0，结束线程*/
            if (pool->wait_exit_thr_num > 0) {
                pool->wait_exit_thr_num--;

                /*如果线程池里线程个数大于最小值时可以结束当前线程*/
                if ((unsigned)pool->threads->size() > pool->min_thr_num) {
                    /* De_printf("thread 0x%x is exiting\n", (unsigned int)pthread_self()); */
                    pool->threads->remove(pthread_self());
                    pthread_mutex_unlock(&(pool->lock));
                    pthread_exit(NULL);

                }

            }
        }

        /*如果指定了true，要关闭线程池里的每个线程，自行退出处理*/
        if (pool->shutdown) {
            pool->threads->remove(pthread_self());
            pthread_mutex_unlock(&(pool->lock));
            /* De_printf("thread 0x%x is exiting\n", (unsigned int)pthread_self()); */
            pthread_exit(NULL);     /* 线程自行结束 */

        }

        /*从任务队列里获取任务, 是一个出队操作*/
        thread_pool_task_queue_t *task_queue; 
        task_queue = pool->threadpool_task_queue;
        task.function = (*task_queue->begin()).function;
        task.arg = (*task_queue->begin()).arg;
        task_queue->pop_front();

        /*通知可以有新的任务添加进来*/
        pthread_cond_broadcast(&(pool->queue_not_full));

        /*任务取出后，立即将 线程池琐 释放*/
        pthread_mutex_unlock(&(pool->lock));

        /*执行任务*/ 
        /* De_printf("thread 0x%x start working\n", (unsigned int)pthread_self()); */
        pthread_mutex_lock(&(pool->thread_counter));                            /*忙状态线程数变量琐*/
        pool->busy_thr_num++;                                                   /*忙状态线程数+1*/
        pthread_mutex_unlock(&(pool->thread_counter));
        (*(task.function))(task.arg);                                           /*执行回调函数任务*/
        //task.function(task.arg);                                              /*执行回调函数任务*/
        //
        //        /*任务结束处理*/ 
        /* De_printf("thread 0x%x end working\n", (unsigned int)pthread_self()); */
        pthread_mutex_lock(&(pool->thread_counter));
        pool->busy_thr_num--;                                       /*处理掉一个任务，忙状态数线程数-1*/
        pthread_mutex_unlock(&(pool->thread_counter));

    }

    pthread_exit(NULL);

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rdi
callq 0x4720
movq -0x10(%rbp), %rax
movq 0xc0(%rax), %rdi
callq 0xffd0
movq %rax, %rcx
xorl %eax, %eax
cmpq $0x0, %rcx
movb %al, -0x79(%rbp)
jne 0xf6a1
movq -0x10(%rbp), %rax
cmpl $0x0, 0xd4(%rax)
setne %al
xorb $-0x1, %al
movb %al, -0x79(%rbp)
movb -0x79(%rbp), %al
testb $0x1, %al
jne 0xf6ad
jmp 0xf741
movq -0x10(%rbp), %rdi
addq $0x80, %rdi
movq -0x10(%rbp), %rsi
callq 0x4760
movq -0x10(%rbp), %rax
cmpl $0x0, 0xd0(%rax)
jbe 0xf73c
movq -0x10(%rbp), %rax
movl 0xd0(%rax), %ecx
addl $-0x1, %ecx
movl %ecx, 0xd0(%rax)
movq -0x10(%rbp), %rax
movq 0xb8(%rax), %rdi
callq 0x10060
movq -0x10(%rbp), %rcx
cmpl 0xc8(%rcx), %eax
jbe 0xf73a
movq -0x10(%rbp), %rax
movq 0xb8(%rax), %rax
movq %rax, -0x88(%rbp)
callq 0x4450
movq -0x88(%rbp), %rdi
movq %rax, -0x28(%rbp)
leaq -0x28(%rbp), %rsi
callq 0x10090
movq -0x10(%rbp), %rdi
callq 0x4390
xorl %eax, %eax
movl %eax, %edi
callq 0x4840
jmp 0xf73c
jmp 0xf670
movq -0x10(%rbp), %rax
cmpl $0x0, 0xd4(%rax)
je 0xf78b
movq -0x10(%rbp), %rax
movq 0xb8(%rax), %rax
movq %rax, -0x90(%rbp)
callq 0x4450
movq -0x90(%rbp), %rdi
movq %rax, -0x30(%rbp)
leaq -0x30(%rbp), %rsi
callq 0x10090
movq -0x10(%rbp), %rdi
callq 0x4390
xorl %eax, %eax
movl %eax, %edi
callq 0x4840
movq -0x10(%rbp), %rax
movq 0xc0(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rsi
leaq -0x58(%rbp), %rdi
callq 0x10170
leaq -0x58(%rbp), %rdi
callq 0x101a0
movq (%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x38(%rbp), %rsi
leaq -0x78(%rbp), %rdi
callq 0x10170
leaq -0x78(%rbp), %rdi
callq 0x101a0
movq 0x8(%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x38(%rbp), %rdi
callq 0x101c0
movq -0x10(%rbp), %rdi
addq $0x50, %rdi
callq 0x41a0
movq -0x10(%rbp), %rdi
callq 0x4390
movq -0x10(%rbp), %rdi
addq $0x28, %rdi
callq 0x4720
movq -0x10(%rbp), %rax
movl 0xcc(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0xcc(%rax)
movq -0x10(%rbp), %rdi
addq $0x28, %rdi
callq 0x4390
movq -0x20(%rbp), %rax
movq -0x18(%rbp), %rdi
callq *%rax
movq -0x10(%rbp), %rdi
addq $0x28, %rdi
callq 0x4720
movq -0x10(%rbp), %rax
movl 0xcc(%rax), %ecx
addl $-0x1, %ecx
movl %ecx, 0xcc(%rax)
movq -0x10(%rbp), %rdi
addq $0x28, %rdi
callq 0x4390
jmp 0xf667
nopl (%rax)