chiark / gitweb /
unit: free data from merged unit when we don't need it anymore
[elogind.git] / unit.c
diff --git a/unit.c b/unit.c
index 392be841d9866529e2941d20019d27d6b3dc28b9..d4f0538b36edc901a1b86336d4e226b6a515a685 100644 (file)
--- a/unit.c
+++ b/unit.c
@@ -219,6 +219,7 @@ int unit_set_description(Unit *u, const char *description) {
 
 void unit_add_to_load_queue(Unit *u) {
         assert(u);
+        assert(u->meta.type != _UNIT_TYPE_INVALID);
 
         if (u->meta.load_state != UNIT_STUB || u->meta.in_load_queue)
                 return;
@@ -239,6 +240,7 @@ void unit_add_to_cleanup_queue(Unit *u) {
 
 void unit_add_to_dbus_queue(Unit *u) {
         assert(u);
+        assert(u->meta.type != _UNIT_TYPE_INVALID);
 
         if (u->meta.load_state == UNIT_STUB || u->meta.in_dbus_queue || set_isempty(u->meta.manager->subscribed))
                 return;
@@ -409,6 +411,12 @@ int unit_merge(Unit *u, Unit *other) {
             other->meta.load_state != UNIT_FAILED)
                 return -EEXIST;
 
+        if (other->meta.job)
+                return -EEXIST;
+
+        if (unit_active_state(other) != UNIT_INACTIVE)
+                return -EEXIST;
+
         /* Merge names */
         merge_names(u, other);
 
@@ -416,11 +424,16 @@ int unit_merge(Unit *u, Unit *other) {
         for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
                 merge_dependencies(u, other, d);
 
-        unit_add_to_dbus_queue(u);
-
         other->meta.load_state = UNIT_MERGED;
         other->meta.merged_into = u;
 
+        /* If there is still some data attached to the other node, we
+         * don't need it anymore, and can free it. */
+        if (other->meta.load_state != UNIT_STUB)
+                if (UNIT_VTABLE(other)->done)
+                        UNIT_VTABLE(other)->done(other);
+
+        unit_add_to_dbus_queue(u);
         unit_add_to_cleanup_queue(other);
 
         return 0;