Search code examples
caio

C keep track of aio_read task


I have a function that starts an aio_read task and returns to the main program.

I want to periodically check if the task is completed to close the file descriptor and maybe notify the user.

My current approach is declaring a struct that contains the struct aiocb of the task and the file descriptor. Adding it to a global array and checking if any task is working with the following (aio_check function):

#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <aio.h>
#include <unistd.h>

#include "aioqueue.h"

void aio_add(struct aiocb a, int fd) {
    for (int i = 0; i < MAX; i++) {
        if (aio_array[i].valid == 0) {
            aio_pack tmp;
            tmp.cb = a;
            tmp.fd = fd;
            tmp.valid = 1;
            aio_array[i] = tmp;

            printf("request enqueued\n");
            return;
        }
    }
    printf("This shell cannot keep track of so many IO operations :/ \n");
}

void aio_check() {
    for (int i = 0; i < MAX; i++) {
        // wait until the request has finished
        if(aio_array[i].valid) {
            if (aio_error(&aio_array[i].cb) != EINPROGRESS) {
                int nleidos = aio_return(&aio_array[i].cb);

                if (nleidos != -1)
                    printf("AIO Task finished: %d B\n", nleidos);
                else
                    printf("Error!");

                close(aio_array[i].fd); 
                aio_array[i].valid = 0; 
            } else {
                printf("At least one AIO task is in progress\n");           
            }
        }
    }
}

and the code for aioqueue.h

#define MAX 10

typedef struct {
    struct aiocb cb;
    int fd;
    int valid;
} aio_pack;

aio_pack aio_array[MAX];

void aio_add(struct aiocb a, int fd);
void aio_check();

The problem is that if i call aio_check after i added a task i always get the

At least one AIO task is in progress

message. Even if it's clear that the task has finished.

I suppose that it might be due to the fact that im passing a copy of the struct aiocb in a moment where the aio_error is EINPROGRESS and as its a copy it never gets updated. But im pretty lost at this moment. Any help would be greatly appreciated.

Thank you in advance.


Solution

  • You need to call aio_suspend() in order to process what i/o's have completed, otherwise aio_error() etc will never return differently. See https://github.com/ned14/llfio/blob/master/include/llfio/v2.0/detail/impl/posix/io_service.ipp#L290.