summaryrefslogtreecommitdiff
path: root/unit.c
diff options
context:
space:
mode:
Diffstat (limited to 'unit.c')
-rw-r--r--unit.c90
1 files changed, 54 insertions, 36 deletions
diff --git a/unit.c b/unit.c
index c722717fe6..e6e5574312 100644
--- a/unit.c
+++ b/unit.c
@@ -627,33 +627,44 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) {
retroactively_stop_dependencies(u);
}
-int unit_watch_fd(Unit *u, int fd, uint32_t events) {
+int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w) {
struct epoll_event ev;
assert(u);
assert(fd >= 0);
+ assert(w);
+ assert(w->type == WATCH_INVALID || (w->type == WATCH_FD && w->fd == fd && w->unit == u));
zero(ev);
- ev.data.fd = fd;
- ev.data.ptr = u;
- ev.data.u32 = MANAGER_FD;
+ ev.data.ptr = w;
ev.events = events;
- if (epoll_ctl(u->meta.manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) >= 0)
- return 0;
+ if (epoll_ctl(u->meta.manager->epoll_fd,
+ w->type == WATCH_INVALID ? EPOLL_CTL_ADD : EPOLL_CTL_MOD,
+ fd,
+ &ev) < 0)
+ return -errno;
- if (errno == EEXIST)
- if (epoll_ctl(u->meta.manager->epoll_fd, EPOLL_CTL_MOD, fd, &ev) >= 0)
- return 0;
+ w->fd = fd;
+ w->type = WATCH_FD;
+ w->unit = u;
- return -errno;
+ return 0;
}
-void unit_unwatch_fd(Unit *u, int fd) {
+void unit_unwatch_fd(Unit *u, Watch *w) {
assert(u);
- assert(fd >= 0);
+ assert(w);
- assert_se(epoll_ctl(u->meta.manager->epoll_fd, EPOLL_CTL_DEL, fd, NULL) >= 0 || errno == ENOENT);
+ if (w->type == WATCH_INVALID)
+ return;
+
+ assert(w->type == WATCH_FD && w->unit == u);
+ assert_se(epoll_ctl(u->meta.manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
+
+ w->fd = -1;
+ w->type = WATCH_INVALID;
+ w->unit = NULL;
}
int unit_watch_pid(Unit *u, pid_t pid) {
@@ -670,25 +681,22 @@ void unit_unwatch_pid(Unit *u, pid_t pid) {
hashmap_remove(u->meta.manager->watch_pids, UINT32_TO_PTR(pid));
}
-int unit_watch_timer(Unit *u, usec_t delay, int *id) {
- struct epoll_event ev;
- int fd;
+int unit_watch_timer(Unit *u, usec_t delay, Watch *w) {
struct itimerspec its;
- int flags;
+ int flags, fd;
bool ours;
assert(u);
- assert(id);
+ assert(w);
+ assert(w->type == WATCH_INVALID || (w->type == WATCH_TIMER && w->unit == u));
/* This will try to reuse the old timer if there is one */
- if (*id >= 0) {
+ if (w->type == WATCH_TIMER) {
ours = false;
- fd = *id;
-
+ fd = w->fd;
} else {
ours = true;
-
if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0)
return -errno;
}
@@ -711,16 +719,21 @@ int unit_watch_timer(Unit *u, usec_t delay, int *id) {
if (timerfd_settime(fd, flags, &its, NULL) < 0)
goto fail;
- zero(ev);
- ev.data.fd = fd;
- ev.data.ptr = u;
- ev.data.u32 = MANAGER_TIMER;
- ev.events = POLLIN;
+ if (w->type == WATCH_INVALID) {
+ struct epoll_event ev;
- if (epoll_ctl(u->meta.manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
- goto fail;
+ zero(ev);
+ ev.data.ptr = w;
+ ev.events = POLLIN;
+
+ if (epoll_ctl(u->meta.manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
+ goto fail;
+ }
+
+ w->fd = fd;
+ w->type = WATCH_TIMER;
+ w->unit = u;
- *id = fd;
return 0;
fail:
@@ -730,16 +743,21 @@ fail:
return -errno;
}
-void unit_unwatch_timer(Unit *u, int *id) {
+void unit_unwatch_timer(Unit *u, Watch *w) {
assert(u);
- assert(id);
+ assert(w);
- if (*id < 0)
+ if (w->type == WATCH_INVALID)
return;
- assert_se(epoll_ctl(u->meta.manager->epoll_fd, EPOLL_CTL_DEL, *id, NULL) >= 0);
- assert_se(close_nointr(*id) == 0);
- *id = -1;
+ assert(w->type == WATCH_TIMER && w->unit == u);
+
+ assert_se(epoll_ctl(u->meta.manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
+ assert_se(close_nointr(w->fd) == 0);
+
+ w->fd = -1;
+ w->type = WATCH_INVALID;
+ w->unit = NULL;
}
bool unit_job_is_applicable(Unit *u, JobType j) {