// File: davmac314[P]dinit/src/dinit-log.cc
// Function: (anonymous namespace)::buffered_log_stream::fd_event(dasynq::v2::event_loop<dasynq::null_mutex, dasynq::v2::default_traits<dasynq::null_mutex>>&, int, int)
rearm buffered_log_stream::fd_event(eventloop_t &loop, int fd, int flags) noexcept
{
    if ((! partway) && (! special) && discarded) {
        special_buf = "dinit: *** log message discarded due to full buffer ***\n";
        special = true;
        discarded = false;
        msg_index = 0;
    }

    if ((! partway) && special) {
        const char * start = special_buf + msg_index;
        const char * end = start;
        while (*end != '\n') end++;
        int r = bp_sys::write(fd, start, end - start + 1);
        if (r >= 0) {
            if (start + r > end) {
                // All written: go on to next message in queue
                special = false;
                discarded = false;
                msg_index = 0;
                
                if (release) {
                    release_console();
                    return rearm::DISARM;
                }
            }
            else {
                msg_index += r;
                return rearm::REARM;
            }
        }
        else if (errno != EAGAIN && errno != EINTR && errno != EWOULDBLOCK) {
            return rearm::REMOVE;
        }
        return rearm::REARM;
    }
    else {
        // Writing from the regular circular buffer
        
        if (current_index == 0) {
            release_console();
            return rearm::DISARM;
        }
        
        // We try to find a complete line (terminated by '\n') in the buffer, and write it
        // out. Since it may span the circular buffer end, it may consist of two distinct spans,
        // and so we use writev to write them atomically.
        
        struct iovec logiov[2];
        
        char *ptr = log_buffer.get_ptr(0);
        unsigned len = log_buffer.get_contiguous_length(ptr);
        char *creptr = ptr + len;  // contiguous region end
        char *eptr = std::find(ptr, creptr, '\n');
        
        bool will_complete = false;  // will complete this message?
        if (eptr != creptr) {
            eptr++;  // include '\n'
            will_complete = true;
        }

        len = eptr - ptr;
        
        logiov[0].iov_base = ptr;
        logiov[0].iov_len = len;
        int iovs_to_write = 1;
        
        // Do we need the second span?
        if (!will_complete && len != log_buffer.get_length()) {
            ptr = log_buffer.get_buf_base();
            creptr = ptr + log_buffer.get_length() - len;
            eptr = std::find(ptr, creptr, '\n');
            if (eptr != creptr) {
                eptr++; // include '\n'
                // It should not ever be the case that we do not now have a complete message
                will_complete = true;
            }
            logiov[1].iov_base = ptr;
            logiov[1].iov_len = eptr - ptr;
            len += logiov[1].iov_len;
            iovs_to_write = 2;
        }
        
        ssize_t r = bp_sys::writev(fd, logiov, iovs_to_write);

        if (r >= 0) {
            bool complete = (r == len) && will_complete;
            log_buffer.consume(len);
            partway = ! complete;
            if (complete) {
                current_index -= len;
                if (current_index == 0 || release) {
                    // No more messages buffered / stop logging to console:
                    release_console();
                    return rearm::DISARM;
                }
            }
        }
        else if (errno != EAGAIN && errno != EINTR && errno != EWOULDBLOCK) {
            return rearm::REMOVE;
        }
    }
    
    // We've written something by the time we get here. We could fall through to below, but
    // let's give other events a chance to be processed by returning now.
    return rearm::REARM;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movl %ecx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xa8(%rbp)
testb $0x1, 0x28(%rax)
jne 0x6bde5
movq -0xa8(%rbp), %rax
testb $0x1, 0x2b(%rax)
jne 0x6bde5
movq -0xa8(%rbp), %rax
testb $0x1, 0x29(%rax)
je 0x6bde5
movq -0xa8(%rbp), %rax
leaq 0xd8ee(%rip), %rcx      # 0x796c0
movq %rcx, 0x30(%rax)
movb $0x1, 0x2b(%rax)
movb $0x0, 0x29(%rax)
movl $0x0, 0x38(%rax)
movq -0xa8(%rbp), %rax
testb $0x1, 0x28(%rax)
jne 0x6bf0d
movq -0xa8(%rbp), %rax
testb $0x1, 0x2b(%rax)
je 0x6bf0d
movq -0xa8(%rbp), %rcx
movq 0x30(%rcx), %rax
movslq 0x38(%rcx), %rcx
addq %rcx, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movsbl (%rax), %eax
cmpl $0xa, %eax
je 0x6be3f
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x6be25
movl -0x1c(%rbp), %edi
movq -0x28(%rbp), %rsi
movq -0x30(%rbp), %rdx
subq %rsi, %rdx
incq %rdx
callq 0xa200
movq %rax, -0xb0(%rbp)
jmp 0x6be5e
movq -0xb0(%rbp), %rax
movl %eax, -0x34(%rbp)
cmpl $0x0, -0x34(%rbp)
jl 0x6bed5
movq -0x28(%rbp), %rax
movslq -0x34(%rbp), %rcx
addq %rcx, %rax
cmpq -0x30(%rbp), %rax
jbe 0x6beb7
movq -0xa8(%rbp), %rax
movb $0x0, 0x2b(%rax)
movb $0x0, 0x29(%rax)
movl $0x0, 0x38(%rax)
testb $0x1, 0x2a(%rax)
je 0x6beb5
movq -0xa8(%rbp), %rdi
callq 0x6c240
jmp 0x6bea9
movl $0x1, -0x4(%rbp)
jmp 0x6c228
jmp 0x6bed3
movq -0xa8(%rbp), %rax
movl -0x34(%rbp), %ecx
addl 0x38(%rax), %ecx
movl %ecx, 0x38(%rax)
movl $0x0, -0x4(%rbp)
jmp 0x6c228
jmp 0x6bf01
callq 0xa060
cmpl $0xb, (%rax)
je 0x6beff
callq 0xa060
cmpl $0x4, (%rax)
je 0x6beff
callq 0xa060
cmpl $0xb, (%rax)
je 0x6beff
movl $0x3, -0x4(%rbp)
jmp 0x6c228
jmp 0x6bf01
movl $0x0, -0x4(%rbp)
jmp 0x6c228
movq -0xa8(%rbp), %rax
cmpl $0x0, 0x1044(%rax)
jne 0x6bf37
movq -0xa8(%rbp), %rdi
callq 0x6c240
jmp 0x6bf2b
movl $0x1, -0x4(%rbp)
jmp 0x6c228
movq -0xa8(%rbp), %rdi
addq $0x3c, %rdi
xorl %esi, %esi
callq 0x6c800
movq %rax, -0xb8(%rbp)
jmp 0x6bf52
movq -0xa8(%rbp), %rdi
movq -0xb8(%rbp), %rax
movq %rax, -0x68(%rbp)
addq $0x3c, %rdi
movq -0x68(%rbp), %rsi
callq 0x6c840
movl %eax, -0xbc(%rbp)
jmp 0x6bf79
movl -0xbc(%rbp), %eax
movl %eax, -0x6c(%rbp)
movq -0x68(%rbp), %rax
movl -0x6c(%rbp), %ecx
addq %rcx, %rax
movq %rax, -0x78(%rbp)
movq -0x68(%rbp), %rdi
movq -0x78(%rbp), %rsi
movb $0xa, -0x81(%rbp)
leaq -0x81(%rbp), %rdx
callq 0x6c8d0
movq %rax, -0xc8(%rbp)
jmp 0x6bfb4
movq -0xc8(%rbp), %rax
movq %rax, -0x80(%rbp)
movb $0x0, -0x82(%rbp)
movq -0x80(%rbp), %rax
cmpq -0x78(%rbp), %rax
je 0x6bfe3
movq -0x80(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x80(%rbp)
movb $0x1, -0x82(%rbp)
movq -0x80(%rbp), %rax
movq -0x68(%rbp), %rcx
subq %rcx, %rax
movl %eax, -0x6c(%rbp)
movq -0x68(%rbp), %rax
movq %rax, -0x60(%rbp)
movl -0x6c(%rbp), %eax
movq %rax, -0x58(%rbp)
movl $0x1, -0x88(%rbp)
testb $0x1, -0x82(%rbp)
jne 0x6c111
movq -0xa8(%rbp), %rdi
movl -0x6c(%rbp), %eax
movl %eax, -0xcc(%rbp)
addq $0x3c, %rdi
callq 0x6c920
movl %eax, %ecx
movl -0xcc(%rbp), %eax
cmpl %ecx, %eax
je 0x6c111
movq -0xa8(%rbp), %rdi
addq $0x3c, %rdi
callq 0x6c940
movq %rax, -0xd8(%rbp)
jmp 0x6c059
movq -0xa8(%rbp), %rdi
movq -0xd8(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
movq %rax, -0xe8(%rbp)
addq $0x3c, %rdi
callq 0x6c920
movl %eax, %ecx
movq -0xe8(%rbp), %rax
movl %ecx, %ecx
addq %rcx, %rax
movl -0x6c(%rbp), %ecx
subq %rcx, %rax
movq %rax, -0x78(%rbp)
movq -0x68(%rbp), %rdi
movq -0x78(%rbp), %rsi
movb $0xa, -0x89(%rbp)
leaq -0x89(%rbp), %rdx
callq 0x6c8d0
movq %rax, -0xe0(%rbp)
jmp 0x6c0bb
movq -0xe0(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
cmpq -0x78(%rbp), %rax
je 0x6c0e3
movq -0x80(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x80(%rbp)
movb $0x1, -0x82(%rbp)
movq -0x68(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x80(%rbp), %rax
movq -0x68(%rbp), %rcx
subq %rcx, %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rcx
movl -0x6c(%rbp), %eax
addq %rcx, %rax
movl %eax, -0x6c(%rbp)
movl $0x2, -0x88(%rbp)
movl -0x1c(%rbp), %edi
movl -0x88(%rbp), %edx
leaq -0x60(%rbp), %rsi
callq 0xa390
movq %rax, -0xf0(%rbp)
jmp 0x6c12c
movq -0xf0(%rbp), %rax
movq %rax, -0x98(%rbp)
cmpq $0x0, -0x98(%rbp)
jl 0x6c1f6
movq -0x98(%rbp), %rcx
movl -0x6c(%rbp), %eax
movl %eax, %edx
xorl %eax, %eax
cmpq %rdx, %rcx
movb %al, -0xf1(%rbp)
jne 0x6c16d
movb -0x82(%rbp), %al
movb %al, -0xf1(%rbp)
movq -0xa8(%rbp), %rdi
movb -0xf1(%rbp), %al
andb $0x1, %al
movb %al, -0x99(%rbp)
addq $0x3c, %rdi
movl -0x6c(%rbp), %esi
callq 0x6c950
movq -0xa8(%rbp), %rax
movb -0x99(%rbp), %cl
xorb $-0x1, %cl
andb $0x1, %cl
movb %cl, 0x28(%rax)
testb $0x1, -0x99(%rbp)
je 0x6c1f4
movq -0xa8(%rbp), %rax
movl -0x6c(%rbp), %edx
movl 0x1044(%rax), %ecx
subl %edx, %ecx
movl %ecx, 0x1044(%rax)
cmpl $0x0, 0x1044(%rax)
je 0x6c1db
movq -0xa8(%rbp), %rax
testb $0x1, 0x2a(%rax)
je 0x6c1f2
movq -0xa8(%rbp), %rdi
callq 0x6c240
jmp 0x6c1e9
movl $0x1, -0x4(%rbp)
jmp 0x6c228
jmp 0x6c1f4
jmp 0x6c21f
callq 0xa060
cmpl $0xb, (%rax)
je 0x6c21d
callq 0xa060
cmpl $0x4, (%rax)
je 0x6c21d
callq 0xa060
cmpl $0xb, (%rax)
je 0x6c21d
movl $0x3, -0x4(%rbp)
jmp 0x6c228
jmp 0x6c21f
jmp 0x6c221
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
movq %rax, %rdi
callq 0xfa30
nopl (%rax)