// File: cybozu[P]yrmcds/cybozu/reactor.cpp
// Function: cybozu::reactor::poll()
void reactor::poll() {
    // process readable resources
    std::sort(m_readables.begin(), m_readables.end());
    std::unique_copy(m_readables.begin(), m_readables.end(),
                     std::back_inserter(m_readables_copy));
    m_readables.clear();
    for( int fd: m_readables_copy ) {
        if( ! m_resources[fd]->on_readable(fd) )
            remove_resource(fd);
    }
    m_readables_copy.clear();

    // process drop requests
    {
        lock_guard g(m_lock);
        m_drop_req_copy.swap(m_drop_req);
    }
    for( int fd: m_drop_req_copy )
        remove_resource(fd);
    m_drop_req_copy.clear();

    struct epoll_event events[EPOLL_SIZE];
    int timeout = m_readables.empty() ? POLLING_TIMEOUT : 0;
    int n = epoll_wait(m_fd, events, EPOLL_SIZE, timeout);
    if( n == -1 ) {
        if( errno == EINTR ) return;
        throw_unix_error(errno, "epoll_wait");
    }

    for( int i = 0; i < n; ++i ) {
        const struct epoll_event& ev = events[i];
        const int fd = ev.data.fd;
        resource& r = *(m_resources[fd]);
        if( ev.events & EPOLLERR ) {
            if( ! r.on_error(fd) )
                remove_resource(fd);
            continue;
        }
        if( ev.events & EPOLLHUP ) {
            if( ! r.on_hangup(fd) ) {
                remove_resource(fd);
                continue;
            }
        }
        if( ev.events & EPOLLIN ) {
            if( ! r.on_readable(fd) ) {
                remove_resource(fd);
                continue;
            }
        }
        if( ev.events & EPOLLOUT ) {
            if( ! r.on_writable(fd) )
                remove_resource(fd);
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x6b0, %rsp            # imm = 0x6B0
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x6b0(%rbp)
addq $0x40, %rdi
callq 0xffb0
movq -0x6b0(%rbp), %rdi
movq %rax, -0x10(%rbp)
addq $0x40, %rdi
callq 0xffe0
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x10130
movq -0x6b0(%rbp), %rdi
addq $0x40, %rdi
callq 0xffb0
movq -0x6b0(%rbp), %rdi
movq %rax, -0x20(%rbp)
addq $0x40, %rdi
callq 0xffe0
movq -0x6b0(%rbp), %rdi
movq %rax, -0x28(%rbp)
addq $0x58, %rdi
callq 0x101f0
movq %rax, -0x30(%rbp)
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x10170
movq -0x6b0(%rbp), %rdi
movq %rax, -0x38(%rbp)
addq $0x40, %rdi
callq 0x10220
movq -0x6b0(%rbp), %rax
addq $0x58, %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
callq 0xffb0
movq %rax, -0x48(%rbp)
movq -0x40(%rbp), %rdi
callq 0xffe0
movq %rax, -0x50(%rbp)
leaq -0x48(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x10240
testb $0x1, %al
jne 0xed25
jmp 0xed7b
leaq -0x48(%rbp), %rdi
callq 0x10280
movq -0x6b0(%rbp), %rdi
movl (%rax), %eax
movl %eax, -0x54(%rbp)
addq $0x8, %rdi
leaq -0x54(%rbp), %rsi
callq 0x102a0
movq %rax, %rdi
callq 0xfbd0
movq %rax, %rdi
movl -0x54(%rbp), %esi
movq (%rdi), %rax
callq *0x18(%rax)
testb $0x1, %al
jne 0xed6e
movq -0x6b0(%rbp), %rdi
movl -0x54(%rbp), %esi
callq 0xf040
jmp 0xed70
leaq -0x48(%rbp), %rdi
callq 0x102d0
jmp 0xed12
movq -0x6b0(%rbp), %rdi
addq $0x58, %rdi
callq 0x10220
movq -0x6b0(%rbp), %rsi
addq $0x70, %rsi
leaq -0x60(%rbp), %rdi
callq 0x102f0
movq -0x6b0(%rbp), %rsi
movq %rsi, %rdi
addq $0x90, %rdi
addq $0x78, %rsi
callq 0x10320
leaq -0x60(%rbp), %rdi
callq 0x10380
movq -0x6b0(%rbp), %rax
addq $0x90, %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rdi
callq 0xffb0
movq %rax, -0x70(%rbp)
movq -0x68(%rbp), %rdi
callq 0xffe0
movq %rax, -0x78(%rbp)
leaq -0x70(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x10240
testb $0x1, %al
jne 0xee00
jmp 0xee28
leaq -0x70(%rbp), %rdi
callq 0x10280
movq -0x6b0(%rbp), %rdi
movl (%rax), %eax
movl %eax, -0x7c(%rbp)
movl -0x7c(%rbp), %esi
callq 0xf040
leaq -0x70(%rbp), %rdi
callq 0x102d0
jmp 0xeded
movq -0x6b0(%rbp), %rdi
addq $0x90, %rdi
callq 0x10220
movq -0x6b0(%rbp), %rdi
addq $0x40, %rdi
callq 0x103b0
movb %al, %sil
movq -0x6b0(%rbp), %rax
xorl %ecx, %ecx
movl $0x64, %edx
testb $0x1, %sil
cmovnel %edx, %ecx
movl %ecx, -0x684(%rbp)
movl (%rax), %edi
leaq -0x680(%rbp), %rsi
movl -0x684(%rbp), %ecx
movl $0x80, %edx
callq 0x82c0
movl %eax, -0x688(%rbp)
cmpl $-0x1, -0x688(%rbp)
jne 0xeeb3
callq 0x8050
cmpl $0x4, (%rax)
jne 0xeea0
jmp 0xf02e
callq 0x8050
movl (%rax), %edi
leaq 0x6b505(%rip), %rsi     # 0x7a3b3
callq 0xa320
movl $0x0, -0x68c(%rbp)
movl -0x68c(%rbp), %eax
cmpl -0x688(%rbp), %eax
jge 0xf02e
movq -0x6b0(%rbp), %rdi
movslq -0x68c(%rbp), %rcx
leaq -0x680(%rbp), %rax
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x698(%rbp)
movq -0x698(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x69c(%rbp)
addq $0x8, %rdi
leaq -0x69c(%rbp), %rsi
callq 0x102a0
movq %rax, %rdi
callq 0x103f0
movq %rax, -0x6a8(%rbp)
movq -0x698(%rbp), %rax
movl (%rax), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0xef60
movq -0x6a8(%rbp), %rdi
movl -0x69c(%rbp), %esi
movq (%rdi), %rax
callq *0x30(%rax)
testb $0x1, %al
jne 0xef5b
movq -0x6b0(%rbp), %rdi
movl -0x69c(%rbp), %esi
callq 0xf040
jmp 0xf01a
movq -0x698(%rbp), %rax
movl (%rax), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0xef9e
movq -0x6a8(%rbp), %rdi
movl -0x69c(%rbp), %esi
movq (%rdi), %rax
callq *0x28(%rax)
testb $0x1, %al
jne 0xef9c
movq -0x6b0(%rbp), %rdi
movl -0x69c(%rbp), %esi
callq 0xf040
jmp 0xf01a
jmp 0xef9e
movq -0x698(%rbp), %rax
movl (%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0xefdc
movq -0x6a8(%rbp), %rdi
movl -0x69c(%rbp), %esi
movq (%rdi), %rax
callq *0x18(%rax)
testb $0x1, %al
jne 0xefda
movq -0x6b0(%rbp), %rdi
movl -0x69c(%rbp), %esi
callq 0xf040
jmp 0xf01a
jmp 0xefdc
movq -0x698(%rbp), %rax
movl (%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0xf018
movq -0x6a8(%rbp), %rdi
movl -0x69c(%rbp), %esi
movq (%rdi), %rax
callq *0x20(%rax)
testb $0x1, %al
jne 0xf016
movq -0x6b0(%rbp), %rdi
movl -0x69c(%rbp), %esi
callq 0xf040
jmp 0xf018
jmp 0xf01a
movl -0x68c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x68c(%rbp)
jmp 0xeebd
addq $0x6b0, %rsp            # imm = 0x6B0
popq %rbp
retq
nopw (%rax,%rax)