// File: /workspace/github_cpp_makefile_star2_O2/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 0x95f0
movq %rax, 0x40(%rbx)
movq %rbx, %rdi
callq 0x9480
pushq $-0x1
popq %rbp
movq 0x18(%rbx), %rsi
movl 0x4(%rbx), %edi
movl 0x8(%rbx), %edx
movl %ebp, %ecx
callq 0x9330
testl %eax, %eax
jle 0xa9ea
movl %eax, %eax
imulq $0xc, %rax, %r15
xorl %r12d, %r12d
cmpq %r12, %r15
je 0xa94c
movq 0x18(%rbx), %r14
movq 0x4(%r14,%r12), %r13
movl (%r14,%r12), %eax
testb $0x18, %al
je 0xa98f
movq 0x10(%r13), %r14
testq %r14, %r14
jne 0xa9ca
jmp 0xa9e4
testb $0x4, %al
je 0xa9aa
movq 0x10(%r13), %rdi
testq %rdi, %rdi
je 0xa9e4
movq (%rdi), %rax
callq *0x20(%rax)
testb %al, %al
je 0xa9c3
movl (%r14,%r12), %eax
testw $0x2001, %ax            # imm = 0x2001
je 0xa9e4
movq 0x10(%r13), %rdi
testq %rdi, %rdi
je 0xa9e4
movq (%rdi), %rax
callq *0x18(%rax)
testb %al, %al
jne 0xa9e4
leaq 0x10(%r13), %rax
movq (%rax), %r14
movl (%r13), %esi
movq %rbx, %rdi
movl $0x2005, %edx           # imm = 0x2005
callq 0x9ae0
movq (%r14), %rax
movq %r14, %rdi
callq *0x38(%rax)
addq $0xc, %r12
jmp 0xa96e
cmpl $-0x1, %eax
jne 0xa94c
callq 0x9060
movl (%rax), %edi
cmpl $0x4, %edi
je 0xa94c
movq 0x75c6(%rip), %rax      # 0x11fd0
movq (%rax), %r14
callq 0x91d0
leaq 0x3741(%rip), %rsi      # 0xe15a
movq %r14, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x9940
movl 0x4(%rbx), %edi
callq 0x9bc0
orl $-0x1, 0x4(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop