aboutsummaryrefslogtreecommitdiff
path: root/io/channel-socket.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2016-03-07 12:12:36 +0100
committerDaniel P. Berrange <berrange@redhat.com>2016-03-10 17:19:07 +0000
commita58972056776e2f2588aed5a2dc0db7cc28f80b1 (patch)
treec0dd41eda6b2fb73dd1b477b17723c695aa0a6a1 /io/channel-socket.c
parent30fd3e27907dfd1c0c66cc1339657af1a2ce1d4b (diff)
downloadqemu-a58972056776e2f2588aed5a2dc0db7cc28f80b1.zip
qemu-a58972056776e2f2588aed5a2dc0db7cc28f80b1.tar.gz
qemu-a58972056776e2f2588aed5a2dc0db7cc28f80b1.tar.bz2
io: implement socket watch for win32 using WSAEventSelect+select
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: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Diffstat (limited to 'io/channel-socket.c')
-rw-r--r--io/channel-socket.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/io/channel-socket.c b/io/channel-socket.c
index 2387d97..ae67ab1 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
+ QIO_CHANNEL(cioc)->event = CreateEvent(NULL, FALSE, FALSE, NULL);
+#endif
+
+
retry:
trace_qio_channel_socket_accept(ioc);
cioc->fd = qemu_accept(ioc->fd, (struct sockaddr *)&cioc->remoteAddr,
@@ -384,7 +393,10 @@ static void qio_channel_socket_finalize(Object *obj)
{
QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(obj);
if (ioc->fd != -1) {
- close(ioc->fd);
+#ifdef WIN32
+ WSAEventSelect(ioc->fd, NULL, 0);
+#endif
+ closesocket(ioc->fd);
ioc->fd = -1;
}
}
@@ -634,6 +646,11 @@ qio_channel_socket_set_blocking(QIOChannel *ioc,
qemu_set_block(sioc->fd);
} else {
qemu_set_nonblock(sioc->fd);
+#ifdef WIN32
+ WSAEventSelect(sioc->fd, ioc->event,
+ FD_READ | FD_ACCEPT | FD_CLOSE |
+ FD_CONNECT | FD_WRITE | FD_OOB);
+#endif
}
return 0;
}
@@ -669,13 +686,18 @@ qio_channel_socket_close(QIOChannel *ioc,
{
QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
- if (closesocket(sioc->fd) < 0) {
+ if (sioc->fd != -1) {
+#ifdef WIN32
+ WSAEventSelect(sioc->fd, NULL, 0);
+#endif
+ if (closesocket(sioc->fd) < 0) {
+ sioc->fd = -1;
+ error_setg_errno(errp, socket_error(),
+ "Unable to close socket");
+ return -1;
+ }
sioc->fd = -1;
- error_setg_errno(errp, socket_error(),
- "Unable to close socket");
- return -1;
}
- sioc->fd = -1;
return 0;
}