// File: /workspace/github_c_makefile_star2_O0/sharpyfox[P]citrusleaf-client/src/cf_socket.c
// Function: cf_socket_write_timeout
int
cf_socket_write_timeout(int fd, uint8_t *buf, size_t buf_len, uint64_t trans_deadline, int attempt_ms)
{
	if (!buf_len) {
		return 0;
	}

	char *ctx = "cf_socket_write_timeout()";
	int errbuf_len = 64;
	char errbuf[errbuf_len];

	int flags;
	if (-1 == (flags = fcntl(fd, F_GETFL, 0))) {
		flags = 0;
	}
	if (!(flags & O_NONBLOCK)) {
		if (-1 == fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
			return(ENOENT);
		}
	}

	// between the transaction deadline and the attempt_ms, find the lesser
	// and create a deadline for this attempt
	uint64_t deadline = attempt_ms + cf_getms();
	if ((trans_deadline != 0) && (trans_deadline < deadline)) {
		deadline = trans_deadline;
	}

	int rv = 0, epoll_fd = -1, busy = 0, try = 0;
	size_t pos = 0;
	uint64_t start = cf_getms();

	if (0 > (epoll_fd = epoll_create(1))) {
		rv = errno;
		cf_warn("%s: epoll_create() failed (errno %d: \"%s\") ~~ Failing!", ctx, errno, my_strerror_r(errno, errbuf, errbuf_len));
		goto Fail;
	}

	struct epoll_event event;
	memset(&event, 0, sizeof(struct epoll_event));
	event.data.fd = fd;
	event.events = EPOLLOUT;

	if (0 > epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &event)) {
		rv = errno;
		cf_warn("%s: epoll_ctl(ADD) of socket failed (errno %d: \"%s\") ~~ Failing!", ctx, errno, my_strerror_r(errno, errbuf, errbuf_len));
		goto Fail;
	}

	do {
		uint64_t now = cf_getms();
		if (now > deadline) {
#ifdef DEBUG_TIME
			debug_time_printf("socket write timeout 1", try, busy, start, now, deadline);
#endif
			rv = ETIMEDOUT;
			goto Fail;
		}

		uint64_t ms_left = deadline - now;

		int nevents = 0;
		int max_events = 1;
		int wait_ms = 1;
		struct epoll_event events[max_events];

		if (0 > (nevents = epoll_wait(epoll_fd, events, max_events, wait_ms))) {
			if ((rv = errno) == EINTR) {
				cf_debug("%s: epoll_wait() on socket encountered EINTR ~~ Retrying!", ctx);
				busy++;
				goto Retry;
			} else {
				cf_warn("%s: epoll_wait() on socket failed (errno %d: \"%s\") ~~ Failing!", ctx, errno, my_strerror_r(errno, errbuf, errbuf_len));
			}
			goto Fail;
		} else {
			if (nevents == 0) {
				cf_debug("%s: epoll_wait() returned no events ~~ Retrying!", ctx);
				busy++;
				goto Retry;
			}
			if (nevents != 1) {
				cf_warn("%s: epoll_wait() returned %d events ~~ only 1 expected, so ignoring others!", ctx, nevents);
			}
			if (events[0].data.fd == fd) {
				if (events[0].events & EPOLLOUT) {
					cf_debug("%s: epoll_wait() on socket ready for write detected ~~ Succeeding!", ctx);
				} else {
					// (Note:  ERR and HUP events are automatically waited for as well.)
					if (events[0].events & (EPOLLERR | EPOLLHUP)) {
						cf_debug("%s: epoll_wait() on socket detected failure event 0x%x ~~ Failing!", ctx, events[0].events);
					} else {
						cf_warn("%s: epoll_wait() on socket detected non-write events 0x%x ~~ Failing!", ctx, events[0].events);
					}
					rv = EBADF;
					goto Fail;
				}
			} else {
				cf_warn("%s: epoll_wait() on socket returned event on unknown socket %d ~~ Retrying!", ctx, events[0].data.fd);
				goto Retry;
			}

			int r_bytes = write(fd, buf + pos, buf_len - pos);

			if (r_bytes > 0) {
				pos += r_bytes;
				if (pos >= buf_len)	{
					goto Success;
				}
			} else if (r_bytes == 0) {
				// It's likely the socket has been closed on the remote side.
				rv = EBADF;
				goto Fail;
			} else if ((errno != ETIMEDOUT) && (errno != EWOULDBLOCK) && (errno != EINPROGRESS) && (errno != EAGAIN)) {
#ifdef DEBUG_TIME
				debug_time_printf("socket write timeout 2", try, busy, start, now, deadline);
#endif
				rv = errno;
				goto Fail;
			}
		}

Retry:
		try++;

	} while (pos < buf_len);

Success:
	if (0 > epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, &event)) {
		cf_warn("%s: epoll_ctl(DEL) on socket failed (errno %d: \"%s\")", ctx, errno, my_strerror_r(errno, errbuf, errbuf_len));
	}
	close(epoll_fd);

	rv = 0;
	goto Done;

Fail:
	cf_debug("%s: socket write timeout fail: %d (%s)", ctx, errno, my_strerror_r(errno, errbuf, errbuf_len));

	if (epoll_fd > 0) {
		if (0 > epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, &event)) {
			cf_warn("%s: epoll_ctl(DEL) on socket failed (errno %d: \"%s\")", ctx, errno, my_strerror_r(errno, errbuf, errbuf_len));
		}
		close(epoll_fd);
	}

Done:
	return(rv);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x170, %rsp            # imm = 0x170
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movl %r8d, -0x24(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0x15cc1
movl $0x0, -0x4(%rbp)
jmp 0x1657a
leaq 0x3ed7(%rip), %rax      # 0x19b9f
movq %rax, -0x30(%rbp)
movl $0x40, -0x34(%rbp)
movl -0x34(%rbp), %eax
movq %rsp, %rcx
movq %rcx, -0x40(%rbp)
movq %rax, %rdx
addq $0xf, %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0xc8(%rbp)
movq %rcx, %rsp
movq %rax, -0x48(%rbp)
movl -0x8(%rbp), %edi
movl $0x3, %esi
xorl %edx, %edx
movb $0x0, %al
callq 0x2470
movl %eax, %ecx
movl %ecx, -0x4c(%rbp)
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpl %ecx, %eax
jne 0x15d22
movl $0x0, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
andl $0x800, %eax            # imm = 0x800
cmpl $0x0, %eax
jne 0x15d67
movl -0x8(%rbp), %edi
movl -0x4c(%rbp), %edx
orl $0x800, %edx            # imm = 0x800
movl $0x4, %esi
movb $0x0, %al
callq 0x2470
movl %eax, %ecx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpl %ecx, %eax
jne 0x15d65
movl $0x2, -0x4(%rbp)
movl $0x1, -0x50(%rbp)
jmp 0x16573
jmp 0x15d67
movslq -0x24(%rbp), %rax
movq %rax, -0xd0(%rbp)
callq 0x169a0
movq %rax, %rcx
movq -0xd0(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x15da1
movq -0x20(%rbp), %rax
cmpq -0x58(%rbp), %rax
jae 0x15da1
movq -0x20(%rbp), %rax
movq %rax, -0x58(%rbp)
movl $0x0, -0x5c(%rbp)
movl $0xffffffff, -0x60(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0x64(%rbp)
movl $0x0, -0x68(%rbp)
movq $0x0, -0x70(%rbp)
callq 0x169a0
movq %rax, -0x78(%rbp)
movl $0x1, %edi
callq 0x2550
movl %eax, %ecx
movl %ecx, -0x60(%rbp)
xorl %eax, %eax
cmpl %ecx, %eax
jle 0x15e70
callq 0x2040
movl (%rax), %eax
movl %eax, -0x5c(%rbp)
leaq 0x84e0(%rip), %rax      # 0x1e2d8
movl (%rax), %ecx
movl $0x1, %eax
cmpl %ecx, %eax
jg 0x15e6b
leaq 0x84d6(%rip), %rax      # 0x1e2e0
movq (%rax), %rax
movq %rax, -0xd8(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0xe8(%rbp)
callq 0x2040
movl (%rax), %eax
movl %eax, -0xdc(%rbp)
callq 0x2040
movq -0xc8(%rbp), %rsi
movl (%rax), %edi
movslq -0x34(%rbp), %rdx
callq 0x15c50
movq -0xe8(%rbp), %rdx
movl -0xdc(%rbp), %ecx
movq -0xd8(%rbp), %r9
movq %rax, %r8
movl $0x1, %edi
leaq 0x3a5a(%rip), %rsi      # 0x198c0
movb $0x0, %al
callq *%r9
jmp 0x1643d
leaq -0x84(%rbp), %rdi
xorl %esi, %esi
movl $0xc, %edx
callq 0x2170
movl -0x8(%rbp), %eax
movl %eax, -0x80(%rbp)
movl $0x4, -0x84(%rbp)
movl -0x60(%rbp), %edi
movl -0x8(%rbp), %edx
movl $0x1, %esi
leaq -0x84(%rbp), %rcx
callq 0x2350
movl %eax, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jle 0x15f3f
callq 0x2040
movl (%rax), %eax
movl %eax, -0x5c(%rbp)
leaq 0x8411(%rip), %rax      # 0x1e2d8
movl (%rax), %ecx
movl $0x1, %eax
cmpl %ecx, %eax
jg 0x15f3a
leaq 0x8407(%rip), %rax      # 0x1e2e0
movq (%rax), %rax
movq %rax, -0xf0(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x100(%rbp)
callq 0x2040
movl (%rax), %eax
movl %eax, -0xf4(%rbp)
callq 0x2040
movq -0xc8(%rbp), %rsi
movl (%rax), %edi
movslq -0x34(%rbp), %rdx
callq 0x15c50
movq -0x100(%rbp), %rdx
movl -0xf4(%rbp), %ecx
movq -0xf0(%rbp), %r9
movq %rax, %r8
movl $0x1, %edi
leaq 0x39c2(%rip), %rsi      # 0x198f7
movb $0x0, %al
callq *%r9
jmp 0x1643d
jmp 0x15f41
callq 0x169a0
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rax
cmpq -0x58(%rbp), %rax
jbe 0x15f66
movl $0x6e, -0x5c(%rbp)
jmp 0x1643d
movq -0x58(%rbp), %rax
movq -0x90(%rbp), %rcx
subq %rcx, %rax
movq %rax, -0x98(%rbp)
movl $0x0, -0x9c(%rbp)
movl $0x1, -0xa0(%rbp)
movl $0x1, -0xa4(%rbp)
movl -0xa0(%rbp), %eax
movq %rsp, %rcx
movq %rcx, -0xb0(%rbp)
leaq (%rax,%rax,2), %rcx
leaq 0xf(,%rcx,4), %rcx
andq $-0x10, %rcx
movq %rsp, %rsi
subq %rcx, %rsi
movq %rsi, -0x108(%rbp)
movq %rsi, %rsp
movq %rax, -0xb8(%rbp)
movl -0x60(%rbp), %edi
movl -0xa0(%rbp), %edx
movl -0xa4(%rbp), %ecx
callq 0x2140
movl %eax, %ecx
movl %ecx, -0x9c(%rbp)
xorl %eax, %eax
cmpl %ecx, %eax
jle 0x160cb
callq 0x2040
movl (%rax), %eax
movl %eax, -0x5c(%rbp)
cmpl $0x4, %eax
jne 0x16043
leaq 0x82cc(%rip), %rax      # 0x1e2d8
movl (%rax), %ecx
movl $0x3, %eax
cmpl %ecx, %eax
jg 0x16035
leaq 0x82c2(%rip), %rax      # 0x1e2e0
movq (%rax), %rcx
movq -0x30(%rbp), %rdx
movl $0x3, %edi
leaq 0x3907(%rip), %rsi      # 0x19938
movb $0x0, %al
callq *%rcx
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x16332
leaq 0x828e(%rip), %rax      # 0x1e2d8
movl (%rax), %ecx
movl $0x1, %eax
cmpl %ecx, %eax
jg 0x160bd
leaq 0x8284(%rip), %rax      # 0x1e2e0
movq (%rax), %rax
movq %rax, -0x110(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x120(%rbp)
callq 0x2040
movl (%rax), %eax
movl %eax, -0x114(%rbp)
callq 0x2040
movq -0xc8(%rbp), %rsi
movl (%rax), %edi
movslq -0x34(%rbp), %rdx
callq 0x15c50
movq -0x120(%rbp), %rdx
movl -0x114(%rbp), %ecx
movq -0x110(%rbp), %r9
movq %rax, %r8
movl $0x1, %edi
leaq 0x38ba(%rip), %rsi      # 0x19972
movb $0x0, %al
callq *%r9
jmp 0x160bf
movl $0x2, -0x50(%rbp)
jmp 0x16342
cmpl $0x0, -0x9c(%rbp)
jne 0x16112
leaq 0x81fd(%rip), %rax      # 0x1e2d8
movl (%rax), %ecx
movl $0x3, %eax
cmpl %ecx, %eax
jg 0x16104
leaq 0x81f3(%rip), %rax      # 0x1e2e0
movq (%rax), %rcx
movq -0x30(%rbp), %rdx
movl $0x3, %edi
leaq 0x38b1(%rip), %rsi      # 0x199b1
movb $0x0, %al
callq *%rcx
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x16332
cmpl $0x1, -0x9c(%rbp)
je 0x16154
leaq 0x81b6(%rip), %rax      # 0x1e2d8
movl (%rax), %ecx
movl $0x1, %eax
cmpl %ecx, %eax
jg 0x16152
leaq 0x81ac(%rip), %rax      # 0x1e2e0
movq (%rax), %r8
movq -0x30(%rbp), %rdx
movl -0x9c(%rbp), %ecx
movl $0x1, %edi
leaq 0x3895(%rip), %rsi      # 0x199e2
movb $0x0, %al
callq *%r8
jmp 0x16154
movq -0x108(%rbp), %rax
movl 0x4(%rax), %eax
cmpl -0x8(%rbp), %eax
jne 0x1624b
movq -0x108(%rbp), %rax
movl (%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x161ad
leaq 0x8159(%rip), %rax      # 0x1e2d8
movl (%rax), %ecx
movl $0x3, %eax
cmpl %ecx, %eax
jg 0x161a8
leaq 0x814f(%rip), %rax      # 0x1e2e0
movq (%rax), %rcx
movq -0x30(%rbp), %rdx
movl $0x3, %edi
leaq 0x3a15(%rip), %rsi      # 0x19bb9
movb $0x0, %al
callq *%rcx
jmp 0x16249
movq -0x108(%rbp), %rax
movl (%rax), %eax
andl $0x18, %eax
cmpl $0x0, %eax
je 0x161fa
leaq 0x8113(%rip), %rax      # 0x1e2d8
movl (%rax), %ecx
movl $0x3, %eax
cmpl %ecx, %eax
jg 0x161f8
movq -0x108(%rbp), %rax
leaq 0x8102(%rip), %rcx      # 0x1e2e0
movq (%rcx), %r8
movq -0x30(%rbp), %rdx
movl (%rax), %ecx
movl $0x3, %edi
leaq 0x387d(%rip), %rsi      # 0x19a70
movb $0x0, %al
callq *%r8
jmp 0x16236
leaq 0x80d7(%rip), %rax      # 0x1e2d8
movl (%rax), %ecx
movl $0x1, %eax
cmpl %ecx, %eax
jg 0x16234
movq -0x108(%rbp), %rax
leaq 0x80c6(%rip), %rcx      # 0x1e2e0
movq (%rcx), %r8
movq -0x30(%rbp), %rdx
movl (%rax), %ecx
movl $0x1, %edi
leaq 0x39cd(%rip), %rsi      # 0x19bfc
movb $0x0, %al
callq *%r8
jmp 0x16236
movl $0x9, -0x5c(%rbp)
movl $0x2, -0x50(%rbp)
jmp 0x16342
jmp 0x1628b
leaq 0x8086(%rip), %rax      # 0x1e2d8
movl (%rax), %ecx
movl $0x1, %eax
cmpl %ecx, %eax
jg 0x16286
movq -0x108(%rbp), %rax
leaq 0x8075(%rip), %rcx      # 0x1e2e0
movq (%rcx), %r8
movq -0x30(%rbp), %rdx
movl 0x4(%rax), %ecx
movl $0x1, %edi
leaq 0x3877(%rip), %rsi      # 0x19af8
movb $0x0, %al
callq *%r8
jmp 0x16332
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
addq -0x70(%rbp), %rsi
movq -0x18(%rbp), %rdx
subq -0x70(%rbp), %rdx
callq 0x20e0
movl %eax, -0xbc(%rbp)
cmpl $0x0, -0xbc(%rbp)
jle 0x162d6
movslq -0xbc(%rbp), %rax
addq -0x70(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
cmpq -0x18(%rbp), %rax
jb 0x162d4
movl $0x6, -0x50(%rbp)
jmp 0x16342
jmp 0x1632e
cmpl $0x0, -0xbc(%rbp)
jne 0x162ef
movl $0x9, -0x5c(%rbp)
movl $0x2, -0x50(%rbp)
jmp 0x16342
callq 0x2040
cmpl $0x6e, (%rax)
je 0x1632a
callq 0x2040
cmpl $0xb, (%rax)
je 0x1632a
callq 0x2040
cmpl $0x73, (%rax)
je 0x1632a
callq 0x2040
cmpl $0xb, (%rax)
je 0x1632a
callq 0x2040
movl (%rax), %eax
movl %eax, -0x5c(%rbp)
movl $0x2, -0x50(%rbp)
jmp 0x16342
jmp 0x1632c
jmp 0x1632e
jmp 0x16330
jmp 0x16332
movl -0x68(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x68(%rbp)
movl $0x0, -0x50(%rbp)
movq -0xb0(%rbp), %rax
movq %rax, %rsp
movl -0x50(%rbp), %eax
movl %eax, -0x124(%rbp)
testl %eax, %eax
je 0x1637c
jmp 0x1635b
movl -0x124(%rbp), %eax
subl $0x2, %eax
je 0x1643d
jmp 0x1636c
movl -0x124(%rbp), %eax
subl $0x6, %eax
je 0x1638e
jmp 0x16573
jmp 0x1637e
movq -0x70(%rbp), %rax
cmpq -0x18(%rbp), %rax
jb 0x15f41
jmp 0x1638e
movl -0x60(%rbp), %edi
movl -0x8(%rbp), %edx
movl $0x2, %esi
leaq -0x84(%rbp), %rcx
callq 0x2350
movl %eax, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jle 0x16429
leaq 0x7f24(%rip), %rax      # 0x1e2d8
movl (%rax), %ecx
movl $0x1, %eax
cmpl %ecx, %eax
jg 0x16427
leaq 0x7f1a(%rip), %rax      # 0x1e2e0
movq (%rax), %rax
movq %rax, -0x130(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x140(%rbp)
callq 0x2040
movl (%rax), %eax
movl %eax, -0x134(%rbp)
callq 0x2040
movq -0xc8(%rbp), %rsi
movl (%rax), %edi
movslq -0x34(%rbp), %rdx
callq 0x15c50
movq -0x140(%rbp), %rdx
movl -0x134(%rbp), %ecx
movq -0x130(%rbp), %r9
movq %rax, %r8
movl $0x1, %edi
leaq 0x3722(%rip), %rsi      # 0x19b44
movb $0x0, %al
callq *%r9
jmp 0x16429
movl -0x60(%rbp), %edi
callq 0x2570
movl $0x0, -0x5c(%rbp)
jmp 0x16566
leaq 0x7e94(%rip), %rax      # 0x1e2d8
movl (%rax), %ecx
movl $0x3, %eax
cmpl %ecx, %eax
jg 0x164b7
leaq 0x7e8a(%rip), %rax      # 0x1e2e0
movq (%rax), %rax
movq %rax, -0x148(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x158(%rbp)
callq 0x2040
movl (%rax), %eax
movl %eax, -0x14c(%rbp)
callq 0x2040
movq -0xc8(%rbp), %rsi
movl (%rax), %edi
movslq -0x34(%rbp), %rdx
callq 0x15c50
movq -0x158(%rbp), %rdx
movl -0x14c(%rbp), %ecx
movq -0x148(%rbp), %r9
movq %rax, %r8
movl $0x3, %edi
leaq 0x3790(%rip), %rsi      # 0x19c42
movb $0x0, %al
callq *%r9
cmpl $0x0, -0x60(%rbp)
jle 0x16564
movl -0x60(%rbp), %edi
movl -0x8(%rbp), %edx
movl $0x2, %esi
leaq -0x84(%rbp), %rcx
callq 0x2350
movl %eax, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jle 0x1655c
leaq 0x7df1(%rip), %rax      # 0x1e2d8
movl (%rax), %ecx
movl $0x1, %eax
cmpl %ecx, %eax
jg 0x1655a
leaq 0x7de7(%rip), %rax      # 0x1e2e0
movq (%rax), %rax
movq %rax, -0x160(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x170(%rbp)
callq 0x2040
movl (%rax), %eax
movl %eax, -0x164(%rbp)
callq 0x2040
movq -0xc8(%rbp), %rsi
movl (%rax), %edi
movslq -0x34(%rbp), %rdx
callq 0x15c50
movq -0x170(%rbp), %rdx
movl -0x164(%rbp), %ecx
movq -0x160(%rbp), %r9
movq %rax, %r8
movl $0x1, %edi
leaq 0x35ef(%rip), %rsi      # 0x19b44
movb $0x0, %al
callq *%r9
jmp 0x1655c
movl -0x60(%rbp), %edi
callq 0x2570
jmp 0x16566
movl -0x5c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x50(%rbp)
movq -0x40(%rbp), %rax
movq %rax, %rsp
movl -0x4(%rbp), %eax
movq %rbp, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
nopl (%rax)