// File: tylerkaraszewski[P]Argyle/Server.cpp
// Function: Server::start()
bool Server::start()
{
  if (listen(m_mainSocket, 10))
  {
    m_logger.logError("Listen error(" + Utils::llToString(errno) + "): " + strerror(errno));
    close(m_mainSocket);
    return false;
  }

  initSocketList();

  while (m_shouldQuit == false)
  {
    int n = poll(m_sockets, m_socketCount, 1000);
    if (n == -1)
    {
      if (errno == EINTR)
      {
        // This happens when we try and exit. For a legit exit, m_shouldQuit should be set. For some other signal,
        // we'll just try and continue.
        continue;
      }
      m_logger.logError("Poll error(" + Utils::llToString(errno) + "): " + strerror(errno));
      close(m_mainSocket);
      return false;
    }
    // No socket activity, just start the next loop.
    if (n == 0)
    {
      continue;
    }

    int socketToWatch = -1;
    vector<int> socketsToUnwatch;
    for (int i = 0; i < m_socketCount; ++i)
    {
      // General error check.
      if (m_sockets[i].revents & POLLERR)
      {
        socketsToUnwatch.push_back(m_sockets[i].fd);
        continue;
      }
      if (m_sockets[i].revents & POLLHUP)
      {
        socketsToUnwatch.push_back(m_sockets[i].fd);
        continue;
      }
      if (m_sockets[i].revents & POLLNVAL)
      {
        socketsToUnwatch.push_back(m_sockets[i].fd);
        continue;
      }

      // Special socket.
      if (m_sockets[i].fd == m_mainSocket)
      {
        if (m_sockets[i].revents & POLLIN)
        {
          struct sockaddr_in newAddress;
          socklen_t newAddressSize = sizeof(newAddress);
          int newSocket = accept(m_mainSocket, (struct sockaddr*)&m_address, &newAddressSize);
          if (newSocket != -1)
          {
            socketToWatch = newSocket;
          }
          else
          {
            m_logger.logError("Accept error(" + Utils::llToString(errno) + "): " + strerror(errno));
          }
        }
      }
      else
      {
        bool isFinished = m_connections[m_sockets[i].fd]->process(m_sockets[i].events, m_sockets[i].revents);
        if (isFinished)
        {
          socketsToUnwatch.push_back(m_sockets[i].fd);
        }
      }
    }

    // @TODO: Timeout expiration goes here (or possibly after the 'unwatchSockets' call below).

    // Rebuild our socket list if anything has changed.
    unwatchSockets(socketsToUnwatch);
    watchSocket(socketToWatch);
  }
  return true;
}

// Assembly:
subq $0x238, %rsp            # imm = 0x238
movq %rdi, 0x228(%rsp)
movq 0x228(%rsp), %rax
movq %rax, 0x48(%rsp)
movl (%rax), %edi
movl $0xa, %esi
callq 0x4450
cmpl $0x0, %eax
je 0x55a8
movq 0x48(%rsp), %rax
movq 0x58(%rax), %rax
movq %rax, 0x38(%rsp)
callq 0x4060
movslq (%rax), %rsi
leaq 0x1a8(%rsp), %rdi
movq %rdi, 0x40(%rsp)
callq 0x10f70
movq 0x40(%rsp), %rdx
leaq 0xdbcf(%rip), %rsi      # 0x13034
leaq 0x1c8(%rsp), %rdi
callq 0x6230
jmp 0x5474
leaq 0xdb97(%rip), %rdx      # 0x13012
leaq 0x1e8(%rsp), %rdi
leaq 0x1c8(%rsp), %rsi
callq 0x61e0
jmp 0x5492
callq 0x4060
movl (%rax), %edi
callq 0x4150
movq %rax, %rdx
leaq 0x208(%rsp), %rdi
leaq 0x1e8(%rsp), %rsi
callq 0x61e0
jmp 0x54b8
movq 0x38(%rsp), %rdi
leaq 0x208(%rsp), %rsi
callq 0x10f40
jmp 0x54cc
leaq 0x208(%rsp), %rdi
callq 0x4788
leaq 0x1e8(%rsp), %rdi
callq 0x4788
leaq 0x1c8(%rsp), %rdi
callq 0x4788
leaq 0x1a8(%rsp), %rdi
callq 0x4788
movq 0x48(%rsp), %rax
movl (%rax), %edi
callq 0x4750
movb $0x0, 0x237(%rsp)
jmp 0x5b84
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
jmp 0x5596
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
jmp 0x5589
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
jmp 0x557c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
leaq 0x208(%rsp), %rdi
callq 0x4788
leaq 0x1e8(%rsp), %rdi
callq 0x4788
leaq 0x1c8(%rsp), %rdi
callq 0x4788
leaq 0x1a8(%rsp), %rdi
callq 0x4788
jmp 0x5b95
movq 0x48(%rsp), %rdi
callq 0x5bb0
movq 0x48(%rsp), %rax
movb 0x16(%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x5b7c
movq 0x48(%rsp), %rax
movq 0x8(%rax), %rdi
movslq 0x10(%rax), %rsi
movl $0x3e8, %edx            # imm = 0x3E8
callq 0x45c0
movl %eax, 0x198(%rsp)
cmpl $-0x1, 0x198(%rsp)
jne 0x5777
callq 0x4060
cmpl $0x4, (%rax)
jne 0x5600
jmp 0x55b2
movq 0x48(%rsp), %rax
movq 0x58(%rax), %rax
movq %rax, 0x28(%rsp)
callq 0x4060
movslq (%rax), %rsi
leaq 0x118(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0x10f70
movq 0x30(%rsp), %rdx
leaq 0xda0e(%rip), %rsi      # 0x13042
leaq 0x138(%rsp), %rdi
callq 0x6230
jmp 0x5643
leaq 0xd9c8(%rip), %rdx      # 0x13012
leaq 0x158(%rsp), %rdi
leaq 0x138(%rsp), %rsi
callq 0x61e0
jmp 0x5661
callq 0x4060
movl (%rax), %edi
callq 0x4150
movq %rax, %rdx
leaq 0x178(%rsp), %rdi
leaq 0x158(%rsp), %rsi
callq 0x61e0
jmp 0x5687
movq 0x28(%rsp), %rdi
leaq 0x178(%rsp), %rsi
callq 0x10f40
jmp 0x569b
leaq 0x178(%rsp), %rdi
callq 0x4788
leaq 0x158(%rsp), %rdi
callq 0x4788
leaq 0x138(%rsp), %rdi
callq 0x4788
leaq 0x118(%rsp), %rdi
callq 0x4788
movq 0x48(%rsp), %rax
movl (%rax), %edi
callq 0x4750
movb $0x0, 0x237(%rsp)
jmp 0x5b84
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
jmp 0x5765
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
jmp 0x5758
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
jmp 0x574b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
leaq 0x178(%rsp), %rdi
callq 0x4788
leaq 0x158(%rsp), %rdi
callq 0x4788
leaq 0x138(%rsp), %rdi
callq 0x4788
leaq 0x118(%rsp), %rdi
callq 0x4788
jmp 0x5b95
cmpl $0x0, 0x198(%rsp)
jne 0x5786
jmp 0x55b2
movl $0xffffffff, 0x114(%rsp) # imm = 0xFFFFFFFF
leaq 0xf8(%rsp), %rdi
callq 0x6280
movl $0x0, 0xf4(%rsp)
movq 0x48(%rsp), %rcx
movl 0xf4(%rsp), %eax
cmpl 0x10(%rcx), %eax
jge 0x5b34
movq 0x48(%rsp), %rax
movq 0x8(%rax), %rax
movslq 0xf4(%rsp), %rcx
movswl 0x6(%rax,%rcx,8), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x581e
movq 0x48(%rsp), %rax
movq 0x8(%rax), %rax
movslq 0xf4(%rsp), %rcx
leaq (%rax,%rcx,8), %rsi
leaq 0xf8(%rsp), %rdi
callq 0x6290
jmp 0x5800
jmp 0x5b1e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
jmp 0x5b6d
movq 0x48(%rsp), %rax
movq 0x8(%rax), %rax
movslq 0xf4(%rsp), %rcx
movswl 0x6(%rax,%rcx,8), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x5865
movq 0x48(%rsp), %rax
movq 0x8(%rax), %rax
movslq 0xf4(%rsp), %rcx
leaq (%rax,%rcx,8), %rsi
leaq 0xf8(%rsp), %rdi
callq 0x6290
jmp 0x5860
jmp 0x5b1e
movq 0x48(%rsp), %rax
movq 0x8(%rax), %rax
movslq 0xf4(%rsp), %rcx
movswl 0x6(%rax,%rcx,8), %eax
andl $0x20, %eax
cmpl $0x0, %eax
je 0x58ac
movq 0x48(%rsp), %rax
movq 0x8(%rax), %rax
movslq 0xf4(%rsp), %rcx
leaq (%rax,%rcx,8), %rsi
leaq 0xf8(%rsp), %rdi
callq 0x6290
jmp 0x58a7
jmp 0x5b1e
movq 0x48(%rsp), %rcx
movq 0x8(%rcx), %rax
movslq 0xf4(%rsp), %rdx
movl (%rax,%rdx,8), %eax
cmpl (%rcx), %eax
jne 0x5a8d
movq 0x48(%rsp), %rax
movq 0x8(%rax), %rax
movslq 0xf4(%rsp), %rcx
movswl 0x6(%rax,%rcx,8), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x5a88
movq 0x48(%rsp), %rsi
movl $0x10, 0xe0(%rsp)
movl (%rsi), %edi
addq $0x48, %rsi
leaq 0xe0(%rsp), %rdx
callq 0x4130
movl %eax, 0x24(%rsp)
jmp 0x5913
movl 0x24(%rsp), %eax
movl %eax, 0xdc(%rsp)
cmpl $-0x1, 0xdc(%rsp)
je 0x593b
movl 0xdc(%rsp), %eax
movl %eax, 0x114(%rsp)
jmp 0x5a86
movq 0x48(%rsp), %rax
movq 0x58(%rax), %rax
movq %rax, 0x18(%rsp)
callq 0x4060
movslq (%rax), %rsi
leaq 0x58(%rsp), %rdi
callq 0x10f70
jmp 0x595d
leaq 0xd6ea(%rip), %rsi      # 0x1304e
leaq 0x78(%rsp), %rdi
leaq 0x58(%rsp), %rdx
callq 0x6230
jmp 0x5975
leaq 0xd696(%rip), %rdx      # 0x13012
leaq 0x98(%rsp), %rdi
leaq 0x78(%rsp), %rsi
callq 0x61e0
jmp 0x5990
callq 0x4060
movl (%rax), %edi
callq 0x4150
movq %rax, %rdx
leaq 0xb8(%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0x61e0
jmp 0x59b6
movq 0x18(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
callq 0x10f40
jmp 0x59ca
leaq 0xb8(%rsp), %rdi
callq 0x4788
leaq 0x98(%rsp), %rdi
callq 0x4788
leaq 0x78(%rsp), %rdi
callq 0x4788
leaq 0x58(%rsp), %rdi
callq 0x4788
jmp 0x5a86
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
jmp 0x5a77
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
jmp 0x5a6d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
jmp 0x5a60
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
leaq 0xb8(%rsp), %rdi
callq 0x4788
leaq 0x98(%rsp), %rdi
callq 0x4788
leaq 0x78(%rsp), %rdi
callq 0x4788
leaq 0x58(%rsp), %rdi
callq 0x4788
jmp 0x5b6d
jmp 0x5a88
jmp 0x5b1c
movq 0x48(%rsp), %rax
movq %rax, %rdi
addq $0x18, %rdi
movq 0x8(%rax), %rax
movslq 0xf4(%rsp), %rcx
leaq (%rax,%rcx,8), %rsi
callq 0x6300
movq %rax, 0x10(%rsp)
jmp 0x5ab5
movq 0x48(%rsp), %rax
movq 0x10(%rsp), %rcx
movq (%rcx), %rdi
movq 0x8(%rax), %rax
movslq 0xf4(%rsp), %rcx
leaq 0x4(%rax,%rcx,8), %rsi
leaq 0x6(%rax,%rcx,8), %rdx
callq 0x8b30
movb %al, 0xf(%rsp)
jmp 0x5ae3
movb 0xf(%rsp), %al
andb $0x1, %al
movb %al, 0x57(%rsp)
testb $0x1, 0x57(%rsp)
je 0x5b1a
movq 0x48(%rsp), %rax
movq 0x8(%rax), %rax
movslq 0xf4(%rsp), %rcx
leaq (%rax,%rcx,8), %rsi
leaq 0xf8(%rsp), %rdi
callq 0x6290
jmp 0x5b18
jmp 0x5b1a
jmp 0x5b1c
jmp 0x5b1e
movl 0xf4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xf4(%rsp)
jmp 0x57a9
movq 0x48(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
callq 0x5cd0
jmp 0x5b48
movq 0x48(%rsp), %rdi
movl 0x114(%rsp), %esi
callq 0x5f50
jmp 0x5b5b
leaq 0xf8(%rsp), %rdi
callq 0x63f0
jmp 0x55b2
leaq 0xf8(%rsp), %rdi
callq 0x63f0
jmp 0x5b95
movb $0x1, 0x237(%rsp)
movb 0x237(%rsp), %al
andb $0x1, %al
addq $0x238, %rsp            # imm = 0x238
retq
movq 0x1a0(%rsp), %rdi
callq 0x46b0
nopw %cs:(%rax,%rax)