From ba421b96a473a4e608c2b1d01d3bb3dfe36c23a6 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 dc88862..9a7720d 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -1666,11 +1666,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; @@ -1699,7 +1699,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; @@ -1737,7 +1747,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; } @@ -1754,27 +1764,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) { @@ -1792,7 +1787,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); } }