[systemd-devel] [PATCH 17/26] unit: place reservations before merging other's dependencies
Michal Schmidt
mschmidt at redhat.com
Thu Oct 16 00:50:55 PDT 2014
With the hashmap implementation that uses chaining the reservations
merely ensure that the merging won't result in long bucket chains.
With a future alternative implementation it will additionally reserve
memory to make sure the merging won't fail.
---
src/core/unit.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/src/core/unit.c b/src/core/unit.c
index 0389e6e..41b9ba4 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -585,6 +585,27 @@ static void merge_names(Unit *u, Unit *other) {
assert_se(hashmap_replace(u->manager->units, t, u) == 0);
}
+static int reserve_dependencies(Unit *u, Unit *other, UnitDependency d) {
+ unsigned n_reserve;
+
+ assert(u);
+ assert(other);
+ assert(d < _UNIT_DEPENDENCY_MAX);
+
+ /*
+ * If u does not have this dependency set allocated, there is no need
+ * to reserve anything. In that case other's set will be transfered
+ * as a whole to u by complete_move().
+ */
+ if (!u->dependencies[d])
+ return 0;
+
+ /* merge_dependencies() will skip a u-on-u dependency */
+ n_reserve = set_size(other->dependencies[d]) - !!set_get(other->dependencies[d], u);
+
+ return set_reserve(u->dependencies[d], n_reserve);
+}
+
static void merge_dependencies(Unit *u, Unit *other, const char *other_id, UnitDependency d) {
Iterator i;
Unit *back;
@@ -627,6 +648,7 @@ static void merge_dependencies(Unit *u, Unit *other, const char *other_id, UnitD
int unit_merge(Unit *u, Unit *other) {
UnitDependency d;
const char *other_id = NULL;
+ int r;
assert(u);
assert(other);
@@ -660,6 +682,17 @@ int unit_merge(Unit *u, Unit *other) {
if (other->id)
other_id = strdupa(other->id);
+ /* Make reservations to ensure merge_dependencies() won't fail */
+ for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
+ r = reserve_dependencies(u, other, d);
+ /*
+ * We don't rollback reservations if we fail. We don't have
+ * a way to undo reservations. A reservation is not a leak.
+ */
+ if (r < 0)
+ return r;
+ }
+
/* Merge names */
merge_names(u, other);
--
2.1.0
More information about the systemd-devel
mailing list