diff options
author | Lennart Poettering <lennart@poettering.net> | 2012-01-06 23:08:54 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2012-01-06 23:08:54 +0100 |
commit | 57020a3abff20f176e9f0cbb982d7977119d6f08 (patch) | |
tree | 3b3d69307cecce0dc4ad25aa074c2a0db64bdfb6 /src/unit.c | |
parent | 73aa0c00df8b101bad4c3a038148a633df88610c (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.c | 39 |
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); |