// File: /workspace/github_cpp_makefile_star2_O2/alibakhtiar[P]ExampleHTTPServer/./HttpServer.hh
// Function: SimpleHttpServer::createServer(SimpleHttpServer::Server*)
bool createServer(Server *server)
{
	int st;
	int serverFd;

	// Create new TCP socket(int family, int type, int protocol)
#ifdef __linux__
	serverFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
#else
	WSADATA WSAData;
	WSAStartup(MAKEWORD(2,0), &WSAData);
	serverFd = socket(AF_INET, SOCK_STREAM, 0);
#endif

	if (serverFd < 0) {
		APPERROR(_STRERR, _FUNC, _LINE);
		return false;
	}

	// Socket options
#ifdef __linux__
	int optVal = 1;

	// Re use address
	st = setsockopt(serverFd, SOL_SOCKET, SO_REUSEADDR, (void *)&optVal, sizeof(int));
	if (st == -1) {
		APPERROR(_STRERR, _FUNC, _LINE);
		return false;
	}

	// No-delay
	st = setsockopt(serverFd, IPPROTO_TCP, TCP_NODELAY, (void *)&optVal, sizeof(int));
	if (st == -1) {
		APPERROR(_STRERR, _FUNC, _LINE);
		return false;
	}
#else
	bool bOptVal = true;

	// No-delay
	int iResult = setsockopt(serverFd, SOL_SOCKET, SO_REUSEADDR, (char *)&bOptVal, sizeof(bool));
	if (iResult == SOCKET_ERROR) {
		APPERROR(_STRERR, _FUNC, _LINE);
		return 1;
	}
#endif

	// Bind
	struct sockaddr_in sockAddr;
	memset(&sockAddr, 0, sizeof(struct sockaddr_in));

	sockAddr.sin_family = AF_INET;
	sockAddr.sin_addr.s_addr = inet_addr((char *)server->ip.c_str());
	sockAddr.sin_port = htons(server->port);

	st = bind(serverFd, (struct sockaddr *)&sockAddr, sizeof(struct sockaddr_in));
	if (st == -1) {
		APPERROR(_STRERR, _FUNC, _LINE);
		return false;
	}

	// Listen
	st = listen(serverFd, BACKLOG_SIZE);
	if (st < 0) {
		APPERROR(_STRERR, _FUNC, _LINE);
		return false;
	}

	// Run (main loop)
	int clientFd;
	struct sockaddr_in clientAddr;
	socklen_t clientLength;

	clientLength = (socklen_t)sizeof(struct sockaddr_in);
	memset(&clientAddr, 0, sizeof(struct sockaddr_in));

	std::cout << "http://" << 
		server->ip << ":" << server->port << std::endl;

	while (1) {
		// Accept new connection (new socket)
		clientFd = accept(serverFd, (struct sockaddr *)&clientAddr, &clientLength);
		if (clientFd <= 0) {
			continue;
		}

		// New thread per connection
#ifdef __linux__
		std::thread(serverRequestHandler, server, std::move(clientFd), std::move(clientAddr)).detach();
#else
		serverRequestHandler(server, clientFd, clientAddr);
#endif
	}

	close(serverFd);

#ifndef __linux__
	WSACleanup();
#endif

	return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rdi, %r14
movq %rdi, 0x10(%rsp)
pushq $0x2
popq %rdi
pushq $0x1
popq %rsi
pushq $0x6
popq %rdx
callq 0x2080
testl %eax, %eax
jns 0x28fe
movq 0x5700(%rip), %rax      # 0x7fd0
movq (%rax), %rbx
callq 0x2050
movl (%rax), %edi
callq 0x20d0
leaq 0x274b(%rip), %rsi      # 0x5031
leaq 0x275f(%rip), %rcx      # 0x504c
movq %rbx, %rdi
movq %rax, %rdx
movl $0x1de, %r8d            # imm = 0x1DE
jmp 0x2a2a
movl %eax, %ebx
leaq 0x4(%rsp), %rcx
movl $0x1, (%rcx)
pushq $0x1
popq %rsi
pushq $0x2
popq %rdx
pushq $0x4
popq %r8
movl %eax, %edi
callq 0x2330
cmpl $-0x1, %eax
jne 0x2956
movq 0x56a8(%rip), %rax      # 0x7fd0
movq (%rax), %rbx
callq 0x2050
movl (%rax), %edi
callq 0x20d0
leaq 0x26f3(%rip), %rsi      # 0x5031
leaq 0x2707(%rip), %rcx      # 0x504c
movq %rbx, %rdi
movq %rax, %rdx
movl $0x1e9, %r8d            # imm = 0x1E9
jmp 0x2a2a
pushq $0x6
popq %rsi
pushq $0x1
popq %rdx
leaq 0x4(%rsp), %rcx
pushq $0x4
popq %r8
movl %ebx, %edi
callq 0x2330
cmpl $-0x1, %eax
jne 0x29a6
movq 0x5658(%rip), %rax      # 0x7fd0
movq (%rax), %rbx
callq 0x2050
movl (%rax), %edi
callq 0x20d0
leaq 0x26a3(%rip), %rsi      # 0x5031
leaq 0x26b7(%rip), %rcx      # 0x504c
movq %rbx, %rdi
movq %rax, %rdx
movl $0x1f0, %r8d            # imm = 0x1F0
jmp 0x2a2a
leaq 0x38(%rsp), %r15
andq $0x0, 0x8(%r15)
movw $0x2, (%r15)
movq 0x8(%r14), %rdi
callq 0x2220
movl %eax, 0x4(%r15)
movzwl 0x28(%r14), %eax
rolw $0x8, %ax
movw %ax, 0x2(%r15)
pushq $0x10
popq %rdx
movl %ebx, %edi
movq %r15, %rsi
callq 0x2060
movl $0x208, %ebp            # imm = 0x208
cmpl $-0x1, %eax
je 0x29fd
movl %ebx, %edi
movl $0x96, %esi
callq 0x2250
movl $0x20f, %ebp            # imm = 0x20F
testl %eax, %eax
jns 0x2a42
movq 0x55cc(%rip), %rax      # 0x7fd0
movq (%rax), %rbx
callq 0x2050
movl (%rax), %edi
callq 0x20d0
leaq 0x2617(%rip), %rsi      # 0x5031
leaq 0x262b(%rip), %rcx      # 0x504c
movq %rbx, %rdi
movq %rax, %rdx
movl %ebp, %r8d
xorl %eax, %eax
callq 0x22b0
xorl %eax, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x8(%r14), %r13
leaq 0x1c(%rsp), %r15
movl $0x10, (%r15)
xorps %xmm0, %xmm0
leaq 0x20(%rsp), %r12
movaps %xmm0, (%r12)
movq 0x5562(%rip), %rdi      # 0x7fc8
leaq 0x260d(%rip), %rsi      # 0x507a
callq 0x2200
movq %rax, %rdi
movq %r13, %rsi
callq 0x21e0
leaq 0x25fe(%rip), %rsi      # 0x5082
movq %rax, %rdi
callq 0x2200
movl 0x28(%r14), %esi
movq %rax, %rdi
callq 0x2300
movq %rax, %rdi
callq 0x2140
leaq 0x8(%rsp), %r13
leaq 0x10(%rsp), %rbp
movq %rsp, %r14
movl %ebx, %edi
movq %r12, %rsi
movq %r15, %rdx
callq 0x20b0
movl %eax, (%rsp)
testl %eax, %eax
jle 0x2aad
movq %r13, %rdi
leaq 0x35(%rip), %rsi        # 0x2b00
movq %rbp, %rdx
movq %r14, %rcx
movq %r12, %r8
callq 0x3176
movq %r13, %rdi
callq 0x2310
movq %r13, %rdi
callq 0x320c
jmp 0x2aad
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x320c
movq %rbx, %rdi
callq 0x2320