// File: sjtuwrk[P]SunwayMR/include/Messaging.hpp
// Function: Messaging::listenMessage(int)
void Messaging::listenMessage(int listenPort)
{
	listenStatus = NA;

	// init socket
	int server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (server_sockfd < 0) {
		listenStatus = FAILURE;
		pthread_mutex_unlock(&mutex_listen_status);
		return;
	}

	struct sockaddr_in server_address;

	server_address.sin_family = AF_INET;
	server_address.sin_addr.s_addr =  htonl(INADDR_ANY);
	server_address.sin_port = htons(listenPort);
	int server_len = sizeof(server_address);

	// bind
	int rb = bind(server_sockfd, (struct sockaddr *)&server_address, server_len);
	if (rb < 0)
	{
		listenStatus = FAILURE;
		pthread_mutex_unlock(&mutex_listen_status);
		return;
	}

	//listen
	int n = listen(server_sockfd, 36);
	if (n < 0)
	{
		listenStatus = FAILURE;
		pthread_mutex_unlock(&mutex_listen_status);
		return;
	}

	listenStatus = SUCCESS;
	pthread_mutex_unlock(&mutex_listen_status);

	stringstream listenInfo;
	listenInfo << "Messaging: listening on port [" << listenPort << "]";
	Logging::logInfo(listenInfo.str());

	struct sockaddr_in client_address;
	int client_len = sizeof(sockaddr_in);
	while (1) {
		int client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, (socklen_t *)&client_len);
		if (client_sockfd < 0) {
			stringstream ss;
			ss << "Messaging::listenMessage: accept failed, errno: " << errno;
			Logging::logWarning(ss.str());
			continue;
		}
		string ip = inet_ntoa(client_address.sin_addr);
		// thread data encapsulation
		struct xyz_messaging_listen_thread_data_ *td =
				new xyz_messaging_listen_thread_data_(
						this, listenPort, ip, client_sockfd);
		// create a thread
		pthread_t worker;
		if (pthread_create(&worker, NULL, messageHandler, (void *)td) != 0) {
			Logging::logError("Messaging: failed to create new thread while listening");
			close(client_sockfd);
		}
	}

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x480, %rsp            # imm = 0x480
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x438(%rbp)
movl $0x0, 0xe8(%rax)
movl $0x2, %edi
movl $0x1, %esi
xorl %edx, %edx
callq 0x40f0
movl %eax, -0x10(%rbp)
cmpl $0x0, -0x10(%rbp)
jge 0x8370
movq -0x438(%rbp), %rdi
movl $0x2, 0xe8(%rdi)
addq $0x8, %rdi
callq 0x42d0
jmp 0x883d
movw $0x2, -0x20(%rbp)
xorl %edi, %edi
callq 0x42e0
movl %eax, -0x1c(%rbp)
movl -0xc(%rbp), %eax
movzwl %ax, %edi
callq 0x4080
movw %ax, -0x1e(%rbp)
movl $0x10, -0x24(%rbp)
movl -0x10(%rbp), %edi
movl -0x24(%rbp), %edx
leaq -0x20(%rbp), %rsi
callq 0x4090
movl %eax, -0x28(%rbp)
cmpl $0x0, -0x28(%rbp)
jge 0x83cd
movq -0x438(%rbp), %rdi
movl $0x2, 0xe8(%rdi)
addq $0x8, %rdi
callq 0x42d0
jmp 0x883d
movl -0x10(%rbp), %edi
movl $0x24, %esi
callq 0x44a0
movl %eax, -0x2c(%rbp)
cmpl $0x0, -0x2c(%rbp)
jge 0x8402
movq -0x438(%rbp), %rdi
movl $0x2, 0xe8(%rdi)
addq $0x8, %rdi
callq 0x42d0
jmp 0x883d
movq -0x438(%rbp), %rdi
movl $0x1, 0xe8(%rdi)
addq $0x8, %rdi
callq 0x42d0
leaq -0x1b8(%rbp), %rdi
callq 0x4280
leaq -0x1a8(%rbp), %rdi
leaq 0x11deb(%rip), %rsi     # 0x1a221
callq 0x43f0
movq %rax, -0x440(%rbp)
jmp 0x8444
movq -0x440(%rbp), %rdi
movl -0xc(%rbp), %esi
callq 0x4750
movq %rax, -0x448(%rbp)
jmp 0x845c
movq -0x448(%rbp), %rdi
leaq 0x1244e(%rip), %rsi     # 0x1a8b8
callq 0x43f0
jmp 0x8471
leaq -0x1e8(%rbp), %rdi
leaq -0x1b8(%rbp), %rsi
callq 0x43e0
jmp 0x8486
leaq -0x1e8(%rbp), %rdi
callq 0x7140
jmp 0x8494
leaq -0x1e8(%rbp), %rdi
callq 0x4878
movl $0x10, -0x1fc(%rbp)
jmp 0x84ac
movl -0x10(%rbp), %edi
leaq -0x1f8(%rbp), %rsi
leaq -0x1fc(%rbp), %rdx
callq 0x4150
movl %eax, -0x44c(%rbp)
jmp 0x84ca
movl -0x44c(%rbp), %eax
movl %eax, -0x200(%rbp)
cmpl $0x0, -0x200(%rbp)
jge 0x85df
leaq -0x388(%rbp), %rdi
callq 0x4280
jmp 0x84f1
leaq -0x378(%rbp), %rdi
leaq 0x11d41(%rip), %rsi     # 0x1a240
callq 0x43f0
movq %rax, -0x458(%rbp)
jmp 0x850d
callq 0x4060
movq -0x458(%rbp), %rdi
movl (%rax), %esi
callq 0x4750
jmp 0x8522
leaq -0x3a8(%rbp), %rdi
leaq -0x388(%rbp), %rsi
callq 0x43e0
jmp 0x8537
leaq -0x3a8(%rbp), %rdi
callq 0x7220
jmp 0x8545
leaq -0x3a8(%rbp), %rdi
callq 0x4878
leaq -0x388(%rbp), %rdi
callq 0x42b0
jmp 0x84aa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1c0(%rbp)
movl %eax, -0x1c4(%rbp)
jmp 0x882f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1c0(%rbp)
movl %eax, -0x1c4(%rbp)
leaq -0x1e8(%rbp), %rdi
callq 0x4878
jmp 0x882f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1c0(%rbp)
movl %eax, -0x1c4(%rbp)
jmp 0x85ce
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1c0(%rbp)
movl %eax, -0x1c4(%rbp)
leaq -0x3a8(%rbp), %rdi
callq 0x4878
leaq -0x388(%rbp), %rdi
callq 0x42b0
jmp 0x882f
movl -0x1f4(%rbp), %eax
movl %eax, -0x3cc(%rbp)
movl -0x3cc(%rbp), %edi
callq 0x41c0
movq %rax, -0x468(%rbp)
leaq -0x3cd(%rbp), %rdi
movq %rdi, -0x460(%rbp)
callq 0x47a0
movq -0x468(%rbp), %rsi
movq -0x460(%rbp), %rdx
leaq -0x3c8(%rbp), %rdi
callq 0xe8d0
jmp 0x862c
leaq -0x3cd(%rbp), %rdi
callq 0x4470
movl $0x38, %edi
callq 0x4400
movq %rax, -0x470(%rbp)
jmp 0x864b
movb $0x1, -0x3f9(%rbp)
movl -0xc(%rbp), %eax
movl %eax, -0x474(%rbp)
leaq -0x3f8(%rbp), %rdi
leaq -0x3c8(%rbp), %rsi
callq 0x41a0
jmp 0x8670
movl -0x474(%rbp), %edx
movq -0x438(%rbp), %rsi
movq -0x470(%rbp), %rdi
movl -0x200(%rbp), %r8d
leaq -0x3f8(%rbp), %rcx
callq 0xef90
jmp 0x8699
movb $0x0, -0x3f9(%rbp)
leaq -0x3f8(%rbp), %rdi
callq 0x4878
movq -0x470(%rbp), %rax
movq %rax, -0x3d8(%rbp)
movq -0x3d8(%rbp), %rcx
leaq -0x408(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
leaq 0x18d(%rip), %rdx       # 0x8860
callq 0x47c0
cmpl $0x0, %eax
je 0x8812
leaq -0x429(%rbp), %rdi
movq %rdi, -0x480(%rbp)
callq 0x47a0
movq -0x480(%rbp), %rdx
leaq 0x11b6f(%rip), %rsi     # 0x1a271
leaq -0x428(%rbp), %rdi
callq 0xe8d0
jmp 0x8710
leaq -0x428(%rbp), %rdi
callq 0x7300
jmp 0x871e
leaq -0x428(%rbp), %rdi
callq 0x4878
leaq -0x429(%rbp), %rdi
callq 0x4470
movl -0x200(%rbp), %edi
callq 0x4840
jmp 0x8743
jmp 0x8812
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1c0(%rbp)
movl %eax, -0x1c4(%rbp)
leaq -0x3cd(%rbp), %rdi
callq 0x4470
jmp 0x882f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1c0(%rbp)
movl %eax, -0x1c4(%rbp)
jmp 0x8823
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1c0(%rbp)
movl %eax, -0x1c4(%rbp)
jmp 0x87b4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1c0(%rbp)
movl %eax, -0x1c4(%rbp)
leaq -0x3f8(%rbp), %rdi
callq 0x4878
testb $0x1, -0x3f9(%rbp)
jne 0x87bf
jmp 0x87d0
movq -0x470(%rbp), %rdi
movl $0x38, %esi
callq 0x4410
jmp 0x8823
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1c0(%rbp)
movl %eax, -0x1c4(%rbp)
jmp 0x8804
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1c0(%rbp)
movl %eax, -0x1c4(%rbp)
leaq -0x428(%rbp), %rdi
callq 0x4878
leaq -0x429(%rbp), %rdi
callq 0x4470
jmp 0x8823
leaq -0x3c8(%rbp), %rdi
callq 0x4878
jmp 0x84aa
leaq -0x3c8(%rbp), %rdi
callq 0x4878
leaq -0x1b8(%rbp), %rdi
callq 0x42b0
jmp 0x8846
addq $0x480, %rsp            # imm = 0x480
popq %rbp
retq
movq -0x1c0(%rbp), %rdi
callq 0x4780
nopw %cs:(%rax,%rax)