// File: /workspace/github_cpp_makefile_star2_O1/shaovie[P]reactor/src/poller.cpp
// Function: poller::run()
void poller::run() {
    this->thread_id = pthread_self();
    this->set_cpu_affinity();

    int nfds = 0, msec = -1;
    poll_desc *pd  = nullptr;
    ev_handler *eh = nullptr;
    struct epoll_event *ev_itor = nullptr;

    while (true) {
        nfds = ::epoll_wait(this->efd, this->ready_events, this->ready_events_size, msec);
        if (nfds > 0) {
            for (int i = 0; i < nfds; ++i) {
                ev_itor = this->ready_events + i;
                pd = (poll_desc*)(ev_itor->data.ptr);

                // EPOLLHUP refer to man 2 epoll_ctl
                if (ev_itor->events & (EPOLLHUP|EPOLLERR)) {
                    if (pd->eh != nullptr) {
                        eh = pd->eh;
                        this->remove(pd->fd, ev_handler::ev_all); // MUST before on_close
                        eh->on_close();
                    }
                    continue;
                }

                // MUST before EPOLLIN (e.g. connect)
                if (ev_itor->events & (EPOLLOUT)) {
                    if (pd->eh == nullptr)
                        continue ;
                    if (pd->eh->on_write() == false) {
                        eh = pd->eh;
                        this->remove(pd->fd, ev_handler::ev_all); // MUST before on_close
                        eh->on_close();
                        continue;
                    }
                }

                if (ev_itor->events & (EPOLLIN|EPOLLRDHUP)) {
                    if (pd->eh == nullptr)
                        continue ;
                    if (pd->eh->on_read() == false) {
                        eh = pd->eh;
                        this->remove(pd->fd, ev_handler::ev_all); // MUST before on_close
                        eh->on_close();
                        continue;
                    }
                }
            } // end of `for i < nfds'
        } else if (nfds == -1 && errno != EINTR) {
            fprintf(stderr, "reactor: epoll_wait exception! %s\n", strerror(errno));
            break; // exit
        }
    }

    ::close(this->efd); // Just release this resource and let epoll_ctl direct failure.
    this->efd = -1; // Thread unsafe
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
callq 0x6410
movq %rax, 0x40(%rbx)
movq %rbx, %rdi
callq 0x6330
pushq $0x2
popq %r14
movq 0x18(%rbx), %rsi
movl 0x4(%rbx), %edi
movl 0x8(%rbx), %edx
pushq $-0x1
popq %rcx
callq 0x6240
testl %eax, %eax
jle 0x698a
movl %eax, %eax
imulq $0xc, %rax, %r13
xorl %ebp, %ebp
movq 0x18(%rbx), %r15
movq 0x4(%r15,%rbp), %r12
movl (%r15,%rbp), %eax
testb $0x18, %al
je 0x6910
movq 0x10(%r12), %r15
testq %r15, %r15
jne 0x694f
jmp 0x6978
testb $0x4, %al
je 0x6928
movq 0x10(%r12), %rdi
testq %rdi, %rdi
je 0x6978
movq (%rdi), %rax
callq *0x20(%rax)
testb %al, %al
je 0x6947
movzwl (%r15,%rbp), %eax
testw $0x2001, %ax            # imm = 0x2001
je 0x6978
movq 0x10(%r12), %rdi
testq %rdi, %rdi
je 0x6978
movq (%rdi), %rax
callq *0x18(%rax)
testb %al, %al
jne 0x6978
leaq 0x10(%r12), %rax
movq (%rax), %r15
movl (%r12), %r12d
movq 0x30(%rbx), %rdi
movl %r12d, %esi
callq 0x6850
movl 0x4(%rbx), %edi
movl %r14d, %esi
movl %r12d, %edx
xorl %ecx, %ecx
callq 0x65d0
movq (%r15), %rax
movq %r15, %rdi
callq *0x38(%rax)
addq $0xc, %rbp
cmpq %rbp, %r13
jne 0x68f3
jmp 0x68d1
cmpl $-0x1, %eax
jne 0x68d1
callq 0x6040
movl (%rax), %edi
cmpl $0x4, %edi
je 0x68d1
movq 0x862e(%rip), %rax      # 0xefd8
movq (%rax), %r14
callq 0x6140
leaq 0x47a1(%rip), %rsi      # 0xb15a
movq %r14, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x6630
movl 0x4(%rbx), %edi
callq 0x6830
orl $-0x1, 0x4(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq