source: example/io/filereader.c @ 960665c

Last change on this file since 960665c was f0d67e5, checked in by Thierry Delisle <tdelisle@…>, 4 years ago

Restored io examples to example folder

  • Property mode set to 100644
File size: 2.8 KB
Line 
1/*
2This is a file reading example that users io_uring in non-blocking mode.
3It demonstrates the bare minimum needed to use io_uring.
4It also optionally pre-registers the file descriptors (and a pipe, just to show it works).
5It uses liburing for simplicity.
6*/
7
8
9#include <errno.h>
10#include <fcntl.h>
11#include <liburing.h>
12#include <stdbool.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <unistd.h>
17
18int main(int argc, char * argv[]) {
19        if(argc != 3 && argc != 4) {
20            printf("usage:   %s FILE TIMES [fixed] - read FILE from disk TIMES times\n", argv[0]);
21            return EXIT_FAILURE;
22      }
23
24        bool fixed = false;
25        if(argc == 4) {
26                fixed = 0 == strcmp(argv[3], "fixed");
27        }
28
29      int times = atoi( argv[2] );
30      if(times <= 0) {
31            printf("Invalid number of times %d (from %s).\n", times, argv[2]);
32            return EXIT_FAILURE;
33      }
34
35      int fd = open(argv[1], 0);
36      if(fd < 0) {
37            printf("Could not open file %s.\n", argv[1]);
38            return EXIT_FAILURE;
39      }
40
41        int rfd = fd;
42
43        /* prep the array */
44      char data[100];
45      struct iovec iov = { data, 100 };
46
47        /* init liburing */
48        struct io_uring ring;
49      io_uring_queue_init(256, &ring, 0);
50
51        int pipefds[2];
52        if(fixed) {
53                int ret = pipe(pipefds);
54                if( ret < 0 ) {
55                        printf("Pipe Error : %s\n", strerror( errno ));
56                        return EXIT_FAILURE;
57                }
58                rfd = 0;
59                int fds[] = {
60                        fd, pipefds[0], pipefds[1]
61                };
62                int cnt = sizeof(fds) / sizeof(fds[0]);
63                printf("Registering %d files as fixed\n", cnt);
64                ret = io_uring_register_files(&ring, fds, cnt);
65                if( ret < 0 ) {
66                        printf("Register Error : %s\n", strerror( -ret ));
67                        return EXIT_FAILURE;
68                }
69        }
70
71      /* declare required structs */
72        printf("Reading %s(%d) %d times\n", argv[1], fd, times);
73        size_t counter = 0;
74        for(int i = 0; i < times; i++) {
75                /* get an sqe and fill in a READV operation */
76              struct io_uring_sqe * sqe = io_uring_get_sqe(&ring);
77                io_uring_prep_readv(sqe, rfd, &iov, 1, 0);
78                if(fixed) {
79                        sqe->flags = IOSQE_FIXED_FILE;
80                }
81
82                /* tell the kernel we have an sqe ready for consumption */
83        io_uring_submit(&ring);
84
85                /* poll the cq and count how much polling we did */
86                while(true) {
87                        struct io_uring_cqe * cqe = NULL;
88                        /* wait for the sqe to complete */
89                        int ret = io_uring_wait_cqe_nr(&ring, &cqe, 0);
90
91                        /* read and process cqe event */
92                        switch(ret) {
93                        case 0:
94                                if( cqe->res < 0 ) {
95                                        printf("Completion Error : %s\n", strerror( -cqe->res ));
96                                        return EXIT_FAILURE;
97                                }
98                                io_uring_cqe_seen(&ring, cqe);
99                                goto LOOP;
100                        case -EAGAIN:
101                                counter++;
102                                break;
103                        default:
104                                printf("Wait Error : %s\n", strerror( -ret ));
105                                return EXIT_FAILURE;
106                        }
107                }
108
109                LOOP:;
110        }
111
112        printf("%zu\n", counter);
113
114      io_uring_queue_exit(&ring);
115
116      close(fd);
117
118        if(fixed) {
119                close(pipefds[0]);
120                close(pipefds[1]);
121        }
122}
Note: See TracBrowser for help on using the repository browser.