1 #pragma once
2 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 
4 #include <sys/epoll.h>
5 #include <sys/timerfd.h>
6 #include <sys/wait.h>
7 
8 #include "sd-event.h"
9 
10 #include "hashmap.h"
11 #include "inotify-util.h"
12 #include "list.h"
13 #include "prioq.h"
14 #include "ratelimit.h"
15 
16 typedef enum EventSourceType {
17         SOURCE_IO,
18         SOURCE_TIME_REALTIME,
19         SOURCE_TIME_BOOTTIME,
20         SOURCE_TIME_MONOTONIC,
21         SOURCE_TIME_REALTIME_ALARM,
22         SOURCE_TIME_BOOTTIME_ALARM,
23         SOURCE_SIGNAL,
24         SOURCE_CHILD,
25         SOURCE_DEFER,
26         SOURCE_POST,
27         SOURCE_EXIT,
28         SOURCE_WATCHDOG,
29         SOURCE_INOTIFY,
30         _SOURCE_EVENT_SOURCE_TYPE_MAX,
31         _SOURCE_EVENT_SOURCE_TYPE_INVALID = -EINVAL,
32 } EventSourceType;
33 
34 /* All objects we use in epoll events start with this value, so that
35  * we know how to dispatch it */
36 typedef enum WakeupType {
37         WAKEUP_NONE,
38         WAKEUP_EVENT_SOURCE, /* either I/O or pidfd wakeup */
39         WAKEUP_CLOCK_DATA,
40         WAKEUP_SIGNAL_DATA,
41         WAKEUP_INOTIFY_DATA,
42         _WAKEUP_TYPE_MAX,
43         _WAKEUP_TYPE_INVALID = -EINVAL,
44 } WakeupType;
45 
46 struct inode_data;
47 
48 struct sd_event_source {
49         WakeupType wakeup;
50 
51         unsigned n_ref;
52 
53         sd_event *event;
54         void *userdata;
55         sd_event_handler_t prepare;
56 
57         char *description;
58 
59         EventSourceType type;
60         signed int enabled:3;
61         bool pending:1;
62         bool dispatching:1;
63         bool floating:1;
64         bool exit_on_failure:1;
65         bool ratelimited:1;
66 
67         int64_t priority;
68         unsigned pending_index;
69         unsigned prepare_index;
70         uint64_t pending_iteration;
71         uint64_t prepare_iteration;
72 
73         sd_event_destroy_t destroy_callback;
74         sd_event_handler_t ratelimit_expire_callback;
75 
76         LIST_FIELDS(sd_event_source, sources);
77 
78         RateLimit rate_limit;
79 
80         /* These are primarily fields relevant for time event sources, but since any event source can
81          * effectively become one when rate-limited, this is part of the common fields. */
82         unsigned earliest_index;
83         unsigned latest_index;
84 
85         union {
86                 struct {
87                         sd_event_io_handler_t callback;
88                         int fd;
89                         uint32_t events;
90                         uint32_t revents;
91                         bool registered:1;
92                         bool owned:1;
93                 } io;
94                 struct {
95                         sd_event_time_handler_t callback;
96                         usec_t next, accuracy;
97                 } time;
98                 struct {
99                         sd_event_signal_handler_t callback;
100                         struct signalfd_siginfo siginfo;
101                         int sig;
102                 } signal;
103                 struct {
104                         sd_event_child_handler_t callback;
105                         siginfo_t siginfo;
106                         pid_t pid;
107                         int options;
108                         int pidfd;
109                         bool registered:1; /* whether the pidfd is registered in the epoll */
110                         bool pidfd_owned:1; /* close pidfd when event source is freed */
111                         bool process_owned:1; /* kill+reap process when event source is freed */
112                         bool exited:1; /* true if process exited (i.e. if there's value in SIGKILLing it if we want to get rid of it) */
113                         bool waited:1; /* true if process was waited for (i.e. if there's value in waitid(P_PID)'ing it if we want to get rid of it) */
114                 } child;
115                 struct {
116                         sd_event_handler_t callback;
117                 } defer;
118                 struct {
119                         sd_event_handler_t callback;
120                 } post;
121                 struct {
122                         sd_event_handler_t callback;
123                         unsigned prioq_index;
124                 } exit;
125                 struct {
126                         sd_event_inotify_handler_t callback;
127                         uint32_t mask;
128                         struct inode_data *inode_data;
129                         LIST_FIELDS(sd_event_source, by_inode_data);
130                 } inotify;
131         };
132 };
133 
134 struct clock_data {
135         WakeupType wakeup;
136         int fd;
137 
138         /* For all clocks we maintain two priority queues each, one
139          * ordered for the earliest times the events may be
140          * dispatched, and one ordered by the latest times they must
141          * have been dispatched. The range between the top entries in
142          * the two prioqs is the time window we can freely schedule
143          * wakeups in */
144 
145         Prioq *earliest;
146         Prioq *latest;
147         usec_t next;
148 
149         bool needs_rearm:1;
150 };
151 
152 struct signal_data {
153         WakeupType wakeup;
154 
155         /* For each priority we maintain one signal fd, so that we
156          * only have to dequeue a single event per priority at a
157          * time. */
158 
159         int fd;
160         int64_t priority;
161         sigset_t sigset;
162         sd_event_source *current;
163 };
164 
165 /* A structure listing all event sources currently watching a specific inode */
166 struct inode_data {
167         /* The identifier for the inode, the combination of the .st_dev + .st_ino fields of the file */
168         ino_t ino;
169         dev_t dev;
170 
171         /* An fd of the inode to watch. The fd is kept open until the next iteration of the loop, so that we can
172          * rearrange the priority still until then, as we need the original inode to change the priority as we need to
173          * add a watch descriptor to the right inotify for the priority which we can only do if we have a handle to the
174          * original inode. We keep a list of all inode_data objects with an open fd in the to_close list (see below) of
175          * the sd-event object, so that it is efficient to close everything, before entering the next event loop
176          * iteration. */
177         int fd;
178 
179         /* The inotify "watch descriptor" */
180         int wd;
181 
182         /* The combination of the mask of all inotify watches on this inode we manage. This is also the mask that has
183          * most recently been set on the watch descriptor. */
184         uint32_t combined_mask;
185 
186         /* All event sources subscribed to this inode */
187         LIST_HEAD(sd_event_source, event_sources);
188 
189         /* The inotify object we watch this inode with */
190         struct inotify_data *inotify_data;
191 
192         /* A linked list of all inode data objects with fds to close (see above) */
193         LIST_FIELDS(struct inode_data, to_close);
194 };
195 
196 /* A structure encapsulating an inotify fd */
197 struct inotify_data {
198         WakeupType wakeup;
199 
200         /* For each priority we maintain one inotify fd, so that we only have to dequeue a single event per priority at
201          * a time */
202 
203         int fd;
204         int64_t priority;
205 
206         Hashmap *inodes; /* The inode_data structures keyed by dev+ino */
207         Hashmap *wd;     /* The inode_data structures keyed by the watch descriptor for each */
208 
209         /* The buffer we read inotify events into */
210         union inotify_event_buffer buffer;
211         size_t buffer_filled; /* fill level of the buffer */
212 
213         /* How many event sources are currently marked pending for this inotify. We won't read new events off the
214          * inotify fd as long as there are still pending events on the inotify (because we have no strategy of queuing
215          * the events locally if they can't be coalesced). */
216         unsigned n_pending;
217 
218         /* If this counter is non-zero, don't GC the inotify data object even if not used to watch any inode
219          * anymore. This is useful to pin the object for a bit longer, after the last event source needing it
220          * is gone. */
221         unsigned n_busy;
222 
223         /* A linked list of all inotify objects with data already read, that still need processing. We keep this list
224          * to make it efficient to figure out what inotify objects to process data on next. */
225         LIST_FIELDS(struct inotify_data, buffered);
226 };
227