// File: /workspace/github_cpp_makefile_star2_O2/sidscrazy[P]Paxos/paxos_node.cpp
// Function: PaxosNode::process_message(message*)
void process_message (message *m){
		if (m == NULL){
			return;
		}

		int reponse_code; 
		switch (m->type){
			case MSG_PREPARE: {
				if (m->round > n) {
					n = m->round;
				} 
				state = PREPARING;
				message response (id, m->sender, v, n, MSG_PREPARE_ACK);
				network_lock.lock ();
				send_message (0, &response);
				network_lock.unlock ();
				break; 
			}

			case MSG_PREPARE_ACK: {

				if (m->round > n){
					n = m->round;
					state = NO_VALUE;
					clear_responses ();
				} else if (m->round == n){
					bool already_voted = false;
					for (int i = 0; i < prepare_acks.size (); i++){
						if (prepare_acks [i] == m->sender){
							already_voted = true;
							break;
						}
					}
					if (!already_voted){
						prepare_acks.push_back (m->sender);
						if (v < m->value && !proposed_v){
							v = m->value;
						}
					}

				} else {
					message response (id, m->sender, NO_VALUE, n, MSG_UPDATE);
					network_lock.lock ();
					send_message (0, &response);
					network_lock.unlock ();
					 
				}
				break;
			}

			case MSG_PROPOSE: {
				if (m->round == n && state == PREPARING &&
					((m->value >= v && !proposed_v) || (m->value == v && proposed_v)) ){
					v = m->value;
					state = PROPOSING;
					proposed_v = true;
				} 
				message response (id, m->sender, v, n, MSG_PROPOSE_ACK);
				network_lock.lock ();
				send_message (0, &response);
				network_lock.unlock ();
				break;
			}

			case MSG_PROPOSE_ACK: {
				if (m->round > n){
					n = m->round;
					state = NO_VALUE;
					clear_responses ();
				} else if (m->round < n){
					message response (id, m->sender, NO_VALUE, n, MSG_UPDATE);
					network_lock.lock ();
					send_message (0, &response);
					network_lock.unlock ();

				} else {
					vote *vo = (vote *) malloc (sizeof (vote));
					vo->node = m->sender;
					vo->n = m->round;
					vo->v = m->value;
					votes.push_back (vo);
				} 
				break;
			}

			case MSG_UPDATE: {
				if (m->round > n){
					n = m->round;
					state = NO_VALUE;
					clear_responses ();
				}
				break; 
			}

			case MSG_CONSENSUS: {
				safe_exit (m);
				break;
			}

			case MSG_TEARDOWN: {
				safe_exit (m);
				break;
			}

			default: 
				break;
		}

		free (m);
		if (!(role & PROPOSER)){
			simulate_crash ();
		}
		
	}

// Assembly:
testq %rsi, %rsi
je 0x2d6c
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x20, %rsp
movq %rsi, %r14
movq %rdi, %rbx
movl 0x10(%rsi), %eax
decl %eax
cmpl $0x7, %eax
ja 0x2d4a
leaq 0x2433(%rip), %rcx      # 0x5004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3490
jmp 0x2d4a
movl 0xc(%r14), %ecx
movl 0x10(%rbx), %eax
cmpl %eax, %ecx
jle 0x2cd0
movl %ecx, 0x10(%rbx)
jmp 0x2cc2
movl 0xc(%r14), %ecx
movl 0x10(%rbx), %eax
cmpl %eax, %ecx
jle 0x2c11
movl %ecx, 0x10(%rbx)
movl %ecx, %eax
movl $0xfffffffc, 0x14(%rbx) # imm = 0xFFFFFFFC
movl (%r14), %ecx
movl (%rbx), %edx
movl 0xc(%rbx), %esi
leaq -0x40(%rbp), %r15
movl %edx, (%r15)
movl %ecx, 0x4(%r15)
movl %esi, 0x8(%r15)
movl %eax, 0xc(%r15)
movl $0x2, 0x10(%r15)
jmp 0x2d29
movl 0x10(%rbx), %eax
cmpl %eax, 0xc(%r14)
jne 0x2c78
cmpl $-0x4, 0x14(%rbx)
jne 0x2c78
movl 0x8(%r14), %ecx
movl 0xc(%rbx), %edx
cmpl %edx, %ecx
jl 0x2c60
cmpb $0x1, 0x18(%rbx)
jne 0x2c6a
cmpl %edx, %ecx
jne 0x2c78
cmpb $0x1, 0x18(%rbx)
jne 0x2c78
movl %ecx, 0xc(%rbx)
movl $0xfffffffb, 0x14(%rbx) # imm = 0xFFFFFFFB
movb $0x1, 0x18(%rbx)
movl (%r14), %ecx
movl (%rbx), %edx
movl 0xc(%rbx), %esi
leaq -0x40(%rbp), %r15
movl %edx, (%r15)
movl %ecx, 0x4(%r15)
movl %esi, 0x8(%r15)
movl %eax, 0xc(%r15)
movl $0x4, 0x10(%r15)
jmp 0x2d29
movl 0xc(%r14), %r15d
movl 0x10(%rbx), %eax
cmpl %eax, %r15d
jle 0x2d06
movl %r15d, 0x10(%rbx)
jmp 0x2cc2
movl 0xc(%r14), %eax
cmpl 0x10(%rbx), %eax
jle 0x2d4a
movl %eax, 0x10(%rbx)
orl $-0x1, 0x14(%rbx)
movq %rbx, %rdi
callq 0x33dc
jmp 0x2d4a
jne 0x2d08
leaq 0xe0(%rbx), %rdi
movq 0xe0(%rbx), %rax
movq 0xe8(%rbx), %rcx
subq %rax, %rcx
sarq $0x2, %rcx
xorl %edx, %edx
cmpq %rdx, %rcx
je 0x2d9a
movl (%rax,%rdx,4), %esi
incq %rdx
cmpl (%r14), %esi
jne 0x2cf0
jmp 0x2d4a
jge 0x2d6d
movl (%rbx), %ecx
movl (%r14), %edx
leaq -0x40(%rbp), %r15
movl %ecx, (%r15)
movl %edx, 0x4(%r15)
orl $-0x1, 0x8(%r15)
movl %eax, 0xc(%r15)
movl $0x5, 0x10(%r15)
leaq 0x28(%rbx), %r12
movq %r12, %rdi
callq 0x2b7e
movq %rbx, %rdi
xorl %esi, %esi
movq %r15, %rdx
callq 0x3280
movq %r12, %rdi
callq 0x2150
movq %r14, %rdi
callq 0x2200
testb $0x1, 0x8(%rbx)
jne 0x2d60
movq %rbx, %rdi
callq 0x34f0
addq $0x20, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
pushq $0xc
popq %rdi
callq 0x2250
leaq -0x40(%rbp), %rsi
movq %rax, (%rsi)
movl (%r14), %ecx
movl %ecx, (%rax)
movl %r15d, 0x4(%rax)
movl 0x8(%r14), %ecx
movl %ecx, 0x8(%rax)
leaq 0xc8(%rbx), %rdi
callq 0x346c
jmp 0x2d4a
movq %r14, %rsi
callq 0x3446
movl 0x8(%r14), %eax
cmpl %eax, 0xc(%rbx)
jge 0x2d4a
cmpb $0x0, 0x18(%rbx)
jne 0x2d4a
movl %eax, 0xc(%rbx)
jmp 0x2d4a