// File: TheiaRT[P]libiris/tcp_server.cpp
// Function: TCPServer::start(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int, int)
bool TCPServer::start(std::string host, int port, int backlog)
{
    /* Open a new socket for the server. */
    if ((parentsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("Could not open socket.");
        return false;
    }

    /* Can re-run immediately after kill, instead of waiting. */
    optval = 1;
    setsockopt(parentsock, SOL_SOCKET, SO_REUSEADDR,
               (const void *)&optval, sizeof(optval));

    /* Zero out the server_addr. */
    bzero((char *) &server_addr, sizeof(server_addr));

    server_addr.sin_family = AF_INET;
    /* Let the system figure out our IP address. */
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons((unsigned short) port);

    /* Bind to the port. */
    if (bind(parentsock,
             (struct sockaddr *) &server_addr,
             sizeof(server_addr)) < 0) {
        perror("Could not bind.");
        return false;
    }

    /* Listen on the port with a backlog of up to backlog connections. */
    if (listen(parentsock, backlog) < 0) {
        perror("Could not listen.");
        return false;
    }

    /* Make the loop thread runnable. */
    *running = true;

    /* Start the loop! Go! */
    loop_thread = new std::thread([=] { serve_loop(); });
    return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movl %ecx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x40(%rbp)
movl $0x2, %edi
movl $0x1, %esi
xorl %edx, %edx
callq 0x2070
movq -0x40(%rbp), %rcx
movl %eax, 0x4(%rcx)
cmpl $0x0, %eax
jge 0x26f0
leaq 0x3922(%rip), %rdi      # 0x6004
callq 0x21e0
movb $0x0, -0x1(%rbp)
jmp 0x280b
movq -0x40(%rbp), %rcx
movl $0x1, (%rcx)
movl 0x4(%rcx), %edi
movl $0x1, %esi
movl $0x2, %edx
movl $0x4, %r8d
callq 0x2380
movq -0x40(%rbp), %rdi
addq $0x8, %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x2140
movq -0x40(%rbp), %rax
movw $0x2, 0x8(%rax)
xorl %edi, %edi
callq 0x21b0
movl %eax, %ecx
movq -0x40(%rbp), %rax
movl %ecx, 0xc(%rax)
movl -0x1c(%rbp), %eax
movzwl %ax, %edi
callq 0x2040
movq -0x40(%rbp), %rsi
movw %ax, 0xa(%rsi)
movl 0x4(%rsi), %edi
addq $0x8, %rsi
movl $0x10, %edx
callq 0x2050
cmpl $0x0, %eax
jge 0x277e
leaq 0x38ab(%rip), %rdi      # 0x601b
callq 0x21e0
movb $0x0, -0x1(%rbp)
jmp 0x280b
movq -0x40(%rbp), %rax
movl 0x4(%rax), %edi
movl -0x20(%rbp), %esi
callq 0x22d0
cmpl $0x0, %eax
jge 0x27a4
leaq 0x3892(%rip), %rdi      # 0x602b
callq 0x21e0
movb $0x0, -0x1(%rbp)
jmp 0x280b
movq -0x40(%rbp), %rax
movq 0x58(%rax), %rdi
movl $0x1, %esi
callq 0x36d0
movl $0x8, %edi
callq 0x2260
movq %rax, %rdi
movq -0x40(%rbp), %rax
movq %rdi, %rcx
movq %rcx, -0x48(%rbp)
movq %rax, -0x28(%rbp)
leaq -0x28(%rbp), %rsi
callq 0x2820
jmp 0x27dd
movq -0x40(%rbp), %rax
movq -0x48(%rbp), %rcx
movq %rcx, 0x60(%rax)
movb $0x1, -0x1(%rbp)
jmp 0x280b
movq -0x48(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
movl $0x8, %esi
callq 0x2270
jmp 0x2816
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x50, %rsp
popq %rbp
retq
movq -0x30(%rbp), %rdi
callq 0x2360
nop