// File: Alcaro[P]bridges/arlib/runloop-poll.cpp
// Function: (anonymous namespace)::runloop2_poll::step(bool)
bool step(bool wait)
	{
	again:
		bool ret = false;
		
		timestamp timeout = timestamp::at_never();
		for (auto& node : timeouts.waiting)
		{
			if (node.prod.has_waiter() && node.timeout <= timeout)
				timeout = node.timeout;
		}
		
		timestamp now = timestamp::now();
		duration dur = timeout - now;
#ifdef ARLIB_GUI_GTK3
		GMainContext* gmain_ctx;
		size_t gmain_n_pollfd;
		gint gmain_priority;
		if (has_gui_events)
		{
			gmain_ctx = g_main_context_default(); // g_main_context_query needs this (_prepare doesn't, unclear if glib bug)
			g_main_context_acquire(gmain_ctx);
			g_main_context_prepare(gmain_ctx, &gmain_priority);
			
		query_again:
			int timeout_ms;
			// GPollFD docs say must be same as pollfd, but the structs are
			//  struct pollfd { int fd; short int events; short int revents; };
			//  struct _GPollFD { gint fd; gushort events; gushort revents; };
			// which are not compatible, the latter two fields change signedness
			// it works in practice, but this assert is unusable
			//static_assert(std::is_layout_compatible_v<struct pollfd, GPollFD>);
			gmain_n_pollfd = g_main_context_query(gmain_ctx, gmain_priority, &timeout_ms, (GPollFD*)fds.extra_pollfd(), fds.n_extra_pollfd());
			if (gmain_n_pollfd > fds.n_extra_pollfd())
			{
				fds.reserve_space(gmain_n_pollfd);
				goto query_again;
			}
			
			if (timeout_ms >= 0)
				dur = min(dur, duration::ms(timeout_ms));
		}
#endif
		if (dur.sec < 0 || !scheduled.empty() || !wait)
			dur = { 0, 0 };
		
		test_rethrow();
		ppoll(fds.wait_fd.ptr(), fds.wait_fd.size(), (struct timespec*)&dur, nullptr);
		
#ifdef ARLIB_GUI_GTK3
		if (has_gui_events)
		{
			ret |= g_main_context_check(gmain_ctx, gmain_priority, (GPollFD*)fds.extra_pollfd(), gmain_n_pollfd);
			g_main_context_dispatch(gmain_ctx);
			g_main_context_release(gmain_ctx);
		}
#endif
		
		now = timestamp::now();
		
		// the loop must be index-based, activating a coroutine can add more waiters which can reallocate
		// (and the fd object contains two different arrays to loop over)
		for (size_t n=0;n<fds.n_wait_fds();n++)
		{
			if (fds.wait_fd[n].revents != 0)
			{
				fds.activate(n);
				ret = true;
			}
		}
		for (auto& node : timeouts.waiting)
		{
			if (node.prod.has_waiter() && node.timeout <= now)
			{
				timeouts.activate(&node);
				ret = true;
			}
		}
		while (!scheduled.empty())
		{
			scheduled.pop().resume();
			ret = true;
		}
		test_rethrow();
		
		if (ret && has_gui_events)
		{
			// if there are many events of different priorities ready to run, g_main_context_prepare only considers those of highest priority
			// loop a few more times until glib is done with everything
			wait = false;
			goto again;
		}
		
		return ret;
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movb %sil, %al
movq %rdi, -0x8(%rbp)
andb $0x1, %al
movb %al, -0x9(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xd8(%rbp)
movb $0x0, -0xa(%rbp)
callq 0x32400
movq %rax, %rcx
movq -0xd8(%rbp), %rax
movq %rcx, -0x20(%rbp)
movq %rdx, -0x18(%rbp)
addq $0x28, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0x311a0
movq %rax, -0x30(%rbp)
movq -0x28(%rbp), %rdi
callq 0x311c0
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x38(%rbp), %rax
je 0x30284
movq -0x30(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
callq 0x311e0
testb $0x1, %al
jne 0x30230
jmp 0x30274
movq -0x40(%rbp), %rdi
addq $0x10, %rdi
leaq -0x20(%rbp), %rsi
callq 0x32450
movb %al, -0x41(%rbp)
leaq -0x42(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x32580
movzbl -0x41(%rbp), %edi
callq 0x32430
testb $0x1, %al
jne 0x30260
jmp 0x30274
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rcx
movq %rcx, -0x20(%rbp)
movq 0x18(%rax), %rax
movq %rax, -0x18(%rbp)
jmp 0x30276
movq -0x30(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x30(%rbp)
jmp 0x3020f
callq 0x32590
movq %rax, -0x58(%rbp)
movq %rdx, -0x50(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x78(%rbp), %rsi
movq -0x70(%rbp), %rdx
leaq -0x20(%rbp), %rdi
callq 0x325c0
movq %rax, -0x68(%rbp)
movq %rdx, -0x60(%rbp)
cmpq $0x0, -0x68(%rbp)
jl 0x302dd
movq -0xd8(%rbp), %rdi
addq $0x40, %rdi
callq 0x32620
testb $0x1, %al
jne 0x302d7
jmp 0x302dd
testb $0x1, -0x9(%rbp)
jne 0x30303
movq $0x0, -0x88(%rbp)
movq $0x0, -0x80(%rbp)
movq -0x88(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x80(%rbp), %rax
movq %rax, -0x60(%rbp)
jmp 0x30305
jmp 0x30307
movq -0xd8(%rbp), %rdi
addq $0x10, %rdi
callq 0x32640
movq -0xd8(%rbp), %rdi
movq %rax, -0xe0(%rbp)
addq $0x10, %rdi
callq 0x32660
movq -0xe0(%rbp), %rdi
movq %rax, %rsi
leaq -0x68(%rbp), %rdx
xorl %eax, %eax
movl %eax, %ecx
callq 0x4030
callq 0x32590
movq %rax, -0x98(%rbp)
movq %rdx, -0x90(%rbp)
movq -0x98(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x90(%rbp), %rax
movq %rax, -0x50(%rbp)
movq $0x0, -0xa0(%rbp)
movq -0xd8(%rbp), %rdi
movq -0xa0(%rbp), %rax
movq %rax, -0xe8(%rbp)
callq 0x31200
movq %rax, %rcx
movq -0xe8(%rbp), %rax
cmpq %rcx, %rax
jae 0x303ef
movq -0xd8(%rbp), %rdi
addq $0x10, %rdi
movq -0xa0(%rbp), %rsi
callq 0x31e70
movswl 0x6(%rax), %eax
cmpl $0x0, %eax
je 0x303d9
movq -0xd8(%rbp), %rdi
movq -0xa0(%rbp), %rsi
callq 0x31220
movb $0x1, -0xa(%rbp)
jmp 0x303db
movq -0xa0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xa0(%rbp)
jmp 0x30379
movq -0xd8(%rbp), %rax
addq $0x28, %rax
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rdi
callq 0x311a0
movq %rax, -0xb0(%rbp)
movq -0xa8(%rbp), %rdi
callq 0x311c0
movq %rax, -0xb8(%rbp)
movq -0xb0(%rbp), %rax
cmpq -0xb8(%rbp), %rax
je 0x304cb
movq -0xb0(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0xc0(%rbp), %rdi
callq 0x311e0
testb $0x1, %al
jne 0x3045b
jmp 0x304b2
movq -0xc0(%rbp), %rdi
addq $0x10, %rdi
leaq -0x58(%rbp), %rsi
callq 0x32450
movb %al, -0xc1(%rbp)
leaq -0xc2(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x32580
movzbl -0xc1(%rbp), %edi
callq 0x32430
testb $0x1, %al
jne 0x30497
jmp 0x304b2
movq -0xd8(%rbp), %rdi
addq $0x28, %rdi
movq -0xc0(%rbp), %rsi
callq 0x31280
movb $0x1, -0xa(%rbp)
jmp 0x304b4
movq -0xb0(%rbp), %rax
addq $0x20, %rax
movq %rax, -0xb0(%rbp)
jmp 0x30427
jmp 0x304cd
movq -0xd8(%rbp), %rdi
addq $0x40, %rdi
callq 0x32620
xorb $-0x1, %al
testb $0x1, %al
jne 0x304e5
jmp 0x3050e
movq -0xd8(%rbp), %rdi
addq $0x40, %rdi
callq 0x32680
movq %rax, -0xd0(%rbp)
leaq -0xd0(%rbp), %rdi
callq 0x326b0
movb $0x1, -0xa(%rbp)
jmp 0x304cd
jmp 0x30510
jmp 0x30512
testb $0x1, -0xa(%rbp)
je 0x30529
xorl %eax, %eax
testb $0x1, %al
jne 0x30520
jmp 0x30529
movb $0x0, -0x9(%rbp)
jmp 0x301d2
movb -0xa(%rbp), %al
andb $0x1, %al
addq $0xf0, %rsp
popq %rbp
retq
nopw (%rax,%rax)