// File: /workspace/github_c_makefile_star2_O2/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
leaq 0x11d9(%rip), %rbp      # 0x525c
leaq 0x8(%rsp), %r14
leaq 0x4(%rsp), %r15
pushq $0x12
popq %r12
movl 0x4(%rbx), %eax
cmpq $0x5, %rax
ja 0x4091
movslq (%rbp,%rax,4), %rax
addq %rbp, %rax
jmpq *%rax
movl $0x10, 0x4(%rsp)
movl (%rbx), %edi
movq %r14, %rsi
movq %r15, %rdx
callq 0x2380
cmpl $-0x1, %eax
je 0x435d
movl %eax, %r13d
movl %eax, %edi
pushq $0x3
popq %rsi
xorl %edx, %edx
xorl %eax, %eax
callq 0x20c0
testl %eax, %eax
js 0x42e5
orl $0x800, %eax            # imm = 0x800
movl %r13d, %edi
pushq $0x4
popq %rsi
movl %eax, %edx
xorl %eax, %eax
callq 0x20c0
testl %eax, %eax
js 0x42e5
movl %r13d, %edi
pushq $0x1
popq %rsi
movl %r12d, %edx
callq 0x2e04
testq %rax, %rax
jne 0x4091
cmpl $0x0, 0x418b(%rip)      # 0x829c
jle 0x42f1
movq 0x3eda(%rip), %rax      # 0x7ff8
movq (%rax), %rcx
leaq 0x1733(%rip), %rdi      # 0x585b
pushq $0x1f
popq %rsi
pushq $0x1
popq %rdx
callq 0x23c0
jmp 0x42f1
movl 0xf0(%rbx), %eax
testl %eax, %eax
je 0x424f
movl 0xa4(%rbx), %ecx
testl %ecx, %ecx
jle 0x427c
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 0x4091
movslq 0xc4(%rbx), %rdx
testq %rdx, %rdx
je 0x425b
movl (%rbx), %edi
movq 0xb8(%rbx), %rsi
callq 0x20d0
testl %eax, %eax
jle 0x42b6
movl %eax, %ecx
andl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
addq %rcx, 0x40d1(%rip)      # 0x8280
addq %rcx, 0xb8(%rbx)
subl %eax, 0xc4(%rbx)
jmp 0x4091
movl 0xa4(%rbx), %eax
cmpl 0xa8(%rbx), %eax
jl 0x4207
movq %rbx, %rdi
callq 0x38ed
movslq 0xa8(%rbx), %rax
addq %rax, 0x98(%rbx)
subl %eax, 0xa4(%rbx)
andl $0x0, 0xa8(%rbx)
jmp 0x4091
movq %rbx, %rdi
callq 0x3e4c
testl %eax, %eax
jne 0x4091
movq %rbx, %rdi
callq 0x3ecf
testl %eax, %eax
jne 0x4091
movq %rbx, %rdi
movl %r12d, %esi
callq 0x4005
testl %eax, %eax
jne 0x4367
cmpl $0x0, 0x406b(%rip)      # 0x829c
jle 0x42d9
movq 0x3dba(%rip), %rax      # 0x7ff8
movq (%rax), %rcx
leaq 0x1633(%rip), %rdi      # 0x587b
pushq $0x16
jmp 0x4348
movl $0x1, 0x4(%rbx)
jmp 0x4091
movl 0xc8(%rbx), %eax
movl %eax, 0x4(%rbx)
cmpl $0x1, %eax
jne 0x4091
movq %rbx, %rdi
xorl %esi, %esi
callq 0x2db0
jmp 0x4091
movl (%rbx), %edi
movq 0x90(%rbx), %rsi
movl 0xa0(%rbx), %ecx
cmpl %eax, %ecx
cmovll %ecx, %eax
movslq %eax, %rdx
callq 0x21e0
testl %eax, %eax
jle 0x42fe
movl %eax, %ecx
andl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
addq %rcx, 0x3fcd(%rip)      # 0x8278
subl %eax, 0xf0(%rbx)
jmp 0x4091
cmpl $-0x1, %eax
jne 0x42d0
callq 0x2040
cmpl $0xb, (%rax)
jne 0x42d0
movq %rbx, %rdi
pushq $0x14
popq %rsi
jmp 0x421d
cmpl $0x0, 0x3fc5(%rip)      # 0x829c
jg 0x4335
movl $0x5, 0x4(%rbx)
jmp 0x4091
leaq 0x155c(%rip), %rdi      # 0x5848
callq 0x2360
movl %r13d, %edi
callq 0x21b0
jmp 0x4091
cmpl $-0x1, %eax
je 0x4309
testl %eax, %eax
je 0x42d9
jmp 0x4317
callq 0x2040
cmpl $0xb, (%rax)
je 0x4217
cmpl $0x0, 0x3f7e(%rip)      # 0x829c
jle 0x42d9
movq 0x3cd1(%rip), %rax      # 0x7ff8
movq (%rax), %rcx
leaq 0x1561(%rip), %rdi      # 0x5892
pushq $0x28
jmp 0x4348
movq 0x3cbc(%rip), %rax      # 0x7ff8
movq (%rax), %rcx
leaq 0x1575(%rip), %rdi      # 0x58bb
pushq $0x29
popq %rsi
pushq $0x1
popq %rdx
callq 0x23c0
jmp 0x42d9
movq %rbx, %rdi
callq 0x3029
jmp 0x4367
callq 0x2040
cmpl $0xb, (%rax)
jne 0x4376
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x14c2(%rip), %rdi      # 0x583f
callq 0x2360
jmp 0x4367