// File: /workspace/github_cpp_makefile_star2_O3/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 0x6400
movq %rax, 0x40(%rbx)
movq %rbx, %rdi
callq 0x6310
pushq $0x2
popq %r14
movq 0x18(%rbx), %rsi
movl 0x4(%rbx), %edi
movl 0x8(%rbx), %edx
pushq $-0x1
popq %rcx
callq 0x6220
testl %eax, %eax
jle 0x6979
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 0x6900
movq 0x10(%r12), %r15
testq %r15, %r15
jne 0x693e
jmp 0x6967
testb $0x4, %al
je 0x691c
movq 0x10(%r12), %rdi
testq %rdi, %rdi
je 0x6967
movq (%rdi), %rax
callq *0x20(%rax)
testb %al, %al
je 0x6936
movl (%r15,%rbp), %eax
testw $0x2001, %ax            # imm = 0x2001
je 0x6967
movq 0x10(%r12), %rdi
testq %rdi, %rdi
je 0x6967
movq (%rdi), %rax
callq *0x18(%rax)
testb %al, %al
jne 0x6967
leaq 0x10(%r12), %rax
movq (%rax), %r15
movl (%r12), %r12d
movq 0x30(%rbx), %rdi
movl %r12d, %esi
callq 0x6840
movl 0x4(%rbx), %edi
movl %r14d, %esi
movl %r12d, %edx
xorl %ecx, %ecx
callq 0x65c0
movq (%r15), %rax
movq %r15, %rdi
callq *0x38(%rax)
addq $0xc, %rbp
cmpq %rbp, %r13
jne 0x68e3
jmp 0x68c1
cmpl $-0x1, %eax
jne 0x68c1
callq 0x6040
movl (%rax), %edi
cmpl $0x4, %edi
je 0x68c1
movq 0x863f(%rip), %rax      # 0xefd8
movq (%rax), %r14
callq 0x6130
leaq 0x47b2(%rip), %rsi      # 0xb15a
movq %r14, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x6620
movl 0x4(%rbx), %edi
callq 0x6820
orl $-0x1, 0x4(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq