// File: /workspace/github_c_makefile_star2_O2/Tarsnap[P]kivaloo/kvlds/dispatch.c
// Function: gotrequest
static int
gotrequest(void * cookie, int status)
{
	struct dispatch_state * D = cookie;
	struct proto_kvlds_request * R;
	struct requestq * RQ;

	/* We're no longer waiting for a packet to arrive. */
	D->read_cookie = NULL;

	/* If the wait failed, the connection is dead. */
	if (status)
		goto drop;

	/*
	 * Read packets until there are no more to read, we hit MAXREQS, or
	 * an error occurs.
	 */
	do {
		/* Allocate space for a request. */
		if ((R = proto_kvlds_request_alloc()) == NULL)
			goto err0;

		/* If we have MAXREQS requests, stop looping. */
		if (D->nrequests == MAXREQS)
			break;

		/* Attempt to read a request. */
		if (proto_kvlds_request_read(D->readq, R))
			goto drop1;

		/* If we have no request, stop looping. */
		if (R->type == PROTO_KVLDS_NONE)
			break;

		/* We owe a response to the client. */
		D->nrequests += 1;

		/* Construct a linked list node. */
		if ((RQ = mpool_requestq_malloc()) == NULL)
			goto err1;
		RQ->R = R;
		RQ->next = NULL;

		/* Add to the modifying or non-modifying queue, and poke it. */
		switch (R->type) {
		case PROTO_KVLDS_PARAMS:
			/* Send the response immediately. */
			if (proto_kvlds_response_params(D->writeq, RQ->R->ID,
			    (uint32_t)D->kmax, (uint32_t)D->vmax))
				goto err2;

			/* Free the linked list node. */
			mpool_requestq_free(RQ);

			/* Free the request packet. */
			proto_kvlds_request_free(R);

			/* This request has been handled. */
			D->nrequests -= 1;
			break;
		case PROTO_KVLDS_CAS:
		case PROTO_KVLDS_SET:
		case PROTO_KVLDS_ADD:
		case PROTO_KVLDS_MODIFY:
			/*
			 * We can't add or modify a key-value pair if the key
			 * is too long or the value we're setting is too long.
			 */
			if ((R->key->len > D->kmax) ||
			    (R->value->len > D->vmax))
				goto drop2;

			/* FALLTHROUGH */

		case PROTO_KVLDS_DELETE:
		case PROTO_KVLDS_CAD:
			/* Add to modifying request queue. */
			if (D->mr_head == NULL)
				D->mr_head = RQ;
			else
				*(D->mr_tail) = RQ;
			D->mr_tail = &RQ->next;

			/* The MR queue has gained an element. */
			D->mr_qlen += 1;

			/* Poke the queue. */
			if (poke_mr(D))
				goto err0;
			break;
		case PROTO_KVLDS_GET:
		case PROTO_KVLDS_RANGE:
			/* Add to non-modifying request queue. */
			if (D->nmr_head == NULL)
				D->nmr_head = RQ;
			else
				*(D->nmr_tail) = RQ;
			D->nmr_tail = &RQ->next;

			/* Poke the queue. */
			if (poke_nmr(D))
				goto err0;
			break;
		default:
			/* Don't recognize this packet... */
			warn0("Received unrecognized packet type: 0x%08" PRIx32,
			    R->type);
			goto drop2;
		}
	} while (1);

	/* Free the (unused) request structure. */
	proto_kvlds_request_free(R);

	/* Wait for more requests to arrive. */
	if (readreqs(D))
		goto err0;

	/* Success! */
	return (0);

drop2:
	mpool_requestq_free(RQ);
	D->nrequests -= 1;
drop1:
	proto_kvlds_request_free(R);
drop:
	/* We didn't get a valid request.  Drop the connection. */
	dropconnection(D);

	/* All is good. */
	return (0);

err2:
	mpool_requestq_free(RQ);
err1:
	D->nrequests -= 1;
	proto_kvlds_request_free(R);
err0:
	/* Failure! */
	return (-1);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
andq $0x0, 0x18(%rdi)
testl %esi, %esi
je 0x3ab2
movq %rbx, %rdi
callq 0x3d6d
xorl %eax, %eax
jmp 0x3c88
leaq 0x40(%rbx), %r13
leaq 0x60(%rbx), %r14
pushq $0x20
popq %rbp
callq 0xe824
testq %rax, %rax
je 0x3c85
movq %rax, %r15
cmpq $0x1000, 0x20(%rbx)     # imm = 0x1000
je 0x3c60
movq 0x8(%rbx), %rdi
movq %r15, %rsi
callq 0xe884
testl %eax, %eax
jne 0x3cb9
cmpl $-0x1, 0x8(%r15)
je 0x3c60
incq 0x20(%rbx)
incq 0x17732(%rip)           # 0x1b238
movq 0x17713(%rip), %rax     # 0x1b220
testq %rax, %rax
je 0x3b2b
movq 0x17717(%rip), %rcx     # 0x1b230
leaq -0x1(%rax), %rdx
movq %rdx, 0x176fc(%rip)     # 0x1b220
movq -0x8(%rcx,%rax,8), %r12
jmp 0x3b5c
incq 0x1770e(%rip)           # 0x1b240
cmpl $0x0, 0x1770f(%rip)     # 0x1b248
jne 0x3b51
movq 0x17716(%rip), %rdi     # 0x1b258
callq 0x10c20
movl $0x1, 0x176f7(%rip)     # 0x1b248
movq %rbp, %rdi
callq 0x22a0
movq %rax, %r12
testq %r12, %r12
je 0x3c79
movq %r15, (%r12)
andq $0x0, 0x8(%r12)
movl 0x8(%r15), %esi
leal -0x110(%rsi), %ecx
cmpl $0x21, %ecx
ja 0x3c19
leaq 0x8(%r12), %rax
pushq $0xf
popq %rdx
btq %rcx, %rdx
jb 0x3bca
movl $0x30000, %edx          # imm = 0x30000
btq %rcx, %rdx
jb 0x3bec
movabsq $0x300000000, %rdx      # imm = 0x300000000
btq %rcx, %rdx
jae 0x3c19
cmpq $0x0, (%r13)
movq %r13, %rcx
je 0x3bb9
movq 0x48(%rbx), %rcx
movq %r12, (%rcx)
movq %rax, 0x48(%rbx)
movq %rbx, %rdi
callq 0x3cc6
jmp 0x3c0f
movq 0x10(%r15), %rcx
movzbl (%rcx), %ecx
cmpq %rcx, 0x30(%rbx)
jb 0x3cad
movq 0x18(%r15), %rcx
movzbl (%rcx), %ecx
cmpq %rcx, 0x38(%rbx)
jb 0x3cad
cmpq $0x0, (%r14)
movq %r14, %rcx
je 0x3bf9
movq 0x68(%rbx), %rcx
movq %r12, (%rcx)
movq %rax, 0x68(%rbx)
incq 0x88(%rbx)
movq %rbx, %rdi
callq 0x363c
testl %eax, %eax
je 0x3abd
jmp 0x3c85
cmpl $0x100, %esi            # imm = 0x100
jne 0x3c97
movq 0x10(%rbx), %rdi
movq (%r15), %rsi
movl 0x30(%rbx), %edx
movl 0x38(%rbx), %ecx
callq 0xec84
movq %r13, (%rsp)
movq %rbp, %r13
movl %eax, %ebp
movq %r12, %rdi
callq 0x3877
testl %ebp, %ebp
movq %r13, %rbp
movq (%rsp), %r13
jne 0x3c79
movq %r15, %rdi
callq 0xeb7a
decq 0x20(%rbx)
jmp 0x3abd
movq %r15, %rdi
callq 0xeb7a
movq %rbx, %rdi
callq 0x3a0f
testl %eax, %eax
jne 0x3c85
jmp 0x3aab
decq 0x20(%rbx)
movq %r15, %rdi
callq 0xeb7a
pushq $-0x1
popq %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xd900(%rip), %rdi      # 0x1159e
xorl %eax, %eax
callq 0xe0e4
callq 0x20a0
andl $0x0, (%rax)
movq %r12, %rdi
callq 0x3877
decq 0x20(%rbx)
movq %r15, %rdi
callq 0xeb7a
jmp 0x3aa3