#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #define FILE_SIZE 4096 int main(void) { io_context_t ctx; int fd,fd_odirect,i,event_fd,epoll_fd; struct epoll_event ev; void *buf; size_t offset = 0; struct iocb cb; struct iocb * cbs[1] = { &cb }; fd = open("/tmp/foo",O_RDWR|O_CREAT); if (fd == -1) { perror("open"); return 1; } for (i = 0; i < FILE_SIZE; ++i) { char c = rand() % 255; write(fd, &c, 1); } close(fd); fd_odirect = open("/tmp/foo",O_RDONLY|O_DIRECT); if (fd_odirect == -1) { perror("open"); return 1; } memset(&ctx, 0, sizeof(ctx)); if (0 != io_queue_init(1, &ctx)) { perror("ctx"); return 1; } event_fd = eventfd(0, EFD_CLOEXEC); if (event_fd == -1) { perror("eventfd"); return -1; } epoll_fd = epoll_create(1); if (epoll_fd == -1) { perror("epoll_fd"); return 1; } ev.events = EPOLLIN; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, event_fd, &ev) == -1) { perror("epoll_ctl"); return 1; } posix_memalign(&buf, 512, 32768); while (1) { struct timespec ts = { 0, 0 }; struct io_event ioev; int ret; long v; io_prep_pread(&cb, fd_odirect, buf + offset, 512, offset); io_set_eventfd(&cb, event_fd); if (1 != io_submit(ctx, 1, cbs)) { perror("io_submit"); return 1; } ret = epoll_wait(epoll_fd, &ev, 1, -1); if (ret != 1) { perror("epoll_wait"); } read(event_fd, &v, 8); printf("event_fd returned %ld\n", v); if (io_getevents(ctx, 1, 1, &ioev, &ts) != 1) { perror("io_getevents"); return 1; } printf("Read 1 res %ld res2 %ld\n", ioev.res, ioev.res2); offset += ioev.res; if (ioev.res == 0) { break; } if ((offset + 512) > 32768) { puts("ERROR - reading past buffer"); return 1; } } free(buf); io_destroy(ctx); close(event_fd); close(epoll_fd); close(fd_odirect); return 0; }