+int name_watch_pid(Name *n, pid_t pid) {
+ assert(n);
+ assert(pid >= 1);
+
+ return hashmap_put(n->meta.manager->watch_pids, UINT32_TO_PTR(pid), n);
+}
+
+void name_unwatch_pid(Name *n, pid_t pid) {
+ assert(n);
+ assert(pid >= 1);
+
+ hashmap_remove(n->meta.manager->watch_pids, UINT32_TO_PTR(pid));
+}
+
+int name_watch_timer(Name *n, usec_t delay, int *id) {
+ struct epoll_event ev;
+ int fd;
+ struct itimerspec its;
+ int flags;
+ bool ours;
+
+ assert(n);
+ assert(id);
+
+ /* This will try to reuse the old timer if there is one */
+
+ if (*id >= 0) {
+ ours = false;
+ fd = *id;
+
+ } else {
+ ours = true;
+
+ if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0)
+ return -errno;
+ }
+
+ zero(its);
+
+ if (delay <= 0) {
+ /* Set absolute time in the past, but not 0, since we
+ * don't want to disarm the timer */
+ its.it_value.tv_sec = 0;
+ its.it_value.tv_nsec = 1;
+
+ flags = TFD_TIMER_ABSTIME;
+ } else {
+ timespec_store(&its.it_value, delay);
+ flags = 0;
+ }
+
+ /* This will also flush the elapse counter */
+ if (timerfd_settime(fd, flags, &its, NULL) < 0)
+ goto fail;
+
+ zero(ev);
+ ev.data.fd = fd;
+ ev.data.ptr = n;
+ ev.data.u32 = MANAGER_TIMER;
+ ev.events = POLLIN;
+
+ if (epoll_ctl(n->meta.manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
+ goto fail;
+
+ *id = fd;