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);
    }
}