// File: shaovie[P]reactor/src/io_handle.cpp
// Function: io_handle::send(char const*, int)
int io_handle::send(const char *buff, const int len) {
    if (!pthread_equal(pthread_self(), this->poll->thread_id))
        return this->async_send(buff, len);

    if (this->fd == -1)
        return -1;
    
    // sync send in poller thread
    if (this->async_send_buf_q != nullptr && !this->async_send_buf_q->empty()) {
        char *bf = new char[len];
        ::memcpy(bf, buff, len);
        this->async_send_buf_q->push_back(async_send_buf(bf, len));
        this->async_send_buf_size += len;
        return len;
    }

    int ret = 0;
    do {
        ret = ::send(this->fd, buff, len, 0);
    } while (ret == -1 && errno == EINTR);

    if (ret < len) { // error or partial
        if (ret < 0)
            ret = 0;
        auto left = len - ret;
        char *bf = new char[left];
        ::memcpy(bf, buff + ret, left);
        if (this->async_send_buf_q == nullptr)
            this->async_send_buf_q = new ringq<async_send_buf>(2);
        this->async_send_buf_q->push_back(async_send_buf(bf, left));
        this->async_send_buf_size += left;
        if (this->async_send_polling == false) {
            this->poll->append(this->fd, ev_handler::ev_write);
            this->async_send_polling = true;
        }
        ret = len;
    }
    return ret;
}

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x88(%rsp)
movq %rsi, 0x80(%rsp)
movl %edx, 0x7c(%rsp)
movq 0x88(%rsp), %rax
movq %rax, 0x28(%rsp)
callq 0x14f30
movq %rax, %rdi
movq 0x28(%rsp), %rax
movq 0x18(%rax), %rax
movq 0x40(%rax), %rsi
callq 0x15c70
cmpl $0x0, %eax
jne 0x1f2c9
movq 0x28(%rsp), %rdi
movq 0x80(%rsp), %rsi
movl 0x7c(%rsp), %edx
callq 0x15570
movl %eax, 0x94(%rsp)
jmp 0x1f518
movq 0x28(%rsp), %rax
cmpl $-0x1, 0x8(%rax)
jne 0x1f2e4
movl $0xffffffff, 0x94(%rsp) # imm = 0xFFFFFFFF
jmp 0x1f518
movq 0x28(%rsp), %rax
cmpq $0x0, 0x38(%rax)
je 0x1f38e
movq 0x28(%rsp), %rax
movq 0x38(%rax), %rdi
callq 0x141f0
testb $0x1, %al
jne 0x1f38e
movslq 0x7c(%rsp), %rdi
movq $-0x1, %rax
cmpq $0x0, %rdi
cmovlq %rax, %rdi
callq 0x14050
movq %rax, 0x70(%rsp)
movq 0x70(%rsp), %rdi
movq 0x80(%rsp), %rsi
movslq 0x7c(%rsp), %rdx
callq 0x14e70
movq 0x28(%rsp), %rax
movq 0x38(%rax), %rax
movq %rax, 0x20(%rsp)
movq 0x70(%rsp), %rsi
movl 0x7c(%rsp), %edx
leaq 0x60(%rsp), %rdi
callq 0x15430
movq 0x20(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x15400
movq 0x28(%rsp), %rax
movl 0x7c(%rsp), %ecx
addl 0x34(%rax), %ecx
movl %ecx, 0x34(%rax)
movl 0x7c(%rsp), %eax
movl %eax, 0x94(%rsp)
jmp 0x1f518
movl $0x0, 0x5c(%rsp)
movq 0x28(%rsp), %rax
movl 0x8(%rax), %edi
movq 0x80(%rsp), %rsi
movslq 0x7c(%rsp), %rdx
xorl %ecx, %ecx
callq 0x14820
movl %eax, 0x5c(%rsp)
xorl %eax, %eax
cmpl $-0x1, 0x5c(%rsp)
movb %al, 0x1f(%rsp)
jne 0x1f3d2
callq 0x140c0
cmpl $0x4, (%rax)
sete %al
movb %al, 0x1f(%rsp)
movb 0x1f(%rsp), %al
testb $0x1, %al
jne 0x1f396
movl 0x5c(%rsp), %eax
cmpl 0x7c(%rsp), %eax
jge 0x1f50d
cmpl $0x0, 0x5c(%rsp)
jge 0x1f3f7
movl $0x0, 0x5c(%rsp)
movl 0x7c(%rsp), %eax
subl 0x5c(%rsp), %eax
movl %eax, 0x58(%rsp)
movslq 0x58(%rsp), %rdi
movq $-0x1, %rax
cmpq $0x0, %rdi
cmovlq %rax, %rdi
callq 0x14050
movq %rax, 0x50(%rsp)
movq 0x50(%rsp), %rdi
movq 0x80(%rsp), %rsi
movslq 0x5c(%rsp), %rax
addq %rax, %rsi
movslq 0x58(%rsp), %rdx
callq 0x14e70
movq 0x28(%rsp), %rax
cmpq $0x0, 0x38(%rax)
jne 0x1f49a
movl $0x18, %edi
callq 0x15120
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x10(%rsp)
movl $0x2, %esi
callq 0x150c0
jmp 0x1f46d
movq 0x28(%rsp), %rax
movq 0x10(%rsp), %rcx
movq %rcx, 0x38(%rax)
jmp 0x1f49a
movq 0x10(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x48(%rsp)
movl %eax, 0x44(%rsp)
callq 0x15060
jmp 0x1f527
movq 0x28(%rsp), %rax
movq 0x38(%rax), %rax
movq %rax, 0x8(%rsp)
movq 0x50(%rsp), %rsi
movl 0x58(%rsp), %edx
leaq 0x30(%rsp), %rdi
callq 0x15430
movq 0x8(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x15400
movq 0x28(%rsp), %rax
movl 0x58(%rsp), %ecx
addl 0x34(%rax), %ecx
movl %ecx, 0x34(%rax)
movb 0x30(%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x1f505
movq 0x28(%rsp), %rax
movq 0x18(%rax), %rdi
movl 0x8(%rax), %esi
movl $0x4, %edx
callq 0x14750
movq 0x28(%rsp), %rax
movb $0x1, 0x30(%rax)
movl 0x7c(%rsp), %eax
movl %eax, 0x5c(%rsp)
movl 0x5c(%rsp), %eax
movl %eax, 0x94(%rsp)
movl 0x94(%rsp), %eax
addq $0x98, %rsp
retq
movq 0x48(%rsp), %rdi
callq 0x15ce0
nopw %cs:(%rax,%rax)