From 8581dc72de05227a236b6ff3751c40f1e0be1b2f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 6 Mar 2014 02:19:42 +0100 Subject: [PATCH] core: correctly unregister PIDs from PID hashtables Conflicts: src/core/unit.c --- src/core/unit.c | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/src/core/unit.c b/src/core/unit.c index a510eb2..6ee34ec 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -1668,11 +1668,11 @@ int unit_watch_pid(Unit *u, pid_t pid) { /* Watch a specific PID. We only support one or two units * watching each PID for now, not more. */ - r = hashmap_ensure_allocated(&u->manager->watch_pids1, trivial_hash_func, trivial_compare_func); + r = set_ensure_allocated(&u->pids, trivial_hash_func, trivial_compare_func); if (r < 0) return r; - r = set_ensure_allocated(&u->pids, trivial_hash_func, trivial_compare_func); + r = hashmap_ensure_allocated(&u->manager->watch_pids1, trivial_hash_func, trivial_compare_func); if (r < 0) return r; @@ -1701,7 +1701,17 @@ void unit_unwatch_pid(Unit *u, pid_t pid) { set_remove(u->pids, LONG_TO_PTR(pid)); } -static int watch_pids_in_path(Unit *u, const char *path) { +void unit_unwatch_all_pids(Unit *u) { + assert(u); + + while (!set_isempty(u->pids)) + unit_unwatch_pid(u, PTR_TO_LONG(set_first(u->pids))); + + set_free(u->pids); + u->pids = NULL; +} + +static int unit_watch_pids_in_path(Unit *u, const char *path) { _cleanup_closedir_ DIR *d = NULL; _cleanup_fclose_ FILE *f = NULL; int ret = 0, r; @@ -1739,7 +1749,7 @@ static int watch_pids_in_path(Unit *u, const char *path) { if (!p) return -ENOMEM; - r = watch_pids_in_path(u, p); + r = unit_watch_pids_in_path(u, p); if (r < 0 && ret >= 0) ret = r; } @@ -1756,27 +1766,12 @@ static int watch_pids_in_path(Unit *u, const char *path) { int unit_watch_all_pids(Unit *u) { assert(u); - if (!u->cgroup_path) - return -ENOENT; - /* Adds all PIDs from our cgroup to the set of PIDs we watch */ - return watch_pids_in_path(u, u->cgroup_path); -} - -void unit_unwatch_all_pids(Unit *u) { - Iterator i; - void *e; - - assert(u); - - SET_FOREACH(e, u->pids, i) { - hashmap_remove_value(u->manager->watch_pids1, e, u); - hashmap_remove_value(u->manager->watch_pids2, e, u); - } + if (!u->cgroup_path) + return -ENOENT; - set_free(u->pids); - u->pids = NULL; + return unit_watch_pids_in_path(u, u->cgroup_path); } void unit_tidy_watch_pids(Unit *u, pid_t except1, pid_t except2) { @@ -1794,7 +1789,7 @@ void unit_tidy_watch_pids(Unit *u, pid_t except1, pid_t except2) { continue; if (kill(pid, 0) < 0 && errno == ESRCH) - set_remove(u->pids, e); + unit_unwatch_pid(u, pid); } }