// File: qian-jiahong[P]uvncrep017-ws/repeater.cpp
// Function: routeConnections(int, int)
static void routeConnections(int viewerSocket, int serverSocket)
{
    int seconds;
    int heartBeatSeconds;
    fd_set readfds;
    int numfds;
    bool select_ok;
    struct timeval tv;
    const int SELECT_WAIT_SECONDS=1;
    const int CLEANUP_SECONDS=5;
    const int HEARTBEAT_SECONDS=90;
    startEndEvent seEv;
        
    seconds = 0;
    heartBeatSeconds = 0;
    numfds = myMax(viewerSocket, serverSocket) + 1;

    debug(LEVEL_0, "routeConnections(): starting select() loop, terminate with ctrl+c\n");
    while (stopped == false) {
        FD_ZERO(&readfds);
        
        if (viewerSocket != -1)
            FD_SET(viewerSocket, &readfds);
            
        if (serverSocket != -1)
            FD_SET(serverSocket, &readfds);

        tv.tv_sec = SELECT_WAIT_SECONDS;
        tv.tv_usec = 0;
        
        select_ok = true;
        if (-1 == select(numfds, &readfds, NULL, NULL, &tv)) {
            select_ok = false;
            if (stopped == false) {
                debug(LEVEL_2, "routeConnections(): select() failed, errno=%d (%s)\n", errno, strerror(errno));
            }
        }

        if ((select_ok == true) && (stopped == false)) {
            //New viewer trying to connect ?
            if (viewerSocket != -1) {
                if (FD_ISSET(viewerSocket, &readfds)) {
                    debug(LEVEL_3, "routeConnections(): new viewer connecting, accepting...\n");
                    acceptConnection(viewerSocket, CONNECTION_FROM_VIEWER);
                }
            }

            //New server trying to connect ?
            if (serverSocket != -1) {
                if (FD_ISSET(serverSocket, &readfds)) {
                    debug(LEVEL_3, "routeConnections(): new server connecting, accepting...\n");
                    acceptConnection(serverSocket, CONNECTION_FROM_SERVER);
                }
            }

            //Remove old inactive connections, check after every 5 seconds
            seconds += SELECT_WAIT_SECONDS;
            if (seconds >= CLEANUP_SECONDS) {
                seconds = 0;
                removeOldOrBrokenConnections();
            }
            
            //Send REPEATER_HEATBEAT to event interface every 90 seconds
            heartBeatSeconds += SELECT_WAIT_SECONDS;
            if (heartBeatSeconds >= HEARTBEAT_SECONDS) {
                heartBeatSeconds = 0;
                if (useEventInterface) {
                    event.eventNum = REPEATER_HEARTBEAT;
                    event.timeStamp = time(NULL);
                    event.repeaterProcessId = getpid();
     
                    seEv.maxSessions = maxSessions;
                    memcpy(event.extraInfo, &seEv, sizeof(startEndEvent));
                    
                    if (false == sendRepeaterEvent(event)) {
                        debug(LEVEL_1, "routeConnections(): Warning, event fifo is full\n");
                    }
                }
            }
        
            //Clean up after children (Repeaterprocs that have exited)
            cleanUpAfterRepeaterProcs();
            
            //Handle event interface posting & cleanup
            handleRepeaterEvents();
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1e0, %rsp            # imm = 0x1E0
movl %edi, -0x4(%rbp)
movl %esi, -0x8(%rbp)
movl $0x1, -0xac(%rbp)
movl $0x5, -0xb0(%rbp)
movl $0x5a, -0xb4(%rbp)
movl $0x0, -0xc(%rbp)
movl $0x0, -0x10(%rbp)
movl -0x4(%rbp), %edi
movl -0x8(%rbp), %esi
callq 0x4580
addl $0x1, %eax
movl %eax, -0x94(%rbp)
xorl %edi, %edi
leaq 0x6e18(%rip), %rsi      # 0xaec2
movb $0x0, %al
callq 0x2480
movb 0xbae9(%rip), %al       # 0xfba0
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x4454
jmp 0x40c7
leaq -0x90(%rbp), %rax
movq %rax, -0xc8(%rbp)
movl $0x0, -0xbc(%rbp)
movl -0xbc(%rbp), %eax
cmpq $0x10, %rax
jae 0x4111
movq -0xc8(%rbp), %rax
movl -0xbc(%rbp), %ecx
movq $0x0, (%rax,%rcx,8)
movl -0xbc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xbc(%rbp)
jmp 0x40df
jmp 0x4113
cmpl $-0x1, -0x4(%rbp)
je 0x4150
movl -0x4(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movl %edx, %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
movq %rax, %rcx
movl -0x4(%rbp), %eax
movl $0x40, %esi
cltd
idivl %esi
cltq
orq -0x90(%rbp,%rax,8), %rcx
movq %rcx, -0x90(%rbp,%rax,8)
cmpl $-0x1, -0x8(%rbp)
je 0x418d
movl -0x8(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movl %edx, %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
movq %rax, %rcx
movl -0x8(%rbp), %eax
movl $0x40, %esi
cltd
idivl %esi
cltq
orq -0x90(%rbp,%rax,8), %rcx
movq %rcx, -0x90(%rbp,%rax,8)
movq $0x1, -0xa8(%rbp)
movq $0x0, -0xa0(%rbp)
movb $0x1, -0x95(%rbp)
movl -0x94(%rbp), %edi
leaq -0x90(%rbp), %rsi
xorl %eax, %eax
movl %eax, %ecx
leaq -0xa8(%rbp), %r8
movq %rcx, %rdx
callq 0x21f0
movl %eax, %ecx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpl %ecx, %eax
jne 0x4223
movb $0x0, -0x95(%rbp)
movb 0xb9be(%rip), %al       # 0xfba0
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x4221
callq 0x2030
movl (%rax), %eax
movl %eax, -0x144(%rbp)
callq 0x2030
movl (%rax), %edi
callq 0x20b0
movl -0x144(%rbp), %edx
movq %rax, %rcx
movl $0x2, %edi
leaq 0x6ceb(%rip), %rsi      # 0xaf05
movb $0x0, %al
callq 0x2480
jmp 0x4223
movb -0x95(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x444f
movb 0xb963(%rip), %al       # 0xfba0
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x444f
cmpl $-0x1, -0x4(%rbp)
je 0x42b7
movl -0x4(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
cltq
movq -0x90(%rbp,%rax,8), %rax
movq %rax, -0x150(%rbp)
movl -0x4(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x150(%rbp), %rax
movl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
andq %rcx, %rax
cmpq $0x0, %rax
je 0x42b5
movl $0x3, %edi
leaq 0x6c98(%rip), %rsi      # 0xaf39
movb $0x0, %al
callq 0x2480
movl -0x4(%rbp), %edi
movl $0x1, %esi
callq 0x45b0
jmp 0x42b7
cmpl $-0x1, -0x8(%rbp)
je 0x4320
movl -0x8(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
cltq
movq -0x90(%rbp,%rax,8), %rax
movq %rax, -0x158(%rbp)
movl -0x8(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x158(%rbp), %rax
movl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
andq %rcx, %rax
cmpq $0x0, %rax
je 0x431e
movl $0x3, %edi
leaq 0x6c65(%rip), %rsi      # 0xaf72
movb $0x0, %al
callq 0x2480
movl -0x8(%rbp), %edi
xorl %esi, %esi
callq 0x45b0
jmp 0x4320
movl -0xc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc(%rbp)
cmpl $0x5, -0xc(%rbp)
jl 0x433b
movl $0x0, -0xc(%rbp)
callq 0x56f0
movl -0x10(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x10(%rbp)
cmpl $0x5a, -0x10(%rbp)
jl 0x4445
movl $0x0, -0x10(%rbp)
leaq 0x13f98(%rip), %rax     # 0x182f4
testb $0x1, (%rax)
je 0x4443
movl $0x8, 0xd789(%rip)      # 0x11af8
xorl %eax, %eax
movl %eax, %edi
callq 0x21e0
movq %rax, 0xd781(%rip)      # 0x11b00
callq 0x22f0
movl %eax, 0xd77e(%rip)      # 0x11b08
leaq 0xb6af(%rip), %rax      # 0xfa40
movl (%rax), %eax
movl %eax, -0xb8(%rbp)
movl -0xb8(%rbp), %eax
movl %eax, 0xd767(%rip)      # 0x11b0c
leaq -0x140(%rbp), %rdi
leaq 0xd745(%rip), %rsi      # 0x11af8
movl $0x78, %edx
callq 0x21b0
movq -0xd0(%rbp), %rcx
movq %rsp, %rax
movq %rax, -0x160(%rbp)
movq %rcx, 0x70(%rax)
movups -0xe0(%rbp), %xmm0
movups %xmm0, 0x60(%rax)
movups -0xf0(%rbp), %xmm0
movups %xmm0, 0x50(%rax)
movups -0x100(%rbp), %xmm0
movups %xmm0, 0x40(%rax)
movups -0x140(%rbp), %xmm0
movups -0x130(%rbp), %xmm1
movups -0x120(%rbp), %xmm2
movups -0x110(%rbp), %xmm3
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
callq 0x9130
andb $0x1, %al
movzbl %al, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jne 0x4441
movl $0x1, %edi
leaq 0x6b71(%rip), %rsi      # 0xafab
movb $0x0, %al
callq 0x2480
jmp 0x4443
jmp 0x4445
callq 0x5760
callq 0x9200
jmp 0x40b1
addq $0x1e0, %rsp            # imm = 0x1E0
popq %rbp
retq
nopl (%rax)