Skip to content

Commit

Permalink
async: Allow nested qemu_bh_poll calls
Browse files Browse the repository at this point in the history
qemu may segfault when a BH handler first deletes a BH and then (possibly
indirectly) calls a nested qemu_bh_poll(). This is because the inner instance
frees the BH and deletes it from the list that the outer one processes.

This patch deletes BHs only in the outermost qemu_bh_poll instance.

Commit 7887f62 already tried to achieve the same, but it assumed that the BH
handler would only delete its own BH. With a nested qemu_bh_poll(), this isn't
guaranteed, so that commit wasn't enough. Hope this one fixes it for real.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
  • Loading branch information
kevmw committed Sep 6, 2011
1 parent 0fa9131 commit 648fb0e
Showing 1 changed file with 16 additions and 8 deletions.
24 changes: 16 additions & 8 deletions async.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ int qemu_bh_poll(void)
{
QEMUBH *bh, **bhp, *next;
int ret;
static int nesting = 0;

nesting++;

ret = 0;
for (bh = first_bh; bh; bh = next) {
Expand All @@ -68,15 +71,20 @@ int qemu_bh_poll(void)
}
}

nesting--;

/* remove deleted bhs */
bhp = &first_bh;
while (*bhp) {
bh = *bhp;
if (bh->deleted) {
*bhp = bh->next;
g_free(bh);
} else
bhp = &bh->next;
if (!nesting) {
bhp = &first_bh;
while (*bhp) {
bh = *bhp;
if (bh->deleted) {
*bhp = bh->next;
g_free(bh);
} else {
bhp = &bh->next;
}
}
}

return ret;
Expand Down

0 comments on commit 648fb0e

Please sign in to comment.