// File: /workspace/github_cpp_makefile_star2_O3/xuchanglong[P]SimpleReactorImplemention-comments/eventDemultiplexer/event_demultiplexer.cc
// Function: reactor::EpollDemultiplexer::WaitEvents(std::map<int, reactor::EventHandler*, std::less<int>, std::allocator<std::pair<int const, reactor::EventHandler*>>>*, int, time_heap*)
int EpollDemultiplexer::WaitEvents(std::map<handle_t, EventHandler *> *handlers,
    int timeout, time_heap *event_timer)
{
    //  申请用于保存已发送事件的 epoll_event 。
    std::vector<epoll_event> ep_evts(m_fd_num);
    //  获取已发生事件的 epoll_event 。
    int num = epoll_wait(m_epoll_fd, &ep_evts[0], ep_evts.size(), timeout);
    if (num > 0) {
        for (int idx = 0; idx < num; ++idx) {
            handle_t handle = ep_evts[idx].data.fd;
            assert(handlers->find(handle) != handlers->end());
            if ((ep_evts[idx].events & EPOLLERR) || (ep_evts[idx].events & EPOLLHUP)) {
                (*handlers)[handle]->HandleError();
            } else {
                /**
                 * 调用该句柄对应的事件处理器的读写函数。
                */
                if (ep_evts[idx].events & EPOLLIN) {
                    (*handlers)[handle]->HandleRead();
                }
                if (ep_evts[idx].events & EPOLLOUT) {
                    (*handlers)[handle]->HandleWrite();
                }
            }
        }
    }
    if (event_timer != nullptr) {
        event_timer->tick();
    }

    return num;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rcx, %rbx
movl %edx, %ebp
movq %rsi, %r14
movq %rdi, %r15
movslq 0xc(%rdi), %rsi
leaq 0x8(%rsp), %r12
leaq 0x4(%rsp), %rdx
movq %r12, %rdi
callq 0x3028
movl 0x8(%r15), %edi
movq (%r12), %rsi
movq 0x8(%r12), %rax
subq %rsi, %rax
shrq $0x2, %rax
imull $0xaaaaaaab, %eax, %edx # imm = 0xAAAAAAAB
movl %ebp, %ecx
callq 0x2100
movq %rbx, 0x20(%rsp)
movl %eax, (%rsp)
testl %eax, %eax
jle 0x2ee8
leaq 0x8(%r14), %r12
movl (%rsp), %r13d
xorl %ebx, %ebx
leaq 0x4(%rsp), %r15
movq 0x8(%rsp), %rcx
leaq (%rbx,%rbx,2), %rbp
movl 0x4(%rcx,%rbp,4), %eax
movl %eax, 0x4(%rsp)
movq 0x10(%r14), %rdx
testq %rdx, %rdx
je 0x2f22
leaq (%rcx,%rbp,4), %rcx
movq %r12, %rsi
xorl %edi, %edi
cmpl %eax, 0x20(%rdx)
setl %dil
cmovgeq %rdx, %rsi
movq 0x10(%rdx,%rdi,8), %rdx
testq %rdx, %rdx
jne 0x2e5e
cmpq %r12, %rsi
je 0x2f22
cmpl 0x20(%rsi), %eax
jl 0x2f22
movl (%rcx), %eax
testb $0x18, %al
je 0x2e9f
movq %r14, %rdi
movq %r15, %rsi
callq 0x30ea
movl $0x28, %ecx
jmp 0x2ed3
testb $0x1, %al
je 0x2ebf
movq %r14, %rdi
movq %r15, %rsi
callq 0x30ea
movq (%rax), %rdi
movq (%rdi), %rax
callq *0x18(%rax)
movq 0x8(%rsp), %rax
movl (%rax,%rbp,4), %eax
testb $0x4, %al
je 0x2edc
movq %r14, %rdi
movq %r15, %rsi
callq 0x30ea
movl $0x20, %ecx
movq (%rax), %rdi
movq (%rdi), %rax
callq *(%rax,%rcx)
incq %rbx
cmpq %r13, %rbx
jne 0x2e39
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
movl (%rsp), %ebx
je 0x2efa
callq 0x3150
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x2f11
movq 0x18(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
movl %ebx, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1306(%rip), %rdi      # 0x422f
leaq 0x12a3(%rip), %rsi      # 0x41d3
leaq 0x1322(%rip), %rcx      # 0x4259
movl $0x1d, %edx
callq 0x2150
jmp 0x2f43
movq %rax, %rbx
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x2f5d
movq 0x18(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
movq %rbx, %rdi
callq 0x22c0
nop