diff options
author | Lennart Poettering <lennart@poettering.net> | 2014-02-07 11:58:25 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2014-02-07 15:14:36 +0100 |
commit | 5ba6985b6c8ef85a8bcfeb1b65239c863436e75b (patch) | |
tree | d6e881b385efc01d14e13cb8555beb67cae7a61b /src/core/unit.c | |
parent | 8190da36f71a887945297cd65d6426c78b466a50 (diff) |
core: allow PIDs to be watched by two units at the same time
In some cases it is interesting to map a PID to two units at the same
time. For example, when a user logs in via a getty, which is reexeced to
/sbin/login that binary will be explicitly referenced as main pid of the
getty service, as well as implicitly referenced as part of the session
scope.
Diffstat (limited to 'src/core/unit.c')
-rw-r--r-- | src/core/unit.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/src/core/unit.c b/src/core/unit.c index 6e1c112124..b0bb0260bc 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -1704,16 +1704,27 @@ int unit_watch_pid(Unit *u, pid_t pid) { assert(u); assert(pid >= 1); + /* 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); + if (r < 0) + return r; + r = set_ensure_allocated(&u->pids, trivial_hash_func, trivial_compare_func); if (r < 0) return r; - /* Watch a specific PID. We only support one unit watching - * each PID for now. */ + r = hashmap_put(u->manager->watch_pids1, LONG_TO_PTR(pid), u); + if (r == -EEXIST) { + r = hashmap_ensure_allocated(&u->manager->watch_pids2, trivial_hash_func, trivial_compare_func); + if (r < 0) + return r; - r = set_put(u->pids, LONG_TO_PTR(pid)); + r = hashmap_put(u->manager->watch_pids2, LONG_TO_PTR(pid), u); + } - q = hashmap_put(u->manager->watch_pids, LONG_TO_PTR(pid), u); + q = set_put(u->pids, LONG_TO_PTR(pid)); if (q < 0) return q; @@ -1724,7 +1735,8 @@ void unit_unwatch_pid(Unit *u, pid_t pid) { assert(u); assert(pid >= 1); - hashmap_remove_value(u->manager->watch_pids, LONG_TO_PTR(pid), u); + hashmap_remove_value(u->manager->watch_pids1, LONG_TO_PTR(pid), u); + hashmap_remove_value(u->manager->watch_pids2, LONG_TO_PTR(pid), u); set_remove(u->pids, LONG_TO_PTR(pid)); } @@ -1797,8 +1809,10 @@ void unit_unwatch_all_pids(Unit *u) { assert(u); - SET_FOREACH(e, u->pids, i) - hashmap_remove_value(u->manager->watch_pids, e, 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); + } set_free(u->pids); u->pids = NULL; |