LIST_PREPEND(gc_queue, m->manager->machine_gc_queue, m);
m->in_gc_queue = true;
+
+ manager_enqueue_gc(m->manager);
}
MachineState machine_get_state(Machine *s) {
return false;
}
+
+void manager_gc(Manager *m, bool drop_not_started) {
+ Machine *machine;
+
+ assert(m);
+
+ while ((machine = LIST_POP(gc_queue, m->machine_gc_queue))) {
+ machine->in_gc_queue = false;
+
+ /* First, if we are not closing yet, initiate stopping */
+ if (machine_may_gc(machine, drop_not_started) &&
+ machine_get_state(machine) != MACHINE_CLOSING)
+ machine_stop(machine);
+
+ /* Now, the stop probably made this referenced
+ * again, but if it didn't, then it's time to let it
+ * go entirely. */
+ if (machine_may_gc(machine, drop_not_started)) {
+ machine_finalize(machine);
+ machine_free(machine);
+ }
+ }
+}
+
+static int on_deferred_gc(sd_event_source *s, void *userdata) {
+ manager_gc(userdata, /* drop_not_started= */ true);
+ return 0;
+}
+
+void manager_enqueue_gc(Manager *m) {
+ int r;
+
+ assert(m);
+
+ if (m->deferred_gc_event_source) {
+ r = sd_event_source_set_enabled(m->deferred_gc_event_source, SD_EVENT_ONESHOT);
+ if (r < 0)
+ log_warning_errno(r, "Failed to enable GC event source, ignoring: %m");
+
+ return;
+ }
+
+ r = sd_event_add_defer(m->event, &m->deferred_gc_event_source, on_deferred_gc, m);
+ if (r < 0)
+ return (void) log_warning_errno(r, "Failed to allocate GC event source, ignoring: %m");
+
+ r = sd_event_source_set_priority(m->deferred_gc_event_source, SD_EVENT_PRIORITY_IDLE);
+ if (r < 0)
+ log_warning_errno(r, "Failed to tweak priority of event source, ignoring: %m");
+
+ (void) sd_event_source_set_description(m->deferred_gc_event_source, "deferred-gc");
+}
sd_event_source_unref(m->nscd_cache_flush_event);
#endif
+ sd_event_source_disable_unref(m->deferred_gc_event_source);
+
hashmap_free(m->polkit_registry);
manager_varlink_done(m);
return 0;
}
-static void manager_gc(Manager *m, bool drop_not_started) {
- Machine *machine;
-
- assert(m);
-
- while ((machine = LIST_POP(gc_queue, m->machine_gc_queue))) {
- machine->in_gc_queue = false;
-
- /* First, if we are not closing yet, initiate stopping */
- if (machine_may_gc(machine, drop_not_started) &&
- machine_get_state(machine) != MACHINE_CLOSING)
- machine_stop(machine);
-
- /* Now, the stop probably made this referenced
- * again, but if it didn't, then it's time to let it
- * go entirely. */
- if (machine_may_gc(machine, drop_not_started)) {
- machine_finalize(machine);
- machine_free(machine);
- }
- }
-}
-
static int manager_startup(Manager *m) {
Machine *machine;
int r;
if (!hashmap_isempty(m->polkit_registry))
return false;
- manager_gc(m, true);
-
return hashmap_isempty(m->machines);
}
Hashmap *machine_units;
Hashmap *machine_leaders;
+ sd_event_source *deferred_gc_event_source;
+
Hashmap *polkit_registry;
Hashmap *image_cache;
int manager_find_machine_for_uid(Manager *m, uid_t host_uid, Machine **ret_machine, uid_t *ret_internal_uid);
int manager_find_machine_for_gid(Manager *m, gid_t host_gid, Machine **ret_machine, gid_t *ret_internal_gid);
+
+void manager_gc(Manager *m, bool drop_not_started);
+void manager_enqueue_gc(Manager *m);