diff options
author | Lennart Poettering <lennart@poettering.net> | 2011-06-24 23:25:28 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2011-06-24 23:25:28 +0200 |
commit | 31b79c2b4a34961eefc3b3680704124d8490d105 (patch) | |
tree | 36b93e5f01b564b975c773f9fa95505dacdcf4ba /src/logind-session.c | |
parent | 094062918c50cd5a34f7b6510fe206bf78d7cc58 (diff) |
logind: use pipe fd to detect when a session is dead
Diffstat (limited to 'src/logind-session.c')
-rw-r--r-- | src/logind-session.c | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/src/logind-session.c b/src/logind-session.c index 9278f30754..16d6c177d2 100644 --- a/src/logind-session.c +++ b/src/logind-session.c @@ -22,6 +22,7 @@ #include <errno.h> #include <string.h> #include <unistd.h> +#include <sys/epoll.h> #include "logind-session.h" #include "strv.h" @@ -97,8 +98,7 @@ void session_free(Session *s) { hashmap_remove(s->manager->sessions, s->id); - if (s->pipe_fd >= 0) - close_nointr_nofail(s->pipe_fd); + session_unset_pipe_fd(s); free(s->state_file); free(s); @@ -729,6 +729,45 @@ void session_set_idle_hint(Session *s, bool b) { "IdleSinceHintMonotonic\0"); } +int session_set_pipe_fd(Session *s, int fd) { + struct epoll_event ev; + int r; + + assert(s); + assert(fd >= 0); + assert(s->pipe_fd < 0); + + r = hashmap_put(s->manager->pipe_fds, INT_TO_PTR(fd + 1), s); + if (r < 0) + return r; + + zero(ev); + ev.events = 0; + ev.data.u32 = FD_PIPE_BASE + fd; + + if (epoll_ctl(s->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) { + assert_se(hashmap_remove(s->manager->pipe_fds, INT_TO_PTR(fd + 1)) == s); + return -errno; + } + + s->pipe_fd = fd; + return 0; +} + +void session_unset_pipe_fd(Session *s) { + assert(s); + + if (s->pipe_fd < 0) + return; + + assert_se(hashmap_remove(s->manager->pipe_fds, INT_TO_PTR(s->pipe_fd + 1)) == s); + + assert_se(epoll_ctl(s->manager->epoll_fd, EPOLL_CTL_DEL, s->pipe_fd, NULL) == 0); + + close_nointr_nofail(s->pipe_fd); + s->pipe_fd = -1; +} + int session_check_gc(Session *s) { int r; |