forked from svarshavchik/vera
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpoller.H
189 lines (123 loc) · 4.55 KB
/
poller.H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/*
** Copyright 2022 Double Precision, Inc.
** See COPYING for distribution information.
*/
#ifndef poller_h
#define poller_h
#include <functional>
#include <sys/types.h>
#include <variant>
#include <string>
#include <memory>
#include <filesystem>
//! A polled file descriptor
//! The file descriptor should have O_NONBLOCK and O_CLOEXEC set, before
//! polledfd is constructed.
//!
//! The 2nd parameter to the constructor is a callable object that
//! do_poll() invokes whenever the file descriptor is readable, and it
//! receives the file descriptor as the parameter.
//!
//! This object is movable, but not copyable
class polledfd {
int fd{-1};
void destroy();
public:
polledfd()=default;
polledfd(int fd, const std::function<void (int)> &callback);
polledfd(int fd, std::function<void (int)> &&callback);
~polledfd();
polledfd(polledfd &&);
polledfd &operator=(polledfd &&);
polledfd &operator=(const polledfd &)=delete;
};
/* Poll and take action */
void do_poll(int timeout= -1);
/* Update current_time, in current_containers_infoObj */
void update_current_time();
typedef std::function<void (const char *, uint32_t)> inotify_cb_t;
/*! An inotify-based watcher
The constructor's parameters are: a pathname, a mask (see inotify(7)
for the description of the mask value that gets passed to inotify_add_watch),
and a callback.
The callback takes two parameters, a const char *, which might be null, and
the occured event mask.
operator bool is an indication whether the watch was installed successfully.
The destructor removes the watch, and the callback.
An edge case occurs if a new watch gets constructed after other watches
get removed. The new watch does not get added immediately after but only after
the removed watch gets acknowledged by IN_IGNORED. It's possible that
at that time inotify_add_watch fails because the path does not exist. This
results in a synthesized invocation of the callback with an IN_IGNORED value.
To summarize:
1) Operator bool is false after construction when the watch failed because
the watched file or directory definitely does not exist.
2) Operator bool returning true after construction guarantees the callback
getting invoked with an IN_IGNORED mask.
3) In all cases, the callback that gets passed to the constructor does not
get called after either this object gets destroyed or the ultimate moved-to
object gets destroyed (these objects are movable-only).
*/
class inotify_watch_handler {
int wd;
bool installed;
public:
class delink;
friend class delink;
operator bool() const { return installed; }
inotify_watch_handler() : wd{-1}, installed(false) {}
inotify_watch_handler(const std::string &pathname, uint32_t mask,
inotify_cb_t);
~inotify_watch_handler();
//! Value for the mask parameter to the constructor
//! Specifies that pathname is a directory.
static const uint32_t mask_dir;
//! Value for the mask parameter to the constructor
//! Specifies that pathname is a file whose changes we want to modify.
static const uint32_t mask_filemodify;
//! Movable object
inotify_watch_handler(inotify_watch_handler &&);
//! Non-assignable object.
inotify_watch_handler &operator=(
inotify_watch_handler &&
);
//! Non-assignable object.
inotify_watch_handler &operator=(
const inotify_watch_handler &
)=delete;
private:
void destroy();
};
struct poller_transferblockObj {};
typedef std::shared_ptr<poller_transferblockObj> poller_transferblock;
poller_transferblock get_poller_transferblock();
/*! Whether the poller is in a state that will survive a re-exec.
We won't re-exec when there are pending removes or deletes. There's
nothing inherent that actually prevents it. The re-exec-ed process
will rewatch everything, this is just an extra safety measure.
*/
bool poller_is_transferrable();
/*! Monitor a directory for changes.
The constructor takes two callbacks:
- Invoked with the name of the changed file in the given hierarchy.
- Invoked to report a fatal error of some sort.
*/
class monitor_hierarchy : inotify_watch_handler {
public:
typedef std::function<void (const char *)> changed_t;
typedef std::function<void (std::string)> fatal_error_t;
struct monitor_info;
monitor_hierarchy(const std::filesystem::path &dir,
changed_t changed,
fatal_error_t fatal_error);
private:
monitor_hierarchy(std::filesystem::path dir,
changed_t &changed,
std::shared_ptr<fatal_error_t> fatal_error);
monitor_hierarchy(std::shared_ptr<monitor_info> info);
public:
using inotify_watch_handler::operator bool;
};
//! Return a file descriptor for /dev/null
int devnull();
#endif