sd-event struct typedefs and comments (#37790)

This commit is contained in:
Luca Boccassi
2025-07-03 22:22:40 +01:00
committed by GitHub
2 changed files with 75 additions and 75 deletions

View File

@@ -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. */
};

View File

@@ -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);