This patch adds dequeue_work threadlet API and shows how the paio_cancel changes to dequeue_work.
The active field in the qemu_aiocb structure is now useless. Remove it. Signed-off-by: Arun R Bharadwaj <a...@linux.vnet.ibm.com> --- posix-aio-compat.c | 38 ++++++++++++++++---------------------- 1 files changed, 16 insertions(+), 22 deletions(-) diff --git a/posix-aio-compat.c b/posix-aio-compat.c index 2ab1109..2d73846 100644 --- a/posix-aio-compat.c +++ b/posix-aio-compat.c @@ -69,7 +69,6 @@ struct qemu_paiocb { int aio_type; ssize_t ret; - int active; struct qemu_paiocb *next; int async_context_id; @@ -346,7 +345,6 @@ static void handle_work(ThreadletWork *work) pid = getpid(); qemu_mutex_lock(&aiocb_mutex); aiocb = container_of(work, struct qemu_paiocb, work); - aiocb->active = 1; qemu_mutex_unlock(&aiocb_mutex); switch (aiocb->aio_type & QEMU_AIO_TYPE_MASK) { @@ -452,7 +450,6 @@ static void qemu_paio_submit(struct qemu_paiocb *aiocb) { qemu_mutex_lock(&aiocb_mutex); aiocb->ret = -EINPROGRESS; - aiocb->active = 0; qemu_mutex_unlock(&aiocb_mutex); aiocb->work.func = handle_work; @@ -574,33 +571,30 @@ static void paio_remove(struct qemu_paiocb *acb) } } -static void paio_cancel(BlockDriverAIOCB *blockacb) +/** + * dequeue_work: Cancel a task queued on the global queue. + * @work: Contains the information of the task that needs to be cancelled. + */ +static int dequeue_work(ThreadletWork *work) { - struct qemu_paiocb *acb = (struct qemu_paiocb *)blockacb; - int active = 0; - - qemu_mutex_lock(&aiocb_mutex); qemu_mutex_lock(&globalqueue.lock); - if (!acb->active) { - QTAILQ_REMOVE(&globalqueue.request_list, &acb->work, node); - acb->ret = -ECANCELED; - } else if (acb->ret == -EINPROGRESS) { - active = 1; - } + QTAILQ_REMOVE(&globalqueue.request_list, work, node); qemu_mutex_unlock(&globalqueue.lock); - if (!active) { - acb->ret = -ECANCELED; - } else { + return 0; +} + +static void paio_cancel(BlockDriverAIOCB *blockacb) +{ + struct qemu_paiocb *acb = (struct qemu_paiocb *)blockacb; + if (dequeue_work(&acb->work) != 0) { + /* Wait for running work item to complete */ + qemu_mutex_lock(&aiocb_mutex); while (acb->ret == -EINPROGRESS) { - /* - * fail safe: if the aio could not be canceled, - * we wait for it - */ qemu_cond_wait(&aiocb_completion, &aiocb_mutex); } + qemu_mutex_unlock(&aiocb_mutex); } - qemu_mutex_unlock(&aiocb_mutex); paio_remove(acb); }