// File: lega911[P]ijson/src/server.cpp
// Function: Loop::_loop()
void Loop::_loop() {
    epollfd = epoll_create1(0);
    if(epollfd < 0) THROW("epoll_create1");

    eitem events[MAX_EVENTS];
    char buf[BUF_SIZE];
    int countdown = 100;
    while(true) {
        int nready = epoll_wait(epollfd, events, MAX_EVENTS, 10);
        if(nready == -1) {
            if(server->log & 1) std::cout << ltime() << "epoll_wait error: " << errno << std::endl;
            continue;
        }
        stat_ioevent += nready;

        bool need_to_migrate = false;
        for (int i = 0; i < nready; i++) {
            int fd = events[i].data.fd;
            if(fd == server->fake_fd) {
                set_poll_mode(fd, -1);
                continue;
            }

            if(events[i].events & EPOLLERR || events[i].events & EPOLLHUP) {
                if(server->log & 2) std::cout << "epoll_wait returned EPOLLERR/EPOLLHUP (" << events[i].events << "): " << fd << std::endl;
                _close(fd);
                continue;
            }

            Connect* conn = server->connections[fd];
            if(conn->nloop != _nloop) {
                if(server->log & 1) std::cout << "loop warning: connection is in wrong loop\n";
                continue;
            }
            if(events[i].events & EPOLLIN) {
                int size = recv(fd, buf, BUF_SIZE, 0);
                if(size == 0) {
                    _close(fd);
                } else if(size < 0) {
                    if(errno == EAGAIN || errno == EWOULDBLOCK) {
                        // data is not ready yet
                        continue;
                    } else {
                        THROW("recv error");
                    }
                } else {
                    stat_recv += size;
                    try {
                        conn->on_recv(buf, size);
                    } catch (const Exception &e) {
                        if(server->log & 2) e.print("Exception in on_recv");
                        conn->close();
                    }
                    if(conn->is_closed()) _close(fd);
                }
            } else if(events[i].events & EPOLLOUT) {
                try {
                    conn->on_send();
                } catch (const Exception &e) {
                    if(server->log & 2) e.print("Exception in on_send");
                    conn->close();
                }
                if(conn->is_closed()) _close(fd);
            }

            if(conn->go_loop) need_to_migrate = true;
        }

        if(!_nloop) {
            countdown--;
            if(countdown <= 0) {
                countdown = 100;
                _check_timeout();
            }
        }

        _perform_to_send();
        if(need_to_migrate) _migrate_send();
        _delete_connections();
        _migrate_recv();
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x4c80, %rsp           # imm = 0x4C80
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x4c60(%rbp)
xorl %edi, %edi
callq 0x19380
movl %eax, %ecx
movq -0x4c60(%rbp), %rax
movl %ecx, (%rax)
cmpl $0x0, (%rax)
jge 0x28cf0
movl $0x30, %edi
callq 0x19180
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x4c68(%rbp)
leaq 0x1076b(%rip), %rsi     # 0x3940a
leaq 0x105a0(%rip), %rdx     # 0x39246
leaq 0x1076b(%rip), %r8      # 0x39418
movl $0x151, %ecx            # imm = 0x151
callq 0x22ba0
jmp 0x28cb9
movq -0x4c68(%rbp), %rdi
leaq 0x1e039(%rip), %rsi     # 0x46d00
leaq -0x5bbe(%rip), %rdx     # 0x23110
callq 0x19480
movq -0x4c68(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x10(%rbp)
movl %eax, -0x14(%rbp)
callq 0x19210
jmp 0x292be
movl $0x64, -0x4c24(%rbp)
movq -0x4c60(%rbp), %rax
movl (%rax), %edi
leaq -0xc20(%rbp), %rsi
movl $0x100, %edx            # imm = 0x100
movl $0xa, %ecx
callq 0x19170
movl %eax, -0x4c28(%rbp)
cmpl $-0x1, -0x4c28(%rbp)
jne 0x28d8f
movq -0x4c60(%rbp), %rax
movq 0x18(%rax), %rax
movl 0x20(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x28d8a
callq 0x36960
movq %rax, %rsi
movq 0x1e283(%rip), %rdi     # 0x46fd0
callq 0x192e0
movq %rax, %rdi
leaq 0x106cf(%rip), %rsi     # 0x3942b
callq 0x192e0
movq %rax, -0x4c70(%rbp)
callq 0x19050
movq -0x4c70(%rbp), %rdi
movl (%rax), %esi
callq 0x19490
movq %rax, %rdi
movq 0x1e22b(%rip), %rsi     # 0x46fb0
callq 0x19320
jmp 0x28cfa
movq -0x4c60(%rbp), %rax
movslq -0x4c28(%rbp), %rcx
addq 0xa0(%rax), %rcx
movq %rcx, 0xa0(%rax)
movb $0x0, -0x4c29(%rbp)
movl $0x0, -0x4c30(%rbp)
movl -0x4c30(%rbp), %eax
cmpl -0x4c28(%rbp), %eax
jge 0x29243
movq -0x4c60(%rbp), %rcx
movslq -0x4c30(%rbp), %rdx
leaq -0xc20(%rbp), %rax
imulq $0xc, %rdx, %rdx
addq %rdx, %rax
movl 0x4(%rax), %eax
movl %eax, -0x4c34(%rbp)
movl -0x4c34(%rbp), %eax
movq 0x18(%rcx), %rcx
cmpl 0x30(%rcx), %eax
jne 0x28e1e
movq -0x4c60(%rbp), %rdi
movl -0x4c34(%rbp), %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x292d0
jmp 0x2922f
movslq -0x4c30(%rbp), %rcx
leaq -0xc20(%rbp), %rax
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %eax
andl $0x8, %eax
cmpl $0x0, %eax
jne 0x28e60
movslq -0x4c30(%rbp), %rcx
leaq -0xc20(%rbp), %rax
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x28eeb
movq -0x4c60(%rbp), %rax
movq 0x18(%rax), %rax
movl 0x20(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x28ed4
movq 0x1e153(%rip), %rdi     # 0x46fd0
leaq 0x105ba(%rip), %rsi     # 0x3943e
callq 0x192e0
movq %rax, %rdi
movslq -0x4c30(%rbp), %rcx
leaq -0xc20(%rbp), %rax
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %esi
callq 0x193a0
movq %rax, %rdi
leaq 0x105b4(%rip), %rsi     # 0x39466
callq 0x192e0
movq %rax, %rdi
movl -0x4c34(%rbp), %esi
callq 0x19490
movq %rax, %rdi
movq 0x1e0e1(%rip), %rsi     # 0x46fb0
callq 0x19320
movq -0x4c60(%rbp), %rdi
movl -0x4c34(%rbp), %esi
callq 0x29450
jmp 0x2922f
movq -0x4c60(%rbp), %rcx
movq 0x18(%rcx), %rax
movslq -0x4c34(%rbp), %rdx
movq 0x50(%rax,%rdx,8), %rax
movq %rax, -0x4c40(%rbp)
movq -0x4c40(%rbp), %rax
movl 0x38(%rax), %eax
cmpl 0x4(%rcx), %eax
je 0x28f46
movq -0x4c60(%rbp), %rax
movq 0x18(%rax), %rax
movl 0x20(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x28f41
movq 0x1e09b(%rip), %rdi     # 0x46fd0
leaq 0x1052e(%rip), %rsi     # 0x3946a
callq 0x192e0
jmp 0x2922f
movslq -0x4c30(%rbp), %rcx
leaq -0xc20(%rbp), %rax
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x29132
movl -0x4c34(%rbp), %edi
leaq -0x4c20(%rbp), %rsi
movl $0x4000, %edx           # imm = 0x4000
xorl %ecx, %ecx
callq 0x190f0
movl %eax, -0x4c44(%rbp)
cmpl $0x0, -0x4c44(%rbp)
jne 0x28fa8
movq -0x4c60(%rbp), %rdi
movl -0x4c34(%rbp), %esi
callq 0x29450
jmp 0x2912d
cmpl $0x0, -0x4c44(%rbp)
jge 0x2903d
callq 0x19050
cmpl $0xb, (%rax)
je 0x28fc9
callq 0x19050
cmpl $0xb, (%rax)
jne 0x28fce
jmp 0x2922f
movl $0x30, %edi
callq 0x19180
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x4c78(%rbp)
leaq 0x104a9(%rip), %rsi     # 0x39495
leaq 0x10253(%rip), %rdx     # 0x39246
leaq 0x1041e(%rip), %r8      # 0x39418
movl $0x17a, %ecx            # imm = 0x17A
callq 0x22ba0
jmp 0x29006
movq -0x4c78(%rbp), %rdi
leaq 0x1dcec(%rip), %rsi     # 0x46d00
leaq -0x5f0b(%rip), %rdx     # 0x23110
callq 0x19480
movq -0x4c78(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x10(%rbp)
movl %eax, -0x14(%rbp)
callq 0x19210
jmp 0x292be
movq -0x4c60(%rbp), %rax
movslq -0x4c44(%rbp), %rdx
movq 0x90(%rax), %rcx
addq %rdx, %rcx
movq %rcx, 0x90(%rax)
movq -0x4c40(%rbp), %rdi
movl -0x4c44(%rbp), %edx
leaq -0x4c20(%rbp), %rsi
callq 0x19e80
jmp 0x29077
jmp 0x290fe
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x10(%rbp)
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x292be
movq -0x10(%rbp), %rdi
callq 0x19120
movq %rax, %rcx
movq -0x4c60(%rbp), %rax
movq %rcx, -0x4c50(%rbp)
movq 0x18(%rax), %rax
movl 0x20(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x290eb
movq -0x4c50(%rbp), %rdi
leaq 0x103d1(%rip), %rsi     # 0x394a0
callq 0x22ff0
jmp 0x290d6
jmp 0x290eb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x10(%rbp)
movl %eax, -0x14(%rbp)
callq 0x19450
jmp 0x29124
movq -0x4c40(%rbp), %rdi
callq 0x1e9b0
jmp 0x290f9
callq 0x19450
movq -0x4c40(%rbp), %rdi
callq 0x1fcc0
testb $0x1, %al
jne 0x29110
jmp 0x29129
movq -0x4c60(%rbp), %rdi
movl -0x4c34(%rbp), %esi
callq 0x29450
jmp 0x29129
jmp 0x292be
jmp 0x2912b
jmp 0x2912d
jmp 0x29219
movslq -0x4c30(%rbp), %rcx
leaq -0xc20(%rbp), %rax
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x29217
movq -0x4c40(%rbp), %rdi
callq 0x19b70
jmp 0x29163
jmp 0x291ea
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x10(%rbp)
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x292be
movq -0x10(%rbp), %rdi
callq 0x19120
movq %rax, %rcx
movq -0x4c60(%rbp), %rax
movq %rcx, -0x4c58(%rbp)
movq 0x18(%rax), %rax
movl 0x20(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x291d7
movq -0x4c58(%rbp), %rdi
leaq 0x102fa(%rip), %rsi     # 0x394b5
callq 0x22ff0
jmp 0x291c2
jmp 0x291d7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x10(%rbp)
movl %eax, -0x14(%rbp)
callq 0x19450
jmp 0x29210
movq -0x4c40(%rbp), %rdi
callq 0x1e9b0
jmp 0x291e5
callq 0x19450
movq -0x4c40(%rbp), %rdi
callq 0x1fcc0
testb $0x1, %al
jne 0x291fc
jmp 0x29215
movq -0x4c60(%rbp), %rdi
movl -0x4c34(%rbp), %esi
callq 0x29450
jmp 0x29215
jmp 0x292be
jmp 0x29217
jmp 0x29219
movq -0x4c40(%rbp), %rax
testb $0x1, 0x40(%rax)
je 0x2922d
movb $0x1, -0x4c29(%rbp)
jmp 0x2922f
movl -0x4c30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c30(%rbp)
jmp 0x28dbc
movq -0x4c60(%rbp), %rax
cmpl $0x0, 0x4(%rax)
jne 0x29280
movl -0x4c24(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x4c24(%rbp)
cmpl $0x0, -0x4c24(%rbp)
jg 0x2927e
movq -0x4c60(%rbp), %rdi
movl $0x64, -0x4c24(%rbp)
callq 0x295a0
jmp 0x29280
movq -0x4c60(%rbp), %rdi
callq 0x29920
testb $0x1, -0x4c29(%rbp)
je 0x292a1
movq -0x4c60(%rbp), %rdi
callq 0x299c0
movq -0x4c60(%rbp), %rdi
callq 0x29be0
movq -0x4c60(%rbp), %rdi
callq 0x29d20
jmp 0x28cfa
movq -0x10(%rbp), %rdi
callq 0x194a0
movq %rax, %rdi
callq 0x1eb30
nop