summaryrefslogtreecommitdiff
path: root/src/core/unit.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-02-07 11:58:25 +0100
committerLennart Poettering <lennart@poettering.net>2014-02-07 15:14:36 +0100
commit5ba6985b6c8ef85a8bcfeb1b65239c863436e75b (patch)
treed6e881b385efc01d14e13cb8555beb67cae7a61b /src/core/unit.c
parent8190da36f71a887945297cd65d6426c78b466a50 (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.c28
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;