aio: another fix to the walking_handlers logic

Submitted by Paolo Bonzini on Sept. 24, 2012, 3:06 p.m.

Details

Message ID 1348499171-15791-1-git-send-email-pbonzini@redhat.com
State New
Headers show

Commit Message

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(-)

Comments

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 hide | download patch | download mbox

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;