int aioCheckCallbacks(SwapDir * SD) { squidaio_result_t *resultp; squidaio_ctrl_t *ctrlp; AIOCB *done_handler; void *their_data; int retval = 0; assert(initialised); squidaio_counts.check_callback++; for (;;) { if ((resultp = squidaio_poll_done()) == NULL) break; ctrlp = (squidaio_ctrl_t *) resultp->data; if (ctrlp == NULL) continue; /* XXX Should not happen */ dlinkDelete(&ctrlp->node, &used_list); if ((done_handler = ctrlp->done_handler)) { their_data = ctrlp->done_handler_data; ctrlp->done_handler = NULL; ctrlp->done_handler_data = NULL; if (cbdataValid(their_data)) { retval = 1; /* Return that we've actually done some work */ done_handler(ctrlp->fd, their_data, ctrlp->bufp, ctrlp->result.aio_return, ctrlp->result.aio_errno); } else { if (ctrlp->operation == _AIO_OPEN) { /* The open operation was aborted.. */ int fd = ctrlp->result.aio_return; if (fd >= 0) aioClose(fd); } } cbdataUnlock(their_data); } /* free data if requested to aioWrite() */ if (ctrlp->free_func) ctrlp->free_func(ctrlp->bufp); /* free temporary read buffer */ if (ctrlp->operation == _AIO_READ) squidaio_xfree(ctrlp->bufp, ctrlp->len); if (ctrlp->operation == _AIO_CLOSE) aioFDWasClosed(ctrlp->fd); memPoolFree(squidaio_ctrl_pool, ctrlp); } return retval; }
static void squidaio_cleanup_request(squidaio_request_t * requestp) { squidaio_result_t *resultp = requestp->resultp; int cancelled = requestp->cancelled; /* Free allocated structures and copy data back to user space if the */ /* request hasn't been cancelled */ switch (requestp->request_type) { case _AIO_OP_STAT: if (!cancelled && requestp->ret == 0) xmemcpy(requestp->statp, requestp->tmpstatp, sizeof(struct stat)); squidaio_xfree(requestp->tmpstatp, sizeof(struct stat)); squidaio_xstrfree(requestp->path); break; case _AIO_OP_OPEN: if (cancelled && requestp->ret >= 0) /* The open() was cancelled but completed */ close(requestp->ret); squidaio_xstrfree(requestp->path); break; case _AIO_OP_CLOSE: if (cancelled && requestp->ret < 0) /* The close() was cancelled and never got executed */ close(requestp->fd); break; case _AIO_OP_UNLINK: case _AIO_OP_TRUNCATE: case _AIO_OP_OPENDIR: squidaio_xstrfree(requestp->path); break; case _AIO_OP_READ: break; case _AIO_OP_WRITE: break; default: break; } if (resultp != NULL && !cancelled) { resultp->aio_return = requestp->ret; resultp->aio_errno = requestp->err; } memPoolFree(squidaio_request_pool, requestp); } /* squidaio_cleanup_request */
void aioCancel(int fd) { squidaio_ctrl_t *ctrlp; AIOCB *done_handler; void *their_data; dlink_node *m, *next; assert(initialised); squidaio_counts.cancel++; for (m = used_list.head; m; m = next) { next = m->next; ctrlp = m->data; if (ctrlp->fd != fd) continue; squidaio_cancel(&ctrlp->result); if ((done_handler = ctrlp->done_handler)) { their_data = ctrlp->done_handler_data; ctrlp->done_handler = NULL; ctrlp->done_handler_data = NULL; debug(32, 0) ("this be aioCancel. Danger ahead!\n"); if (cbdataValid(their_data)) done_handler(fd, their_data, NULL, -2, -2); cbdataUnlock(their_data); /* free data if requested to aioWrite() */ if (ctrlp->free_func) ctrlp->free_func(ctrlp->bufp); /* free temporary read buffer */ if (ctrlp->operation == _AIO_READ) squidaio_xfree(ctrlp->bufp, ctrlp->len); } dlinkDelete(m, &used_list); memPoolFree(squidaio_ctrl_pool, ctrlp); } }