Merge pull request #28832 from dtardon/list-clear

Add LIST_CLEAR() helper that empties the list
This commit is contained in:
Luca Boccassi
2023-08-17 16:27:43 +01:00
committed by GitHub
22 changed files with 72 additions and 114 deletions
+12
View File
@@ -192,6 +192,18 @@
_p; \
})
#define LIST_CLEAR(name, head, free_func) \
_LIST_CLEAR(name, head, free_func, UNIQ_T(elem, UNIQ))
/* Clear the list, destroing each element with free_func */
#define _LIST_CLEAR(name, head, free_func, elem) \
({ \
typeof(head) elem; \
while ((elem = LIST_POP(name, head))) \
free_func(elem); \
head; \
})
/* Now include "macro.h", because we want our definition of assert() which the macros above use. We include
* it down here instead of up top, since macro.h pulls in log.h which in turn needs our own definitions. */
#include "macro.h"
+1 -5
View File
@@ -247,11 +247,7 @@ void cgroup_context_remove_bpf_foreign_program(CGroupContext *c, CGroupBPFForeig
void cgroup_context_remove_socket_bind(CGroupSocketBindItem **head) {
assert(head);
while (*head) {
CGroupSocketBindItem *h = *head;
LIST_REMOVE(socket_bind_items, *head, h);
free(h);
}
LIST_CLEAR(socket_bind_items, *head, free);
}
void cgroup_context_done(CGroupContext *c) {
+1 -2
View File
@@ -6326,8 +6326,7 @@ void exec_command_done_array(ExecCommand *c, size_t n) {
ExecCommand* exec_command_free_list(ExecCommand *c) {
ExecCommand *i;
while ((i = c)) {
LIST_REMOVE(command, c, i);
while ((i = LIST_POP(command, c))) {
exec_command_done(i);
free(i);
}
+7 -16
View File
@@ -1257,10 +1257,8 @@ static unsigned manager_dispatch_release_resources_queue(Manager *m) {
assert(m);
while ((u = m->release_resources_queue)) {
while ((u = LIST_POP(release_resources_queue, m->release_resources_queue))) {
assert(u->in_release_resources_queue);
LIST_REMOVE(release_resources_queue, m->release_resources_queue, u);
u->in_release_resources_queue = false;
n++;
@@ -1364,12 +1362,11 @@ static unsigned manager_dispatch_gc_unit_queue(Manager *m) {
gc_marker = m->gc_marker;
while ((u = m->gc_unit_queue)) {
while ((u = LIST_POP(gc_queue, m->gc_unit_queue))) {
assert(u->in_gc_queue);
unit_gc_sweep(u, gc_marker);
LIST_REMOVE(gc_queue, m->gc_unit_queue, u);
u->in_gc_queue = false;
n++;
@@ -1392,10 +1389,8 @@ static unsigned manager_dispatch_gc_job_queue(Manager *m) {
assert(m);
while ((j = m->gc_job_queue)) {
while ((j = LIST_POP(gc_queue, m->gc_job_queue))) {
assert(j->in_gc_queue);
LIST_REMOVE(gc_queue, m->gc_job_queue, j);
j->in_gc_queue = false;
n++;
@@ -1459,11 +1454,10 @@ static unsigned manager_dispatch_stop_when_unneeded_queue(Manager *m) {
assert(m);
while ((u = m->stop_when_unneeded_queue)) {
while ((u = LIST_POP(stop_when_unneeded_queue, m->stop_when_unneeded_queue))) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
assert(u->in_stop_when_unneeded_queue);
LIST_REMOVE(stop_when_unneeded_queue, m->stop_when_unneeded_queue, u);
u->in_stop_when_unneeded_queue = false;
n++;
@@ -1500,12 +1494,11 @@ static unsigned manager_dispatch_start_when_upheld_queue(Manager *m) {
assert(m);
while ((u = m->start_when_upheld_queue)) {
while ((u = LIST_POP(start_when_upheld_queue, m->start_when_upheld_queue))) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
Unit *culprit = NULL;
assert(u->in_start_when_upheld_queue);
LIST_REMOVE(start_when_upheld_queue, m->start_when_upheld_queue, u);
u->in_start_when_upheld_queue = false;
n++;
@@ -1542,12 +1535,11 @@ static unsigned manager_dispatch_stop_when_bound_queue(Manager *m) {
assert(m);
while ((u = m->stop_when_bound_queue)) {
while ((u = LIST_POP(stop_when_bound_queue, m->stop_when_bound_queue))) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
Unit *culprit = NULL;
assert(u->in_stop_when_bound_queue);
LIST_REMOVE(stop_when_bound_queue, m->stop_when_bound_queue, u);
u->in_stop_when_bound_queue = false;
n++;
@@ -2177,13 +2169,12 @@ static int manager_dispatch_target_deps_queue(Manager *m) {
assert(m);
while ((u = m->target_deps_queue)) {
while ((u = LIST_POP(target_deps_queue, m->target_deps_queue))) {
_cleanup_free_ Unit **targets = NULL;
int n_targets;
assert(u->in_target_deps_queue);
LIST_REMOVE(target_deps_queue, u->manager->target_deps_queue, u);
u->in_target_deps_queue = false;
/* Take an "atomic" snapshot of dependencies here, as the call below will likely modify the
+1 -2
View File
@@ -288,9 +288,8 @@ void path_free_specs(Path *p) {
assert(p);
while ((s = p->specs)) {
while ((s = LIST_POP(spec, p->specs))) {
path_spec_unwatch(s);
LIST_REMOVE(spec, p->specs, s);
path_spec_done(s);
free(s);
}
+1 -6
View File
@@ -134,14 +134,9 @@ SocketPort *socket_port_free(SocketPort *p) {
}
void socket_free_ports(Socket *s) {
SocketPort *p;
assert(s);
while ((p = s->ports)) {
LIST_REMOVE(port, s->ports, p);
socket_port_free(p);
}
LIST_CLEAR(port, s->ports, socket_port_free);
}
static void socket_done(Unit *u) {
+1 -2
View File
@@ -51,8 +51,7 @@ void timer_free_values(Timer *t) {
assert(t);
while ((v = t->values)) {
LIST_REMOVE(value, t->values, v);
while ((v = LIST_POP(value, t->values))) {
calendar_spec_free(v->calendar_spec);
free(v);
}
+3 -5
View File
@@ -345,13 +345,11 @@ int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, s
}
static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) {
struct sd_dhcp_raw_option *option;
assert(lease);
while (lease->private_options) {
struct sd_dhcp_raw_option *option = lease->private_options;
LIST_REMOVE(options, lease->private_options, option);
while ((option = LIST_POP(options, lease->private_options))) {
free(option->data);
free(option);
}
+2 -13
View File
@@ -99,19 +99,8 @@ static sd_radv *radv_free(sd_radv *ra) {
if (!ra)
return NULL;
while (ra->prefixes) {
sd_radv_prefix *p = ra->prefixes;
LIST_REMOVE(prefix, ra->prefixes, p);
sd_radv_prefix_unref(p);
}
while (ra->route_prefixes) {
sd_radv_route_prefix *p = ra->route_prefixes;
LIST_REMOVE(prefix, ra->route_prefixes, p);
sd_radv_route_prefix_unref(p);
}
LIST_CLEAR(prefix, ra->prefixes, sd_radv_prefix_unref);
LIST_CLEAR(prefix, ra->route_prefixes, sd_radv_route_prefix_unref);
free(ra->rdnss);
free(ra->dnssl);
+3 -6
View File
@@ -907,8 +907,7 @@ static void manager_gc(Manager *m, bool drop_not_started) {
assert(m);
while ((seat = m->seat_gc_queue)) {
LIST_REMOVE(gc_queue, m->seat_gc_queue, seat);
while ((seat = LIST_POP(gc_queue, m->seat_gc_queue))) {
seat->in_gc_queue = false;
if (seat_may_gc(seat, drop_not_started)) {
@@ -917,8 +916,7 @@ static void manager_gc(Manager *m, bool drop_not_started) {
}
}
while ((session = m->session_gc_queue)) {
LIST_REMOVE(gc_queue, m->session_gc_queue, session);
while ((session = LIST_POP(gc_queue, m->session_gc_queue))) {
session->in_gc_queue = false;
/* First, if we are not closing yet, initiate stopping. */
@@ -934,8 +932,7 @@ static void manager_gc(Manager *m, bool drop_not_started) {
}
}
while ((user = m->user_gc_queue)) {
LIST_REMOVE(gc_queue, m->user_gc_queue, user);
while ((user = LIST_POP(gc_queue, m->user_gc_queue))) {
user->in_gc_queue = false;
/* First step: queue stop jobs */
+1 -2
View File
@@ -254,8 +254,7 @@ static void manager_gc(Manager *m, bool drop_not_started) {
assert(m);
while ((machine = m->machine_gc_queue)) {
LIST_REMOVE(gc_queue, m->machine_gc_queue, machine);
while ((machine = LIST_POP(gc_queue, m->machine_gc_queue))) {
machine->in_gc_queue = false;
/* First, if we are not closing yet, initiate stopping */
+1 -6
View File
@@ -35,14 +35,9 @@ static void wireguard_resolve_endpoints(NetDev *netdev);
static int peer_resolve_endpoint(WireguardPeer *peer);
static void wireguard_peer_clear_ipmasks(WireguardPeer *peer) {
WireguardIPmask *mask;
assert(peer);
while ((mask = peer->ipmasks)) {
LIST_REMOVE(ipmasks, peer->ipmasks, mask);
free(mask);
}
LIST_CLEAR(ipmasks, peer->ipmasks, free);
}
static WireguardPeer* wireguard_peer_free(WireguardPeer *peer) {
+1 -6
View File
@@ -73,12 +73,7 @@ int expose_port_parse(ExposePort **l, const char *s) {
}
void expose_port_free_all(ExposePort *p) {
while (p) {
ExposePort *q = p;
LIST_REMOVE(ports, p, q);
free(q);
}
LIST_CLEAR(ports, p, free);
}
int expose_port_flush(FirewallContext **fw_ctx, ExposePort* l, int af, union in_addr_union *exposed) {
+1 -2
View File
@@ -257,8 +257,7 @@ static void context_save_and_clear(Context *c) {
assert(c);
while ((i = c->write_queue)) {
LIST_REMOVE(queue, c->write_queue, i);
while ((i = LIST_POP(queue, c->write_queue))) {
(void) save_state_write_one(i);
write_queue_item_free(i);
}
+1 -4
View File
@@ -204,8 +204,6 @@ typedef struct AsyncPolkitQuery {
} AsyncPolkitQuery;
static AsyncPolkitQuery *async_polkit_query_free(AsyncPolkitQuery *q) {
AsyncPolkitQueryAction *a;
if (!q)
return NULL;
@@ -220,8 +218,7 @@ static AsyncPolkitQuery *async_polkit_query_free(AsyncPolkitQuery *q) {
sd_event_source_disable_unref(q->defer_event_source);
while ((a = LIST_POP(authorized, q->authorized_actions)))
async_polkit_query_action_free(a);
LIST_CLEAR(authorized, q->authorized_actions, async_polkit_query_action_free);
async_polkit_query_action_free(q->denied_action);
async_polkit_query_action_free(q->error_action);
+1 -2
View File
@@ -3689,8 +3689,7 @@ bool dissected_image_verity_sig_ready(const DissectedImage *image, PartitionDesi
MountOptions* mount_options_free_all(MountOptions *options) {
MountOptions *m;
while ((m = options)) {
LIST_REMOVE(mount_options, options, m);
while ((m = LIST_POP(mount_options, options))) {
free(m->options);
free(m);
}
+2 -5
View File
@@ -132,12 +132,9 @@ OpenFile *open_file_free(OpenFile *of) {
}
void open_file_free_many(OpenFile **head) {
OpenFile *of;
assert(head);
while ((of = *head)) {
LIST_REMOVE(open_files, *head, of);
of = open_file_free(of);
}
LIST_CLEAR(open_files, *head, open_file_free);
}
static const char * const open_file_flags_table[_OPENFILE_MAX] = {
+1 -6
View File
@@ -473,12 +473,7 @@ static void varlink_clear(Varlink *v) {
v->pushed_fds = mfree(v->pushed_fds);
v->n_pushed_fds = 0;
while (v->output_queue) {
VarlinkJsonQueueItem *q = v->output_queue;
LIST_REMOVE(queue, v->output_queue, q);
varlink_json_queue_item_free(q);
}
LIST_CLEAR(queue, v->output_queue, varlink_json_queue_item_free);
v->output_queue_tail = NULL;
v->event = sd_event_unref(v->event);
+4 -14
View File
@@ -278,25 +278,15 @@ typedef struct UnitStatusInfo {
LIST_HEAD(ExecStatusInfo, exec_status_info_list);
} UnitStatusInfo;
static void unit_status_info_free(UnitStatusInfo *info) {
ExecStatusInfo *p;
UnitCondition *c;
static void unit_status_info_done(UnitStatusInfo *info) {
strv_free(info->documentation);
strv_free(info->dropin_paths);
strv_free(info->triggered_by);
strv_free(info->triggers);
strv_free(info->listen);
while ((c = info->conditions)) {
LIST_REMOVE(conditions, info->conditions, c);
unit_condition_free(c);
}
while ((p = info->exec_status_info_list)) {
LIST_REMOVE(exec_status_info_list, info->exec_status_info_list, p);
exec_status_info_free(p);
}
LIST_CLEAR(conditions, info->conditions, unit_condition_free);
LIST_CLEAR(exec_status_info_list, info->exec_status_info_list, exec_status_info_free);
}
static void format_active_state(const char *active_state, const char **active_on, const char **active_off) {
@@ -2065,7 +2055,7 @@ static int show_one(
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_set_free_ Set *found_properties = NULL;
_cleanup_(unit_status_info_free) UnitStatusInfo info = {
_cleanup_(unit_status_info_done) UnitStatusInfo info = {
.runtime_max_sec = USEC_INFINITY,
.memory_current = UINT64_MAX,
.memory_high = CGROUP_LIMIT_MAX,
+1 -4
View File
@@ -36,10 +36,7 @@ struct PatternElement {
};
static PatternElement *pattern_element_free_all(PatternElement *e) {
PatternElement *p;
while ((p = LIST_POP(elements, e)))
free(p);
LIST_CLEAR(elements, e, free);
return NULL;
}
+25
View File
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "alloc-util.h"
#include "list.h"
int main(int argc, const char *argv[]) {
@@ -254,5 +255,29 @@ int main(int argc, const char *argv[]) {
assert_se(LIST_POP(item_list, head) == items + 0);
assert_se(LIST_POP(item_list, head) == NULL);
/* No-op on an empty list */
LIST_CLEAR(item_list, head, free);
/* A non-empty list is cleared */
assert_se(LIST_PREPEND(item_list, head, new0(list_item, 1)));
assert_se(LIST_PREPEND(item_list, head, new0(list_item, 1)));
LIST_CLEAR(item_list, head, free);
assert_se(head == NULL);
/* A list can be cleared partially */
assert_se(LIST_PREPEND(item_list, head, new0(list_item, 1)));
assert_se(LIST_PREPEND(item_list, head, new0(list_item, 1)));
assert_se(LIST_PREPEND(item_list, head, items + 0) == items + 0);
LIST_CLEAR(item_list, head->item_list_next, free);
assert_se(head == items + 0);
assert_se(head->item_list_next == NULL);
return 0;
}
+1 -6
View File
@@ -115,8 +115,6 @@ static UnitStatusInfo *unit_status_info_free(UnitStatusInfo *p) {
DEFINE_TRIVIAL_CLEANUP_FUNC(UnitStatusInfo*, unit_status_info_free);
static void context_clear(Context *c) {
UnitStatusInfo *p;
assert(c);
free(c->zone);
@@ -125,10 +123,7 @@ static void context_clear(Context *c) {
sd_bus_slot_unref(c->slot_job_removed);
while ((p = c->units)) {
LIST_REMOVE(units, c->units, p);
unit_status_info_free(p);
}
LIST_CLEAR(units, c->units, unit_status_info_free);
}
static int context_add_ntp_service(Context *c, const char *s, const char *source) {