On 18/12/20 14:01, Marc-André Lureau wrote:
>> in aio_set_fd_handler. I think we can remove the call to
>> qemu_fd_register from qemu_try_set_nonblock, and that should fix the
>> issue as well.
>
> That's tricky to say whether this won't introduce regression. For most
> fds from qemu, if they use aio_set_fd_handler, that should be ok.
>
> But what about other fds? For examples, the ones from slirp?
slirp already calls qemu_fd_register, see net_slirp_register_poll_fd
> In fact, I
> don't understand how it could work today. We are passing socket() fd
> directly to g_poll(). But according to the documentation:
>
> * On Win32, the fd in a GPollFD should be Win32 HANDLE (*not* a file
> * descriptor as provided by the C runtime) that can be used by
> * MsgWaitForMultipleObjects. This does *not* include file handles
> * from CreateFile, SOCKETs, nor pipe handles. (But you can use
> * WSAEventSelect to signal events when a SOCKET is readable).
>
> And MsgWaitForMultipleObjects doesn't mention SOCKET as being valid
> handles to wait for.
No, it's more complicated. On Win32, gpollfds is only used for sockets
(despite the name!), while poll_fds is used for prepare/query/g_poll/check.
What we do is basically the same that QIOChannel and aio-win32.c already
do, just with more indirection to fit the SLIRP callback API:
- main_loop_wait calls net_slirp_poll_notify, which asks SLIRP to send
back the list of file descriptors through the net_slirp_add_poll callback.
- the file descriptors are stored in the gpollfds global.
- os_host_main_loop_wait does a select on the sockets with 0 timeout
- if no socket is ready, g_poll is done with the original timeout
(otherwise the timeout is zeroed)
- the sockets were registered with WSAEventSelect in
net_slirp_register_poll_fd, so they interrupt the subsequent g_poll if
data comes in.
Ah thanks, I mixed the unix and the win32 versions.
I don't see any other use of MainLoopPoll, so all non-SLIRP sockets
should be going through {qemu,aio}_set_fd_handler. In particular this
is the case for all of chardev/ (which uses QIOChannel), io/ and net/.
These are all the other users of qemu_set_nonblock and
qemu_try_set_nonblock.
Ok, I guess we can simply register fd to be a win32-specific call for slirp then.
Paolo
> But when I run qemu with slirp, with or without qemu_fd_register, I
> don't see any error or regression.
>
> Am I missing something?