// File: /workspace/github_c_makefile_star2_O1/yancanchen[P]mc-bloom-filter/mc_bloom_filter.c
// Function: drive_machine
void drive_machine(conn *c) {

    int exit = 0;
    int sfd, flags = 1;
    socklen_t addrlen;
    struct sockaddr_in addr;
    conn *newc;
    int res;

    while (!exit) {
        /* printf("state %d\n", c->state);*/
        switch(c->state) {
            case conn_listening:
                addrlen = sizeof(addr);
                if ((sfd = accept(c->sfd, (struct sockaddr*)(&addr), &addrlen)) == -1) {
                    if (errno == EAGAIN || errno == EWOULDBLOCK) {
                        exit = 1;
                        break;
                    } else {
                        perror("accept()");
                        exit = 1;
                        break;
                    }
                    break;
                }
                if ((flags = fcntl(sfd, F_GETFL, 0)) < 0 ||
                        fcntl(sfd, F_SETFL, flags | O_NONBLOCK) < 0) {
                    perror("setting O_NONBLOCK");
                    close(sfd);
                    break;
                }        
                newc = conn_new(sfd, conn_read, EV_READ | EV_PERSIST);
                if (!newc) {
                    if (my_srv.verbose > 0)
                        fprintf(stderr, "couldn't create new connection\n");
                    close(sfd);
                    break;
                }

                break;

            case conn_read:
                if (try_read_command(c)) {
                    continue;
                }
                if (try_read_network(c)) {
                    continue;
                }
                /* we have no command line and no data to read from network */
                if (!update_event(c, EV_READ | EV_PERSIST)) {
                    if (my_srv.verbose > 0)
                        fprintf(stderr, "Couldn't update event\n");
                    c->state = conn_closing;
                    break;
                }
                exit = 1;
                break;

            case conn_nread:
                /* we are reading rlbytes into ritem; */
                if (c->rbytes >= c->rlbytes) {
                    complete_nread(c);
                    c->rcurr += c->rlbytes;
                    c->rbytes -= c->rlbytes;
                    c->rlbytes = 0;
                    continue;
                }

                if (try_read_network(c)) {
                    continue;
                }

                /* we have no command line and no data to read from network */
                if (!update_event(c, EV_READ | EV_PERSIST)) {
                    if (my_srv.verbose > 0)
                        fprintf(stderr, "Couldn't update event\n");
                    c->state = conn_closing;
                    break;
                }
                exit = 1;
                break;

            case conn_swallow:
                /* we are reading sbytes and throwing them away */
                if (c->sbytes == 0) {
                    c->state = conn_read;
                    break;
                }

                /* first check if we have leftovers in the conn_read buffer */
                if (c->rbytes > 0) {
                    int tocopy = c->rbytes > c->sbytes ? c->sbytes : c->rbytes;
                    c->sbytes -= tocopy;
                    c->rcurr += tocopy;
                    c->rbytes -= tocopy;
                    break;
                }

                /*  now try reading from the socket */
                res = read(c->sfd, c->rbuf, c->rsize > c->sbytes ? c->sbytes : c->rsize);
                if (res > 0) {
                    stats.bytes_read += res;
                    c->sbytes -= res;
                    break;
                }
                if (res == 0) { /* end of stream */
                    c->state = conn_closing;
                    break;
                }
                if (res == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
                    if (!update_event(c, EV_READ | EV_PERSIST)) {
                        if (my_srv.verbose > 0)
                            fprintf(stderr, "Couldn't update event\n");
                        c->state = conn_closing;
                        break;
                    }
                    exit = 1;
                    break;
                }
                /* otherwise we have a real error, on which we close the connection */
                if (my_srv.verbose > 0)
                    fprintf(stderr, "Failed to read, and not due to blocking\n");
                c->state = conn_closing;
                break;

            case conn_write:
                /* we are writing wbytes bytes starting from wcurr */
                if (c->wbytes == 0) {
                    c->state = c->write_and_go;
                    if (c->state == conn_read)
                        set_cork(c, 0);
                    break;
                }
                res = write(c->sfd, c->wcurr, c->wbytes);
                if (res > 0) {
                    stats.bytes_written += res;
                    c->wcurr  += res;
                    c->wbytes -= res;
                    break;
                }
                if (res == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
                    if (!update_event(c, EV_WRITE | EV_PERSIST)) {
                        if (my_srv.verbose > 0)
                            fprintf(stderr, "Couldn't update event\n");
                        c->state = conn_closing;
                        break;
                    }        
                    exit = 1;
                    break;
                }
                /* if res==0 or res==-1 and error is not EAGAIN or EWOULDBLOCK,
                   we have a real error, on which we close the connection */
                if (my_srv.verbose > 0)
                    fprintf(stderr, "Failed to write, and not due to blocking\n");
                c->state = conn_closing;
                break;

            case conn_closing:
                conn_close(c);
                exit = 1;
                break;
        }

    }

    return;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
movb $0x1, %bpl
leaq 0x1d3b(%rip), %r12      # 0x625c
leaq 0x8(%rsp), %r14
leaq 0x4(%rsp), %r15
xorl %r13d, %r13d
movl 0x4(%rbx), %eax
cmpq $0x5, %rax
ja 0x481f
movslq (%r12,%rax,4), %rax
addq %r12, %rax
jmpq *%rax
movq %rbx, %rdi
callq 0x42e6
testl %eax, %eax
jne 0x4606
movq %rbx, %rdi
callq 0x436d
testl %eax, %eax
jne 0x4606
movq %rbx, %rdi
movl $0x12, %esi
callq 0x449f
movl $0x1, %ebp
testl %eax, %eax
jne 0x4822
cmpl $0x0, 0x4d17(%rip)      # 0x929c
jle 0x47f8
callq 0x257f
jmp 0x47f8
movl 0xa4(%rbx), %eax
cmpl 0xa8(%rbx), %eax
jge 0x45e0
movq %rbx, %rdi
callq 0x436d
testl %eax, %eax
jne 0x4606
movq %rbx, %rdi
movl $0x12, %esi
callq 0x449f
movl $0x1, %ebp
testl %eax, %eax
jne 0x4822
cmpl $0x0, 0x4ccc(%rip)      # 0x929c
jle 0x47f8
callq 0x255d
jmp 0x47f8
movq %rbx, %rdi
callq 0x3d3e
movslq 0xa8(%rbx), %rax
addq %rax, 0x98(%rbx)
subl %eax, 0xa4(%rbx)
movl $0x0, 0xa8(%rbx)
testb $0x1, %bpl
jne 0x452e
jmp 0x487d
movl 0xf0(%rbx), %eax
testl %eax, %eax
je 0x4732
movl 0xa4(%rbx), %ecx
testl %ecx, %ecx
jle 0x4783
cmpl %eax, %ecx
movl %eax, %edx
cmovll %ecx, %edx
subl %edx, %eax
movl %eax, 0xf0(%rbx)
movslq %edx, %rax
addq %rax, 0x98(%rbx)
subl %eax, %ecx
movl %ecx, 0xa4(%rbx)
jmp 0x481f
movl $0x10, 0x4(%rsp)
movl (%rbx), %edi
movq %r14, %rsi
movq %r15, %rdx
callq 0x2380
cmpl $-0x1, %eax
je 0x473e
movl %eax, %ebp
movl %eax, %edi
movl $0x3, %esi
xorl %edx, %edx
xorl %eax, %eax
callq 0x20c0
testl %eax, %eax
js 0x480c
orl $0x800, %eax            # imm = 0x800
movl %ebp, %edi
movl $0x4, %esi
movl %eax, %edx
xorl %eax, %eax
callq 0x20c0
testl %eax, %eax
js 0x480c
movl %ebp, %edi
movl $0x1, %esi
movl $0x12, %edx
callq 0x3226
testq %rax, %rax
jne 0x481f
cmpl $0x0, 0x4bcf(%rip)      # 0x929c
jle 0x4818
callq 0x25a1
jmp 0x4818
movq %rbx, %rdi
callq 0x3451
movl $0x1, %ebp
jmp 0x4822
movslq 0xc4(%rbx), %rdx
testq %rdx, %rdx
je 0x4762
movl (%rbx), %edi
movq 0xb8(%rbx), %rsi
callq 0x20d0
testl %eax, %eax
jle 0x47ba
movl %eax, %ecx
andl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
addq %rcx, 0x4b60(%rip)      # 0x9280
addq %rcx, 0xb8(%rbx)
subl %eax, 0xc4(%rbx)
jmp 0x481f
movl $0x1, 0x4(%rbx)
jmp 0x481f
callq 0x2040
movl $0x1, %ebp
cmpl $0xb, (%rax)
je 0x4822
leaq 0x20eb(%rip), %rdi      # 0x6843
callq 0x2360
jmp 0x4822
movl 0xc8(%rbx), %eax
movl %eax, 0x4(%rbx)
cmpl $0x1, %eax
jne 0x481f
movq %rbx, %rdi
xorl %esi, %esi
callq 0x31c9
jmp 0x481f
movl (%rbx), %edi
movq 0x90(%rbx), %rsi
movl 0xa0(%rbx), %ecx
cmpl %eax, %ecx
cmovll %ecx, %eax
movslq %eax, %rdx
callq 0x21f0
testl %eax, %eax
jle 0x4801
movl %eax, %ecx
andl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
addq %rcx, 0x4ac6(%rip)      # 0x9278
subl %eax, 0xf0(%rbx)
jmp 0x481f
cmpl $-0x1, %eax
jne 0x47ef
callq 0x2040
cmpl $0xb, (%rax)
jne 0x47ef
movq %rbx, %rdi
movl $0x14, %esi
callq 0x449f
movl $0x1, %ebp
testl %eax, %eax
jne 0x4822
cmpl $0x0, 0x4ab6(%rip)      # 0x929c
jle 0x47f8
callq 0x24f7
jmp 0x47f8
cmpl $0x0, 0x4aa6(%rip)      # 0x929c
jg 0x4873
movl $0x5, 0x4(%rbx)
jmp 0x481f
cmpl $-0x1, %eax
je 0x4833
testl %eax, %eax
je 0x47f8
jmp 0x4863
leaq 0x2039(%rip), %rdi      # 0x684c
callq 0x2360
movl %ebp, %edi
callq 0x21c0
movl %r13d, %ebp
movl %ebp, %r13d
testl %ebp, %ebp
sete %bpl
je 0x452e
jmp 0x487d
callq 0x2040
cmpl $0xb, (%rax)
jne 0x4863
movq %rbx, %rdi
movl $0x12, %esi
callq 0x449f
movl $0x1, %ebp
testl %eax, %eax
jne 0x4822
cmpl $0x0, 0x4a42(%rip)      # 0x929c
jle 0x47f8
callq 0x2519
jmp 0x47f8
cmpl $0x0, 0x4a32(%rip)      # 0x929c
jle 0x47f8
callq 0x253b
jmp 0x47f8
callq 0x24d5
jmp 0x47f8
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq