From: Paolo Bonzini <pbonzini@redhat.com>
To: "Daniel P. Berrange" <berrange@redhat.com>, qemu-devel@nongnu.org
Cc: Stefan Weil <sw@weilnetz.de>,
Andrew Baumann <Andrew.Baumann@microsoft.com>
Subject: Re: [Qemu-devel] [PATCH v1 12/21] io: implement socket watch for win32 using WSAEventSelect+select
Date: Wed, 9 Mar 2016 18:47:29 +0100 [thread overview]
Message-ID: <56E061B1.9040706@redhat.com> (raw)
In-Reply-To: <1457544504-8548-13-git-send-email-berrange@redhat.com>
On 09/03/2016 18:28, Daniel P. Berrange wrote:
> From: Paolo Bonzini <pbonzini@redhat.com>
Reviewing my own patch looks weird. :)
> On Win32 we cannot directly poll on socket handles. Instead we
> create a Win32 event object and associate the socket handle with
> the event. When the event signals readyness we then have to
> use select to determine which events are ready. Creating Win32
> events is moderately heavyweight, so we don't want todo it
> every time we create a GSource, so this associates a single
> event with a QIOChannel.
>
> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
> ---
> include/io/channel.h | 3 ++
> io/channel-socket.c | 9 ++++
> io/channel-watch.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++-
> io/channel.c | 14 ++++++
> 4 files changed, 161 insertions(+), 1 deletion(-)
>
> diff --git a/include/io/channel.h b/include/io/channel.h
> index 0a1f1ce..20b973a 100644
> --- a/include/io/channel.h
> +++ b/include/io/channel.h
> @@ -78,6 +78,9 @@ typedef gboolean (*QIOChannelFunc)(QIOChannel *ioc,
> struct QIOChannel {
> Object parent;
> unsigned int features; /* bitmask of QIOChannelFeatures */
> +#ifdef _WIN32
> + HANDLE event; /* For use with GSource on Win23 */
Even s390 would have Win24 and Win31 but not Win23. :)
> +#endif
> };
>
> /**
> diff --git a/io/channel-socket.c b/io/channel-socket.c
> index 6f7f594..ff49853 100644
> --- a/io/channel-socket.c
> +++ b/io/channel-socket.c
> @@ -55,6 +55,10 @@ qio_channel_socket_new(void)
> ioc = QIO_CHANNEL(sioc);
> ioc->features |= (1 << QIO_CHANNEL_FEATURE_SHUTDOWN);
>
> +#ifdef WIN32
> + ioc->event = CreateEvent(NULL, FALSE, FALSE, NULL);
> +#endif
> +
> trace_qio_channel_socket_new(sioc);
>
> return sioc;
> @@ -341,6 +345,11 @@ qio_channel_socket_accept(QIOChannelSocket *ioc,
> cioc->remoteAddrLen = sizeof(ioc->remoteAddr);
> cioc->localAddrLen = sizeof(ioc->localAddr);
>
> +#ifdef WIN32
> + ((QIOChannel *)cioc)->event = CreateEvent(NULL, FALSE, FALSE, NULL);
> +#endif
QIO_CHANNEL(cioc)->event?
> + WSAEventSelect(ssource->socket, NULL, 0);
This should probably be moved in qio_channel_socket_finalize.
>
> + /* WSAEnumNetworkEvents is edge-triggered, so we need a separate
> + * call to select to find which events are actually available.
> + * However, if there were no reported events at the time of the last
> + * call, and no new events since then, we know that the socket is
> + * quiescent.
> + */
> + if (!ssource->revents && !ev.lNetworkEvents) {
> + return 0;
> + }
> +
This is unfortunately unsafe, because:
1) WSAEventSelect clears all pending events (so the next
WSAEnumNetworkEvents returns no FD_READ, unless you have read all data
in the buffer with recv)
2) setting a socket to non-blocking should call WSAEventSelect (see
below), but cannot e.g. set ->revents to ~0 for all existing GSource.
It's probably possible to add a generation count or something like that,
but for now please revert this part (I had made it a separate commit in
my prototype because I wasn't sure if it was okay).
> + ssource->condition = condition;
> + ssource->socket = socket;
> + ssource->revents = 0;
> + ssource->fd.fd = (gintptr)ioc->event;
> + ssource->fd.events = G_IO_IN;
> +
> + g_source_add_poll(source, &ssource->fd);
> + WSAEventSelect(ssource->socket, ioc->event,
> + FD_READ | FD_ACCEPT | FD_CLOSE |
> + FD_CONNECT | FD_WRITE | FD_OOB);
This should be moved where the socket is made non-blocking in
qio_channel_socket_set_blocking (because qemu_qemu_set_nonblock also
calls WSAEventSelect).
It's probably worth adding a comment that
qio_channel_socket_source_check only works in non-blocking mode for Windows.
Thanks,
Paolo
next prev parent reply other threads:[~2016-03-09 17:47 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-09 17:28 [Qemu-devel] [PATCH v1 00/21] Multiple fixes & improves to QIOChannel & Win32 Daniel P. Berrange
2016-03-09 17:28 ` [Qemu-devel] [PATCH v1 01/21] osdep: fix socket_error() to work with Mingw64 Daniel P. Berrange
2016-03-10 16:12 ` Paolo Bonzini
2016-03-10 16:13 ` Daniel P. Berrange
2016-03-09 17:28 ` [Qemu-devel] [PATCH v1 02/21] io: use bind() to check for IPv4/6 availability Daniel P. Berrange
2016-03-09 17:28 ` [Qemu-devel] [PATCH v1 03/21] io: initialize sockets in test program Daniel P. Berrange
2016-03-09 17:28 ` [Qemu-devel] [PATCH v1 04/21] io: bind to socket before creating QIOChannelSocket Daniel P. Berrange
2016-03-09 17:28 ` [Qemu-devel] [PATCH v1 05/21] io: wait for incoming client in socket test Daniel P. Berrange
2016-03-09 17:28 ` [Qemu-devel] [PATCH v1 06/21] io: set correct error object in background reader test thread Daniel P. Berrange
2016-03-09 17:28 ` [Qemu-devel] [PATCH v1 07/21] io: assert errors before asserting content in I/O test Daniel P. Berrange
2016-03-09 17:28 ` [Qemu-devel] [PATCH v1 08/21] io: fix copy+paste mistake in socket error message Daniel P. Berrange
2016-03-09 17:28 ` [Qemu-devel] [PATCH v1 09/21] io: add missing EWOULDBLOCK checks in Win32 I/O code paths Daniel P. Berrange
2016-03-09 17:28 ` [Qemu-devel] [PATCH v1 10/21] io: pass HANDLE to g_source_add_poll on Win32 Daniel P. Berrange
2016-03-09 17:28 ` [Qemu-devel] [PATCH v1 11/21] io: introduce qio_channel_create_socket_watch Daniel P. Berrange
2016-03-09 17:28 ` [Qemu-devel] [PATCH v1 12/21] io: implement socket watch for win32 using WSAEventSelect+select Daniel P. Berrange
2016-03-09 17:47 ` Paolo Bonzini [this message]
2016-03-09 19:59 ` Eric Blake
2016-03-09 21:24 ` Paolo Bonzini
2016-03-10 9:41 ` Daniel P. Berrange
2016-03-10 9:54 ` Paolo Bonzini
2016-03-10 16:30 ` Eric Blake
2016-03-10 14:50 ` Daniel P. Berrange
2016-03-09 17:28 ` [Qemu-devel] [PATCH v1 13/21] char: ensure listener socket is in blocking mode when waiting Daniel P. Berrange
2016-03-09 17:48 ` Paolo Bonzini
2016-03-09 17:28 ` [Qemu-devel] [PATCH v1 14/21] char: remove qemu_chr_finish_socket_connection method Daniel P. Berrange
2016-03-09 17:49 ` Paolo Bonzini
2016-03-10 14:50 ` Daniel P. Berrange
2016-03-09 17:28 ` [Qemu-devel] [PATCH v1 15/21] char: remove socket_try_connect method Daniel P. Berrange
2016-03-09 17:28 ` [Qemu-devel] [PATCH v1 16/21] char: remove qemu_chr_open_socket_fd method Daniel P. Berrange
2016-03-09 17:53 ` Paolo Bonzini
2016-03-10 14:51 ` Daniel P. Berrange
2016-03-09 17:28 ` [Qemu-devel] [PATCH v1 17/21] osdep: add wrappers for socket functions Daniel P. Berrange
2016-03-09 18:04 ` Paolo Bonzini
2016-03-10 14:52 ` Daniel P. Berrange
2016-03-09 17:28 ` [Qemu-devel] [PATCH v1 18/21] osdep: remove use of Win32 specific closesocket/ioctlsocket Daniel P. Berrange
2016-03-10 14:53 ` Daniel P. Berrange
2016-03-09 17:28 ` [Qemu-devel] [PATCH v1 19/21] osdep: remove use of socket_error() from all code Daniel P. Berrange
2016-03-09 17:59 ` Paolo Bonzini
2016-03-09 17:28 ` [Qemu-devel] [PATCH v1 20/21] osdep: remove direct use of qemu_socket & qemu_accept Daniel P. Berrange
2016-03-09 18:00 ` Paolo Bonzini
2016-03-09 17:28 ` [Qemu-devel] [PATCH v1 21/21] error: ensure errno detail is printed with error_abort Daniel P. Berrange
2016-03-09 18:01 ` Paolo Bonzini
2016-03-10 8:55 ` Markus Armbruster
2016-03-10 9:40 ` Daniel P. Berrange
2016-03-10 20:36 ` Markus Armbruster
2016-03-09 18:06 ` [Qemu-devel] [PATCH v1 00/21] Multiple fixes & improves to QIOChannel & Win32 Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=56E061B1.9040706@redhat.com \
--to=pbonzini@redhat.com \
--cc=Andrew.Baumann@microsoft.com \
--cc=berrange@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=sw@weilnetz.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.