]> git.sesse.net Git - plocate/blob - io_uring_engine.h
Release plocate 1.1.22.
[plocate] / io_uring_engine.h
1 #ifndef IO_URING_ENGINE_H
2 #define IO_URING_ENGINE_H 1
3
4 #include <functional>
5 #include <queue>
6 #include <stddef.h>
7 #include <string_view>
8 #include <sys/socket.h>
9 #include <sys/types.h>
10 #include <linux/stat.h>
11
12 struct io_uring_sqe;
13 #ifndef WITHOUT_URING
14 #include <liburing.h>
15 #endif
16
17 class IOUringEngine {
18 public:
19         IOUringEngine(size_t slop_bytes);
20         void submit_read(int fd, size_t len, off_t offset, std::function<void(std::string_view)> cb);
21
22         // NOTE: We just do the stat() to get the data into the dentry cache for fast access,
23         // or to check whether the file exists. Thus, the callback has only an OK/not OK boolean.
24         void submit_stat(const char *path, std::function<void(bool ok)> cb);
25         bool get_supports_stat() { return supports_stat; }
26
27         void finish();
28         size_t get_waiting_reads() const { return pending_reads + queued_reads.size(); }
29
30 private:
31 #ifndef WITHOUT_URING
32         void submit_read_internal(io_uring_sqe *sqe, int fd, size_t len, off_t offset, std::function<void(std::string_view)> cb);
33         void submit_stat_internal(io_uring_sqe *sqe, char *path, std::function<void(bool)> cb);
34
35         io_uring ring;
36 #endif
37         size_t pending_reads = 0;  // Number of requests we have going in the ring.
38         bool using_uring, supports_stat = false;
39         const size_t slop_bytes;
40
41         struct QueuedRead {
42                 int fd;
43                 size_t len;
44                 off_t offset;
45                 std::function<void(std::string_view)> cb;
46         };
47         std::queue<QueuedRead> queued_reads;
48
49         struct QueuedStat {
50                 char *pathname;  // Owned by us.
51                 std::function<void(bool)> cb;
52         };
53         std::queue<QueuedStat> queued_stats;
54
55         enum Op { OP_READ,
56                   OP_STAT };
57
58         struct PendingRead {
59                 Op op;
60
61                 std::function<void(std::string_view)> read_cb;
62                 std::function<void(bool)> stat_cb;
63
64                 union {
65                         struct {
66                                 void *buf;
67                                 size_t len;
68
69                                 // For re-submission.
70                                 int fd;
71                                 off_t offset;
72                                 iovec iov;
73                         } read;
74                         struct {
75                                 char *pathname;
76                                 struct statx *buf;
77                         } stat;
78                 };
79         };
80
81         // 256 simultaneous requests should be ample, for slow and fast media alike.
82         static constexpr size_t queue_depth = 256;
83 };
84
85 #endif  // !defined(IO_URING_ENGINE_H)