mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 08:25:20 +09:00
sd-event struct typedefs and comments (#37790)
This commit is contained in:
@@ -42,7 +42,8 @@ typedef enum WakeupType {
|
||||
_WAKEUP_TYPE_INVALID = -EINVAL,
|
||||
} WakeupType;
|
||||
|
||||
struct inode_data;
|
||||
typedef struct inode_data InodeData;
|
||||
typedef struct inotify_data InotifyData;
|
||||
|
||||
struct sd_event_source {
|
||||
WakeupType wakeup;
|
||||
@@ -87,8 +88,8 @@ struct sd_event_source {
|
||||
int fd;
|
||||
uint32_t events;
|
||||
uint32_t revents;
|
||||
bool registered:1;
|
||||
bool owned:1;
|
||||
bool registered;
|
||||
bool owned;
|
||||
} io;
|
||||
struct {
|
||||
sd_event_time_handler_t callback;
|
||||
@@ -106,11 +107,16 @@ struct sd_event_source {
|
||||
pid_t pid;
|
||||
int options;
|
||||
int pidfd;
|
||||
bool registered:1; /* whether the pidfd is registered in the epoll */
|
||||
/* We have five bools, and we want to fit them into 4 bytes so the whole struct
|
||||
* remains 32 bytes. Thus, use bitfields for two of them and single bytes for the
|
||||
* other three. */
|
||||
bool registered; /* whether the pidfd is registered in the epoll */
|
||||
bool pidfd_owned:1; /* close pidfd when event source is freed */
|
||||
bool process_owned:1; /* kill+reap process when event source is freed */
|
||||
bool exited:1; /* true if process exited (i.e. if there's value in SIGKILLing it if we want to get rid of it) */
|
||||
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) */
|
||||
bool exited; /* true if process exited (i.e. if there's value in SIGKILLing it if
|
||||
* we want to get rid of it) */
|
||||
bool waited; /* 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) */
|
||||
} child;
|
||||
struct {
|
||||
sd_event_handler_t callback;
|
||||
@@ -125,19 +131,19 @@ struct sd_event_source {
|
||||
struct {
|
||||
sd_event_inotify_handler_t callback;
|
||||
uint32_t mask;
|
||||
struct inode_data *inode_data;
|
||||
InodeData *inode_data;
|
||||
LIST_FIELDS(sd_event_source, by_inode_data);
|
||||
} inotify;
|
||||
struct {
|
||||
int fd;
|
||||
bool registered;
|
||||
bool locked;
|
||||
bool in_write_list;
|
||||
sd_event_handler_t callback;
|
||||
void *write_buffer;
|
||||
size_t write_buffer_size;
|
||||
uint32_t events, revents;
|
||||
LIST_FIELDS(sd_event_source, write_list);
|
||||
bool registered:1;
|
||||
bool locked:1;
|
||||
bool in_write_list:1;
|
||||
} memory_pressure;
|
||||
};
|
||||
};
|
||||
@@ -157,7 +163,7 @@ struct clock_data {
|
||||
Prioq *latest;
|
||||
usec_t next;
|
||||
|
||||
bool needs_rearm:1;
|
||||
bool needs_rearm;
|
||||
};
|
||||
|
||||
struct signal_data {
|
||||
@@ -182,7 +188,7 @@ struct inode_data {
|
||||
/* An fd of the inode to watch. The fd is kept open until the next iteration of the loop, so that we can
|
||||
* rearrange the priority still until then, as we need the original inode to change the priority as we need to
|
||||
* add a watch descriptor to the right inotify for the priority which we can only do if we have a handle to the
|
||||
* original inode. We keep a list of all inode_data objects with an open fd in the to_close list (see below) of
|
||||
* original inode. We keep a list of all InodeData objects with an open fd in the to_close list (see below) of
|
||||
* the sd-event object, so that it is efficient to close everything, before entering the next event loop
|
||||
* iteration. */
|
||||
int fd;
|
||||
@@ -201,10 +207,10 @@ struct inode_data {
|
||||
LIST_HEAD(sd_event_source, event_sources);
|
||||
|
||||
/* The inotify object we watch this inode with */
|
||||
struct inotify_data *inotify_data;
|
||||
InotifyData *inotify_data;
|
||||
|
||||
/* A linked list of all inode data objects with fds to close (see above) */
|
||||
LIST_FIELDS(struct inode_data, to_close);
|
||||
LIST_FIELDS(InodeData, to_close);
|
||||
};
|
||||
|
||||
/* A structure encapsulating an inotify fd */
|
||||
@@ -217,8 +223,8 @@ struct inotify_data {
|
||||
int fd;
|
||||
int64_t priority;
|
||||
|
||||
Hashmap *inodes; /* The inode_data structures keyed by dev+ino */
|
||||
Hashmap *wd; /* The inode_data structures keyed by the watch descriptor for each */
|
||||
Hashmap *inodes; /* The InodeData structures keyed by dev+ino */
|
||||
Hashmap *wd; /* The InodeData structures keyed by the watch descriptor for each */
|
||||
|
||||
/* How many event sources are currently marked pending for this inotify. We won't read new events off the
|
||||
* inotify fd as long as there are still pending events on the inotify (because we have no strategy of queuing
|
||||
@@ -230,12 +236,18 @@ struct inotify_data {
|
||||
* is gone. */
|
||||
unsigned n_busy;
|
||||
|
||||
/* A linked list of all inotify objects with data already read, that still need processing. We keep this list
|
||||
* to make it efficient to figure out what inotify objects to process data on next. */
|
||||
LIST_FIELDS(struct inotify_data, buffered);
|
||||
/* A linked list of all InotifyData objects with data already read, that still need processing. We
|
||||
* keep this list to make it efficient to figure out what inotify objects to process data on next. */
|
||||
LIST_FIELDS(InotifyData, buffered);
|
||||
|
||||
/* The buffer we read inotify events into */
|
||||
size_t buffer_filled; /* fill level of the buffer */
|
||||
union inotify_event_buffer buffer; /* struct inotify_event in union inotify_event_buffer has flex
|
||||
* array. Hence, this must be at the end. */
|
||||
union inotify_event_buffer buffer; /* We use a union to allow type-punning. One of the variants in
|
||||
* the union — struct inotify_event — has a flex array, so C99
|
||||
* only allows this union to be used at the end of the structure.
|
||||
* The other variant in the union defines a fixed-size buffer that
|
||||
* covers the maximum size that can be used for the flex variant,
|
||||
* so in fact this field has a fixed size and could be safely
|
||||
* placed in the middle of the struct. Unfortunately, there is no
|
||||
* mechanism to let the compiler know that. */
|
||||
};
|
||||
|
||||
@@ -139,10 +139,10 @@ struct sd_event {
|
||||
Hashmap *inotify_data; /* indexed by priority */
|
||||
|
||||
/* A list of inode structures that still have an fd open, that we need to close before the next loop iteration */
|
||||
LIST_HEAD(struct inode_data, inode_data_to_close_list);
|
||||
LIST_HEAD(InodeData, inode_data_to_close_list);
|
||||
|
||||
/* A list of inotify objects that already have events buffered which aren't processed yet */
|
||||
LIST_HEAD(struct inotify_data, buffered_inotify_data_list);
|
||||
LIST_HEAD(InotifyData, buffered_inotify_data_list);
|
||||
|
||||
/* A list of memory pressure event sources that still need their subscription string written */
|
||||
LIST_HEAD(sd_event_source, memory_pressure_write_list);
|
||||
@@ -182,7 +182,7 @@ DEFINE_PRIVATE_ORIGIN_ID_HELPERS(sd_event, event);
|
||||
static thread_local sd_event *default_event = NULL;
|
||||
|
||||
static void source_disconnect(sd_event_source *s);
|
||||
static void event_gc_inode_data(sd_event *e, struct inode_data *d);
|
||||
static void event_gc_inode_data(sd_event *e, InodeData *d);
|
||||
|
||||
static sd_event* event_resolve(sd_event *e) {
|
||||
return e == SD_EVENT_DEFAULT ? default_event : e;
|
||||
@@ -1011,11 +1011,11 @@ static void source_disconnect(sd_event_source *s) {
|
||||
break;
|
||||
|
||||
case SOURCE_INOTIFY: {
|
||||
struct inode_data *inode_data;
|
||||
InodeData *inode_data;
|
||||
|
||||
inode_data = s->inotify.inode_data;
|
||||
if (inode_data) {
|
||||
struct inotify_data *inotify_data;
|
||||
InotifyData *inotify_data;
|
||||
assert_se(inotify_data = inode_data->inotify_data);
|
||||
|
||||
/* Detach this event source from the inode object */
|
||||
@@ -2103,7 +2103,7 @@ _public_ int sd_event_add_memory_pressure(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void event_free_inotify_data(sd_event *e, struct inotify_data *d) {
|
||||
static void event_free_inotify_data(sd_event *e, InotifyData *d) {
|
||||
assert(e);
|
||||
|
||||
if (!d)
|
||||
@@ -2130,13 +2130,9 @@ static void event_free_inotify_data(sd_event *e, struct inotify_data *d) {
|
||||
free(d);
|
||||
}
|
||||
|
||||
static int event_make_inotify_data(
|
||||
sd_event *e,
|
||||
int64_t priority,
|
||||
struct inotify_data **ret) {
|
||||
|
||||
static int event_make_inotify_data(sd_event *e, int64_t priority, InotifyData **ret) {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
struct inotify_data *d;
|
||||
InotifyData *d;
|
||||
int r;
|
||||
|
||||
assert(e);
|
||||
@@ -2154,11 +2150,11 @@ static int event_make_inotify_data(
|
||||
|
||||
fd = fd_move_above_stdio(fd);
|
||||
|
||||
d = new(struct inotify_data, 1);
|
||||
d = new(InotifyData, 1);
|
||||
if (!d)
|
||||
return -ENOMEM;
|
||||
|
||||
*d = (struct inotify_data) {
|
||||
*d = (InotifyData) {
|
||||
.wakeup = WAKEUP_INOTIFY_DATA,
|
||||
.fd = TAKE_FD(fd),
|
||||
.priority = priority,
|
||||
@@ -2191,7 +2187,7 @@ static int event_make_inotify_data(
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int inode_data_compare(const struct inode_data *x, const struct inode_data *y) {
|
||||
static int inode_data_compare(const InodeData *x, const InodeData *y) {
|
||||
int r;
|
||||
|
||||
assert(x);
|
||||
@@ -2204,19 +2200,16 @@ static int inode_data_compare(const struct inode_data *x, const struct inode_dat
|
||||
return CMP(x->ino, y->ino);
|
||||
}
|
||||
|
||||
static void inode_data_hash_func(const struct inode_data *d, struct siphash *state) {
|
||||
static void inode_data_hash_func(const InodeData *d, struct siphash *state) {
|
||||
assert(d);
|
||||
|
||||
siphash24_compress_typesafe(d->dev, state);
|
||||
siphash24_compress_typesafe(d->ino, state);
|
||||
}
|
||||
|
||||
DEFINE_PRIVATE_HASH_OPS(inode_data_hash_ops, struct inode_data, inode_data_hash_func, inode_data_compare);
|
||||
|
||||
static void event_free_inode_data(
|
||||
sd_event *e,
|
||||
struct inode_data *d) {
|
||||
DEFINE_PRIVATE_HASH_OPS(inode_data_hash_ops, InodeData, inode_data_hash_func, inode_data_compare);
|
||||
|
||||
static void event_free_inode_data(sd_event *e, InodeData *d) {
|
||||
assert(e);
|
||||
|
||||
if (!d)
|
||||
@@ -2252,16 +2245,14 @@ static void event_free_inode_data(
|
||||
free(d);
|
||||
}
|
||||
|
||||
static void event_gc_inotify_data(
|
||||
sd_event *e,
|
||||
struct inotify_data *d) {
|
||||
|
||||
static void event_gc_inotify_data(sd_event *e, InotifyData *d) {
|
||||
assert(e);
|
||||
|
||||
/* GCs the inotify data object if we don't need it anymore. That's the case if we don't want to watch
|
||||
* any inode with it anymore, which in turn happens if no event source of this priority is interested
|
||||
* in any inode any longer. That said, we maintain an extra busy counter: if non-zero we'll delay GC
|
||||
* (under the expectation that the GC is called again once the counter is decremented). */
|
||||
/* Collects the InotifyData object if we don't need it anymore. That's the case if we don't want to
|
||||
* watch any inode with it anymore, which in turn happens if no event source of this priority is
|
||||
* interested in any inode any longer. That said, we maintain an extra busy counter: if non-zero
|
||||
* we'll delay GC (under the expectation that the GC is called again once the counter is
|
||||
* decremented). */
|
||||
|
||||
if (!d)
|
||||
return;
|
||||
@@ -2275,11 +2266,8 @@ static void event_gc_inotify_data(
|
||||
event_free_inotify_data(e, d);
|
||||
}
|
||||
|
||||
static void event_gc_inode_data(
|
||||
sd_event *e,
|
||||
struct inode_data *d) {
|
||||
|
||||
struct inotify_data *inotify_data;
|
||||
static void event_gc_inode_data(sd_event *e, InodeData *d) {
|
||||
InotifyData *inotify_data;
|
||||
|
||||
assert(e);
|
||||
|
||||
@@ -2297,18 +2285,18 @@ static void event_gc_inode_data(
|
||||
|
||||
static int event_make_inode_data(
|
||||
sd_event *e,
|
||||
struct inotify_data *inotify_data,
|
||||
InotifyData *inotify_data,
|
||||
dev_t dev,
|
||||
ino_t ino,
|
||||
struct inode_data **ret) {
|
||||
InodeData **ret) {
|
||||
|
||||
struct inode_data *d, key;
|
||||
InodeData *d, key;
|
||||
int r;
|
||||
|
||||
assert(e);
|
||||
assert(inotify_data);
|
||||
|
||||
key = (struct inode_data) {
|
||||
key = (InodeData) {
|
||||
.ino = ino,
|
||||
.dev = dev,
|
||||
};
|
||||
@@ -2325,11 +2313,11 @@ static int event_make_inode_data(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
d = new(struct inode_data, 1);
|
||||
d = new(InodeData, 1);
|
||||
if (!d)
|
||||
return -ENOMEM;
|
||||
|
||||
*d = (struct inode_data) {
|
||||
*d = (InodeData) {
|
||||
.dev = dev,
|
||||
.ino = ino,
|
||||
.wd = -1,
|
||||
@@ -2349,7 +2337,7 @@ static int event_make_inode_data(
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint32_t inode_data_determine_mask(struct inode_data *d) {
|
||||
static uint32_t inode_data_determine_mask(InodeData *d) {
|
||||
bool excl_unlink = true;
|
||||
uint32_t combined = 0;
|
||||
|
||||
@@ -2374,7 +2362,7 @@ static uint32_t inode_data_determine_mask(struct inode_data *d) {
|
||||
return (combined & ~(IN_ONESHOT|IN_DONT_FOLLOW|IN_ONLYDIR|IN_EXCL_UNLINK)) | (excl_unlink ? IN_EXCL_UNLINK : 0);
|
||||
}
|
||||
|
||||
static int inode_data_realize_watch(sd_event *e, struct inode_data *d) {
|
||||
static int inode_data_realize_watch(sd_event *e, InodeData *d) {
|
||||
uint32_t combined_mask;
|
||||
int wd, r;
|
||||
|
||||
@@ -2431,8 +2419,8 @@ static int event_add_inotify_fd_internal(
|
||||
|
||||
_cleanup_close_ int donated_fd = donate ? fd : -EBADF;
|
||||
_cleanup_(source_freep) sd_event_source *s = NULL;
|
||||
struct inotify_data *inotify_data = NULL;
|
||||
struct inode_data *inode_data = NULL;
|
||||
InotifyData *inotify_data = NULL;
|
||||
InodeData *inode_data = NULL;
|
||||
struct stat st;
|
||||
int r;
|
||||
|
||||
@@ -2744,8 +2732,8 @@ _public_ int sd_event_source_get_priority(sd_event_source *s, int64_t *ret) {
|
||||
|
||||
_public_ int sd_event_source_set_priority(sd_event_source *s, int64_t priority) {
|
||||
bool rm_inotify = false, rm_inode = false;
|
||||
struct inotify_data *new_inotify_data = NULL;
|
||||
struct inode_data *new_inode_data = NULL;
|
||||
InotifyData *new_inotify_data = NULL;
|
||||
InodeData *new_inode_data = NULL;
|
||||
int r;
|
||||
|
||||
assert_return(s, -EINVAL);
|
||||
@@ -2756,7 +2744,7 @@ _public_ int sd_event_source_set_priority(sd_event_source *s, int64_t priority)
|
||||
return 0;
|
||||
|
||||
if (s->type == SOURCE_INOTIFY) {
|
||||
struct inode_data *old_inode_data;
|
||||
InodeData *old_inode_data;
|
||||
|
||||
assert(s->inotify.inode_data);
|
||||
old_inode_data = s->inotify.inode_data;
|
||||
@@ -3840,7 +3828,7 @@ static int process_signal(sd_event *e, struct signal_data *d, uint32_t events, i
|
||||
}
|
||||
}
|
||||
|
||||
static int event_inotify_data_read(sd_event *e, struct inotify_data *d, uint32_t revents, int64_t threshold) {
|
||||
static int event_inotify_data_read(sd_event *e, InotifyData *d, uint32_t revents, int64_t threshold) {
|
||||
ssize_t n;
|
||||
|
||||
assert(e);
|
||||
@@ -3874,7 +3862,7 @@ static int event_inotify_data_read(sd_event *e, struct inotify_data *d, uint32_t
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void event_inotify_data_drop(sd_event *e, struct inotify_data *d, size_t sz) {
|
||||
static void event_inotify_data_drop(sd_event *e, InotifyData *d, size_t sz) {
|
||||
assert(e);
|
||||
assert(d);
|
||||
assert(sz <= d->buffer_filled);
|
||||
@@ -3890,7 +3878,7 @@ static void event_inotify_data_drop(sd_event *e, struct inotify_data *d, size_t
|
||||
LIST_REMOVE(buffered, e->buffered_inotify_data_list, d);
|
||||
}
|
||||
|
||||
static int event_inotify_data_process(sd_event *e, struct inotify_data *d) {
|
||||
static int event_inotify_data_process(sd_event *e, InotifyData *d) {
|
||||
int r;
|
||||
|
||||
assert(e);
|
||||
@@ -3912,7 +3900,7 @@ static int event_inotify_data_process(sd_event *e, struct inotify_data *d) {
|
||||
return -EIO;
|
||||
|
||||
if (d->buffer.ev.mask & IN_Q_OVERFLOW) {
|
||||
struct inode_data *inode_data;
|
||||
InodeData *inode_data;
|
||||
|
||||
/* The queue overran, let's pass this event to all event sources connected to this inotify
|
||||
* object */
|
||||
@@ -3928,7 +3916,7 @@ static int event_inotify_data_process(sd_event *e, struct inotify_data *d) {
|
||||
return r;
|
||||
}
|
||||
} else {
|
||||
struct inode_data *inode_data;
|
||||
InodeData *inode_data;
|
||||
|
||||
/* Find the inode object for this watch descriptor. If IN_IGNORED is set we also remove it from
|
||||
* our watch descriptor table. */
|
||||
@@ -4212,7 +4200,7 @@ static int source_dispatch(sd_event_source *s) {
|
||||
|
||||
case SOURCE_INOTIFY: {
|
||||
struct sd_event *e = s->event;
|
||||
struct inotify_data *d;
|
||||
InotifyData *d;
|
||||
size_t sz;
|
||||
|
||||
assert(s->inotify.inode_data);
|
||||
@@ -4387,7 +4375,7 @@ static int process_watchdog(sd_event *e) {
|
||||
}
|
||||
|
||||
static void event_close_inode_data_fds(sd_event *e) {
|
||||
struct inode_data *d;
|
||||
InodeData *d;
|
||||
|
||||
assert(e);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user