tag 624506 + patch
thanks
Matthew Garrett provided the attached patch.
Ansgar
--- Begin Message ---
at currently sleeps until the next job run. That's fine in most
circumstances, but interacts badly with system suspend. When the machine
resumes the sleep will continue as if the intervening time hadn't
passed, delaying the next scheduled run. POSIX timers don't have this
behaviour - they allow an absolute time to be provided (which avoids the
delay) and will fire immediately if they expired while the system was
suspended. This patch adds support for using them, while continuing to
use time() and sleep() on systems that don't provide these functions.
diff -ur at-3.1.13/atd.c at-3.1.13.timer/atd.c
--- at-3.1.13/atd.c 2011-06-25 08:43:14.000000000 -0400
+++ at-3.1.13.timer/atd.c 2011-11-16 17:26:02.405420951 -0500
@@ -686,6 +686,54 @@
return next_job;
}
+#ifdef HAVE_CLOCK_GETTIME
+timer_t timer;
+struct itimerspec timeout;
+
+void timer_setup()
+{
+ struct sigevent sev;
+
+ sev.sigev_notify = SIGEV_SIGNAL;
+ sev.sigev_signo = SIGHUP;
+ sev.sigev_value.sival_ptr = &timer;
+
+ memset(&timeout, 0, sizeof(timeout));
+
+ if (timer_create(CLOCK_REALTIME, &sev, &timer) < 0)
+ pabort("unable to create timer");
+}
+
+time_t atd_gettime()
+{
+ struct timespec curtime;
+
+ clock_gettime(CLOCK_REALTIME, &curtime);
+
+ return curtime.tv_sec;
+}
+
+void atd_setalarm(time_t next)
+{
+ timeout.it_value.tv_sec = next;
+ timer_settime(timer, TIMER_ABSTIME, &timeout, NULL);
+ pause();
+}
+#else
+void timer_setup()
+{
+}
+
+time_t atd_gettime()
+{
+ return time(NULL);
+}
+
+void atd_setalarm(time_t next)
+{
+ sleep(next - atd_gettime());
+}
+#endif
/* Global functions */
int
@@ -783,7 +831,7 @@
sigaction(SIGCHLD, &act, NULL);
if (!run_as_daemon) {
- now = time(NULL);
+ now = atd_gettime();
run_loop();
exit(EXIT_SUCCESS);
}
@@ -806,13 +854,15 @@
act.sa_handler = set_term;
sigaction(SIGINT, &act, NULL);
+ timer_setup();
+
daemon_setup();
do {
- now = time(NULL);
+ now = atd_gettime();
next_invocation = run_loop();
if (next_invocation > now) {
- sleep(next_invocation - now);
+ atd_setalarm(next_invocation);
}
} while (!term_signal);
daemon_cleanup();
diff -ur at-3.1.13/config.h.in at-3.1.13.timer/config.h.in
--- at-3.1.13/config.h.in 2011-06-25 08:43:14.000000000 -0400
+++ at-3.1.13.timer/config.h.in 2011-11-16 17:26:02.406420986 -0500
@@ -38,6 +38,9 @@
/* Define to 1 if you have the `getloadavg' function. */
#undef HAVE_GETLOADAVG
+/* Define to 1 if you have the `clock_gettime' function. */
+#undef HAVE_CLOCK_GETTIME
+
/* Define to 1 if you have the <getopt.h> header file. */
#undef HAVE_GETOPT_H
diff -ur at-3.1.13/configure.ac at-3.1.13.timer/configure.ac
--- at-3.1.13/configure.ac 2011-06-25 08:43:14.000000000 -0400
+++ at-3.1.13.timer/configure.ac 2011-11-16 17:26:02.407421018 -0500
@@ -259,5 +259,9 @@
)
AC_SUBST(DAEMON_GROUPNAME)
+dnl check for POSIX timer functions
+AC_SEARCH_LIBS([clock_gettime],[rt])
+AC_CHECK_FUNCS([clock_gettime])
+
AC_CONFIG_FILES(Makefile atrun atd.8 atrun.8 at.1 at.allow.5 batch)
AC_OUTPUT
--
Matthew Garrett | mj...@srcf.ucam.org
--- End Message ---