summaryrefslogtreecommitdiff
path: root/src/unit.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2012-01-06 23:08:54 +0100
committerLennart Poettering <lennart@poettering.net>2012-01-06 23:08:54 +0100
commit57020a3abff20f176e9f0cbb982d7977119d6f08 (patch)
tree3b3d69307cecce0dc4ad25aa074c2a0db64bdfb6 /src/unit.c
parent73aa0c00df8b101bad4c3a038148a633df88610c (diff)
unit: properly update references to units which are merged
When we merge units that some kind of object points to, those pointers might become invalidated, and needs to be updated. Introduce a UnitRef struct which links up all the unit references, to ensure corrected references. At the same time, drop configured_sockets in the Service object, and replace it by proper UNIT_TRIGGERS resp. UNIT_TRIGGERED_BY dependencies, which allow us to simplify a lot of code.
Diffstat (limited to 'src/unit.c')
-rw-r--r--src/unit.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/src/unit.c b/src/unit.c
index 8630c3c59d..3b476a8e02 100644
--- a/src/unit.c
+++ b/src/unit.c
@@ -377,12 +377,15 @@ void unit_free(Unit *u) {
free(u->meta.description);
free(u->meta.fragment_path);
+ free(u->meta.instance);
set_free_free(u->meta.names);
condition_free_list(u->meta.conditions);
- free(u->meta.instance);
+ while (u->meta.refs)
+ unit_ref_unset(u->meta.refs);
+
free(u);
}
@@ -498,6 +501,10 @@ int unit_merge(Unit *u, Unit *other) {
/* Merge names */
merge_names(u, other);
+ /* Redirect all references */
+ while (other->meta.refs)
+ unit_ref_set(other->meta.refs, u);
+
/* Merge dependencies */
for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
merge_dependencies(u, other, d);
@@ -1530,7 +1537,9 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen
[UNIT_AFTER] = UNIT_BEFORE,
[UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID,
[UNIT_REFERENCES] = UNIT_REFERENCED_BY,
- [UNIT_REFERENCED_BY] = UNIT_REFERENCES
+ [UNIT_REFERENCED_BY] = UNIT_REFERENCES,
+ [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY,
+ [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS
};
int r, q = 0, v = 0, w = 0;
@@ -2592,6 +2601,28 @@ UnitFileState unit_get_unit_file_state(Unit *u) {
return u->meta.unit_file_state;
}
+Unit* unit_ref_set(UnitRef *ref, Unit *u) {
+ assert(ref);
+ assert(u);
+
+ if (ref->unit)
+ unit_ref_unset(ref);
+
+ ref->unit = u;
+ LIST_PREPEND(UnitRef, refs, u->meta.refs, ref);
+ return u;
+}
+
+void unit_ref_unset(UnitRef *ref) {
+ assert(ref);
+
+ if (!ref->unit)
+ return;
+
+ LIST_REMOVE(UnitRef, refs, ref->unit->meta.refs, ref);
+ ref->unit = NULL;
+}
+
static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = {
[UNIT_STUB] = "stub",
[UNIT_LOADED] = "loaded",
@@ -2630,7 +2661,9 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
[UNIT_AFTER] = "After",
[UNIT_REFERENCES] = "References",
[UNIT_REFERENCED_BY] = "ReferencedBy",
- [UNIT_ON_FAILURE] = "OnFailure"
+ [UNIT_ON_FAILURE] = "OnFailure",
+ [UNIT_TRIGGERS] = "Triggers",
+ [UNIT_TRIGGERED_BY] = "TriggeredBy"
};
DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);