/* This is a simple "eventfd" example that uses io_uring It demonstrates that reads work as expected on eventfds. It uses liburing for simplicity. */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include #include #include struct io_uring ring; int main(int argc, char * argv[]) { int fd = eventfd(0, 0); if(fd < 0) { printf("Could not open event fd.\n"); return 2; } /* prep the array */ char buf[sizeof(uint64_t)] = { 0 }; struct iovec iov = { buf, 8 }; { /* Do one write so we can compare blocking behaviour */ eventfd_t val; val = 1; eventfd_write( fd, val ); } /* init liburing */ io_uring_queue_init(256, &ring, 0); /* declare required structs */ struct io_uring_sqe * sqe; struct io_uring_cqe * cqe; /* get an sqe and fill in a READ operation */ sqe = io_uring_get_sqe(&ring); io_uring_prep_read(sqe, fd, buf, 8, 0); sqe->user_data = fd; /* tell the kernel we have an sqe ready for consumption */ io_uring_submit(&ring); printf("First wait\n"); /* wait for the sqe to complete */ int ret = io_uring_wait_cqe(&ring, &cqe); /* read and process cqe event */ if(ret == 0) { signed int len = cqe->res; io_uring_cqe_seen(&ring, cqe); printf("%d ", len); if(len > 0) { printf("%.*s", len, buf); } else if( len < 0 ) { fprintf(stderr, "readv/read returned error : %s\n", strerror(-len)); } } else { printf("%d\n", ret); io_uring_cqe_seen(&ring, cqe); } /* ============================================ */ /* DO it again so the we can compare behaviour. */ /* ============================================ */ /* get an sqe and fill in a READ operation */ sqe = io_uring_get_sqe(&ring); io_uring_prep_read(sqe, fd, buf, 8, 0); sqe->user_data = fd; printf("Second wait\n"); /* tell the kernel we have an sqe ready for consumption */ io_uring_submit(&ring); /* wait for the sqe to complete */ ret = io_uring_wait_cqe(&ring, &cqe); /* read and process cqe event */ if(ret == 0) { signed int len = cqe->res; io_uring_cqe_seen(&ring, cqe); printf("%d ", len); if(len > 0) { printf("%.*s", len, buf); } else if( len < 0 ) { fprintf(stderr, "readv/read returned error : %s\n", strerror(-len)); } } else { printf("%d\n", ret); io_uring_cqe_seen(&ring, cqe); } io_uring_queue_exit(&ring); close(fd); }