aio: Another fix to the walking_handlers logic
The AIO dispatch loop will call QLIST_REMOVE and g_free even if there are other pending calls to qemu_aio_wait outside the current one. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
ca0defb95c
commit
2db2bfc0cc
10
aio.c
10
aio.c
@ -159,14 +159,14 @@ bool qemu_aio_wait(void)
|
|||||||
|
|
||||||
/* if we have any readable fds, dispatch event */
|
/* if we have any readable fds, dispatch event */
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
walking_handlers++;
|
|
||||||
|
|
||||||
/* we have to walk very carefully in case
|
/* we have to walk very carefully in case
|
||||||
* qemu_aio_set_fd_handler is called while we're walking */
|
* qemu_aio_set_fd_handler is called while we're walking */
|
||||||
node = QLIST_FIRST(&aio_handlers);
|
node = QLIST_FIRST(&aio_handlers);
|
||||||
while (node) {
|
while (node) {
|
||||||
AioHandler *tmp;
|
AioHandler *tmp;
|
||||||
|
|
||||||
|
walking_handlers++;
|
||||||
|
|
||||||
if (!node->deleted &&
|
if (!node->deleted &&
|
||||||
FD_ISSET(node->fd, &rdfds) &&
|
FD_ISSET(node->fd, &rdfds) &&
|
||||||
node->io_read) {
|
node->io_read) {
|
||||||
@ -181,13 +181,13 @@ bool qemu_aio_wait(void)
|
|||||||
tmp = node;
|
tmp = node;
|
||||||
node = QLIST_NEXT(node, node);
|
node = QLIST_NEXT(node, node);
|
||||||
|
|
||||||
if (tmp->deleted) {
|
walking_handlers--;
|
||||||
|
|
||||||
|
if (!walking_handlers && tmp->deleted) {
|
||||||
QLIST_REMOVE(tmp, node);
|
QLIST_REMOVE(tmp, node);
|
||||||
g_free(tmp);
|
g_free(tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
walking_handlers--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user