diff options
author | Peter Maydell | 2019-01-15 18:24:00 +0100 |
---|---|---|
committer | Peter Maydell | 2019-01-15 18:24:00 +0100 |
commit | 4b9f0b0f7c84eea2dfb0d5be3e0254bc91319dbc (patch) | |
tree | 6dad0111547ebebcd2bb5e5ac412ba2b4f052883 /util/aio-win32.c | |
parent | Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2019-01-14' into st... (diff) | |
parent | aio-posix: Fix concurrent aio_poll/set_fd_handler. (diff) | |
download | qemu-4b9f0b0f7c84eea2dfb0d5be3e0254bc91319dbc.tar.gz qemu-4b9f0b0f7c84eea2dfb0d5be3e0254bc91319dbc.tar.xz qemu-4b9f0b0f7c84eea2dfb0d5be3e0254bc91319dbc.zip |
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
Pull request
No user-visible changes.
# gpg: Signature made Mon 14 Jan 2019 16:32:19 GMT
# gpg: using RSA key 9CA4ABB381AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>"
# Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35 775A 9CA4 ABB3 81AB 73C8
* remotes/stefanha/tags/block-pull-request:
aio-posix: Fix concurrent aio_poll/set_fd_handler.
aio-posix: Unregister fd from ctx epoll when removing fd_handler.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'util/aio-win32.c')
-rw-r--r-- | util/aio-win32.c | 67 |
1 files changed, 29 insertions, 38 deletions
diff --git a/util/aio-win32.c b/util/aio-win32.c index c58957cc4b..a23b9c364d 100644 --- a/util/aio-win32.c +++ b/util/aio-win32.c @@ -35,6 +35,22 @@ struct AioHandler { QLIST_ENTRY(AioHandler) node; }; +static void aio_remove_fd_handler(AioContext *ctx, AioHandler *node) +{ + /* If aio_poll is in progress, just mark the node as deleted */ + if (qemu_lockcnt_count(&ctx->list_lock)) { + node->deleted = 1; + node->pfd.revents = 0; + } else { + /* Otherwise, delete it for real. We can't just mark it as + * deleted because deleted nodes are only cleaned up after + * releasing the list_lock. + */ + QLIST_REMOVE(node, node); + g_free(node); + } +} + void aio_set_fd_handler(AioContext *ctx, int fd, bool is_external, @@ -44,41 +60,23 @@ void aio_set_fd_handler(AioContext *ctx, void *opaque) { /* fd is a SOCKET in our case */ - AioHandler *node; + AioHandler *old_node; + AioHandler *node = NULL; qemu_lockcnt_lock(&ctx->list_lock); - QLIST_FOREACH(node, &ctx->aio_handlers, node) { - if (node->pfd.fd == fd && !node->deleted) { + QLIST_FOREACH(old_node, &ctx->aio_handlers, node) { + if (old_node->pfd.fd == fd && !old_node->deleted) { break; } } - /* Are we deleting the fd handler? */ - if (!io_read && !io_write) { - if (node) { - /* If aio_poll is in progress, just mark the node as deleted */ - if (qemu_lockcnt_count(&ctx->list_lock)) { - node->deleted = 1; - node->pfd.revents = 0; - } else { - /* Otherwise, delete it for real. We can't just mark it as - * deleted because deleted nodes are only cleaned up after - * releasing the list_lock. - */ - QLIST_REMOVE(node, node); - g_free(node); - } - } - } else { + if (io_read || io_write) { HANDLE event; long bitmask = 0; - if (node == NULL) { - /* Alloc and insert if it's not already there */ - node = g_new0(AioHandler, 1); - node->pfd.fd = fd; - QLIST_INSERT_HEAD_RCU(&ctx->aio_handlers, node, node); - } + /* Alloc and insert if it's not already there */ + node = g_new0(AioHandler, 1); + node->pfd.fd = fd; node->pfd.events = 0; if (node->io_read) { @@ -104,9 +102,13 @@ void aio_set_fd_handler(AioContext *ctx, bitmask |= FD_WRITE | FD_CONNECT; } + QLIST_INSERT_HEAD_RCU(&ctx->aio_handlers, node, node); event = event_notifier_get_handle(&ctx->notifier); WSAEventSelect(node->pfd.fd, event, bitmask); } + if (old_node) { + aio_remove_fd_handler(ctx, old_node); + } qemu_lockcnt_unlock(&ctx->list_lock); aio_notify(ctx); @@ -139,18 +141,7 @@ void aio_set_event_notifier(AioContext *ctx, if (node) { g_source_remove_poll(&ctx->source, &node->pfd); - /* aio_poll is in progress, just mark the node as deleted */ - if (qemu_lockcnt_count(&ctx->list_lock)) { - node->deleted = 1; - node->pfd.revents = 0; - } else { - /* Otherwise, delete it for real. We can't just mark it as - * deleted because deleted nodes are only cleaned up after - * releasing the list_lock. - */ - QLIST_REMOVE(node, node); - g_free(node); - } + aio_remove_fd_handler(ctx, node); } } else { if (node == NULL) { |