userver: userver/engine/io/sys_linux/inotify.hpp Source File
Loading...
Searching...
No Matches
inotify.hpp
1#pragma once
2
3#ifdef __linux__
4
5/// @file userver/engine/io/sys_linux/inotify.hpp
6/// @brief Linux-specific fs notification API
7
8#include <sys/inotify.h>
9
10#include <optional>
11#include <queue>
12#include <string>
13#include <unordered_map>
14
15#include <userver/engine/io/fd_poller.hpp>
16#include <userver/logging/fwd.hpp>
17#include <userver/utils/flags.hpp>
18
19USERVER_NAMESPACE_BEGIN
20
21namespace engine::io::sys_linux {
22
23/// @brief Notification event type
24enum class EventType {
25 kNone = 0,
26 kAccess = IN_ACCESS,
27 kAttribChanged = IN_ATTRIB,
28 kCloseWrite = IN_CLOSE_WRITE,
29 kCloseNoWrite = IN_CLOSE_NOWRITE,
30 kCreate = IN_CREATE,
31 kDelete = IN_DELETE,
32 kDeleteSelf = IN_DELETE_SELF,
33 kModify = IN_MODIFY,
34 kMoveSelf = IN_MOVE_SELF,
35 kMovedFrom = IN_MOVED_FROM,
36 kMovedTo = IN_MOVED_TO,
37 kOpen = IN_OPEN,
38
39 kIsDir = IN_ISDIR, // event occurred against dir
40 kOnlyDir = IN_ONLYDIR, // catch only dir events
41};
42
43std::string ToString(EventType);
44
45/// @brief A set of notification event types
46using EventTypeMask = utils::Flags<EventType>;
47
48std::string ToString(EventTypeMask);
49
50/// @brief Notification event
51struct Event {
52 std::string path;
53 EventTypeMask mask;
54
55 bool operator==(const Event& other) const {
56 return path == other.path && mask == other.mask;
57 }
58};
59
60logging::LogHelper& operator<<(logging::LogHelper& lh,
61 const Event& event) noexcept;
62
63/// @brief File descriptor that allows one to monitor filesystem events, such as
64/// file creation, modification, etc.
65class Inotify final {
66 public:
67 Inotify();
68
69 Inotify(const Inotify&) = delete;
70
71 Inotify(Inotify&&) = delete;
72
73 ~Inotify();
74
75 Inotify& operator=(Inotify&&) = delete;
76
77 Inotify& operator=(const Inotify&) = delete;
78
79 /// Start to watch on the file path. Afterwards file events will be signaled
80 /// through Poll() results.
81 void AddWatch(const std::string& path, EventTypeMask flags);
82
83 /// Stop watching file events previously registered through AddWatch().
84 void RmWatch(const std::string& path);
85
86 /// Read file events with event types previously registered through
87 /// AddWatch(). Poll() blocks current coroutine until the event is obtained
88 /// or the coroutine is cancelled.
89 std::optional<Event> Poll(engine::Deadline deadline);
90
91 private:
92 void Dispatch();
93
94 FdPoller fd_;
95 std::queue<Event> pending_events_;
96 std::unordered_map<std::string, int> path_to_wd_;
97 std::unordered_map<int, std::string> wd_to_path_;
98};
99
100} // namespace engine::io::sys_linux
101
102USERVER_NAMESPACE_END
103
104#endif // __linux__