From: aliguori Date: Tue, 13 Jan 2009 15:13:53 +0000 (+0000) Subject: Fix race in POSIX AIO emulation (Jan Kiszka) X-Git-Tag: 0.10.0-0maemo1~65 X-Git-Url: http://git.maemo.org/git/?p=qemu;a=commitdiff_plain;h=f094a78220187996e33ba5adce29789326cf6c3c Fix race in POSIX AIO emulation (Jan Kiszka) When we cancel an AIO request that is already being processed by aio_thread, qemu_paio_cancel should return QEMU_PAIO_NOTCANCELED as long as aio_thread isn't done with this request. But as the latter currently updates aiocb->ret after every block of the request, we may report QEMU_PAIO_ALLDONE too early. Futhermore, in case some zero-length request should have been queued, aiocb->ret is never set to != -EINPROGRESS and callers like raw_aio_cancel could get stuck in an endless loop. Fix those issues by updating aiocb->ret _after_ the request has been fully processed. This also simplifies the locking. Signed-off-by: Jan Kiszka Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6278 c046a42c-6fe2-441c-8c8c-71466251a162 --- diff --git a/posix-aio-compat.c b/posix-aio-compat.c index 92ec234..c919e3b 100644 --- a/posix-aio-compat.c +++ b/posix-aio-compat.c @@ -81,21 +81,16 @@ static void *aio_thread(void *unused) if (len == -1 && errno == EINTR) continue; else if (len == -1) { - pthread_mutex_lock(&lock); - aiocb->ret = -errno; - pthread_mutex_unlock(&lock); + offset = -errno; break; } else if (len == 0) break; offset += len; - - pthread_mutex_lock(&lock); - aiocb->ret = offset; - pthread_mutex_unlock(&lock); } pthread_mutex_lock(&lock); + aiocb->ret = offset; idle_threads++; pthread_mutex_unlock(&lock);