Patchwork aio: another fix to the walking_handlers logic

login
register
mail settings
Submitter Paolo Bonzini
Date Sept. 24, 2012, 3:06 p.m.
Message ID <1348499171-15791-1-git-send-email-pbonzini@redhat.com>
Download mbox | patch
Permalink /patch/186457/
State New
Headers show

Comments

Paolo Bonzini - Sept. 24, 2012, 3:06 p.m.
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>
---
        This is on top of the existing fix that is posted as part of
        the glusterfs series.  Bharata, can you add this patch as well?

 aio.c | 10 +++++-----
 1 file modificato, 5 inserzioni(+), 5 rimozioni(-)
Bharata B Rao - Sept. 24, 2012, 3:43 p.m.
On Mon, Sep 24, 2012 at 05:06:11PM +0200, Paolo Bonzini wrote:
> 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>
> ---
>         This is on top of the existing fix that is posted as part of
>         the glusterfs series.  Bharata, can you add this patch as well?

Sure, I can. Hoping that there will be consensus on URI parsing library soon
so that these aio fixes and my GlusterFS patches can be pushed in time
for 1.3.

Regards,
Bharata.

Patch

diff --git a/aio.c b/aio.c
index 99b8b72..c738a4e 100644
--- a/aio.c
+++ b/aio.c
@@ -159,14 +159,14 @@  bool qemu_aio_wait(void)
 
     /* if we have any readable fds, dispatch event */
     if (ret > 0) {
-        walking_handlers++;
-
         /* we have to walk very carefully in case
          * qemu_aio_set_fd_handler is called while we're walking */
         node = QLIST_FIRST(&aio_handlers);
         while (node) {
             AioHandler *tmp;
 
+            walking_handlers++;
+
             if (!node->deleted &&
                 FD_ISSET(node->fd, &rdfds) &&
                 node->io_read) {
@@ -181,13 +181,13 @@  bool qemu_aio_wait(void)
             tmp = node;
             node = QLIST_NEXT(node, node);
 
-            if (tmp->deleted) {
+            walking_handlers--;
+
+            if (!walking_handlers && tmp->deleted) {
                 QLIST_REMOVE(tmp, node);
                 g_free(tmp);
             }
         }
-
-        walking_handlers--;
     }
 
     return true;