summaryrefslogtreecommitdiff
path: root/src/atimer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/atimer.c')
-rw-r--r--src/atimer.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/src/atimer.c b/src/atimer.c
index 8723573070e..8387b8aa0e0 100644
--- a/src/atimer.c
+++ b/src/atimer.c
@@ -28,7 +28,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#ifdef HAVE_TIMERFD
#include <errno.h>
-# include <sys/timerfd.h>
+#include <sys/timerfd.h>
+# ifdef CYGWIN
+# include <sys/utsname.h>
+# endif
#endif
#ifdef MSDOS
@@ -113,10 +116,10 @@ start_atimer (enum atimer_type type, struct timespec timestamp,
sigset_t oldset;
/* Round TIMESTAMP up to the next full second if we don't have itimers. */
-#ifndef HAVE_SETITIMER
+#if ! (defined HAVE_ITIMERSPEC || defined HAVE_SETITIMER)
if (timestamp.tv_nsec != 0 && timestamp.tv_sec < TYPE_MAXIMUM (time_t))
timestamp = make_timespec (timestamp.tv_sec + 1, 0);
-#endif /* not HAVE_SETITIMER */
+#endif
/* Get an atimer structure from the free-list, or allocate
a new one. */
@@ -494,15 +497,14 @@ debug_timer_callback (struct atimer *t)
r->intime = 0;
else if (result >= 0)
{
-#ifdef HAVE_SETITIMER
+ bool intime = true;
+#if defined HAVE_ITIMERSPEC || defined HAVE_SETITIMER
struct timespec delta = timespec_sub (now, r->expected);
/* Too late if later than expected + 0.02s. FIXME:
this should depend from system clock resolution. */
- if (timespec_cmp (delta, make_timespec (0, 20000000)) > 0)
- r->intime = 0;
- else
-#endif /* HAVE_SETITIMER */
- r->intime = 1;
+ intime = timespec_cmp (delta, make_timespec (0, 20000000)) <= 0;
+#endif
+ r->intime = intime;
}
}
@@ -558,13 +560,28 @@ Return t if all self-tests are passed, nil otherwise. */)
#endif /* ENABLE_CHECKING */
+/* Cygwin has the timerfd interface starting with release 3.0.0, but
+ it is buggy until release 3.0.2. */
+#ifdef HAVE_TIMERFD
+static bool
+have_buggy_timerfd (void)
+{
+# ifdef CYGWIN
+ struct utsname name;
+ return uname (&name) < 0 || strverscmp (name.release, "3.0.2") < 0;
+# else
+ return false;
+# endif
+}
+#endif
+
void
init_atimer (void)
{
#ifdef HAVE_ITIMERSPEC
# ifdef HAVE_TIMERFD
/* Until this feature is considered stable, you can ask to not use it. */
- timerfd = (egetenv ("EMACS_IGNORE_TIMERFD") ? -1 :
+ timerfd = (egetenv ("EMACS_IGNORE_TIMERFD") || have_buggy_timerfd () ? -1 :
timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK | TFD_CLOEXEC));
# endif
if (timerfd < 0)
@@ -585,6 +602,7 @@ init_atimer (void)
sigaction (SIGALRM, &action, 0);
#ifdef ENABLE_CHECKING
- defsubr (&Sdebug_timer_check);
+ if (!initialized)
+ defsubr (&Sdebug_timer_check);
#endif
}