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