Commit 11804a04 authored by Dmitry Antipov's avatar Dmitry Antipov
Browse files

* atimer.c (toplevel) [HAVE_TIMERFD]: Include errno.h.

(timerfd_callback): Ignore weird events with no data.  Add tight
assertions and comments.
(init_atimer) [HAVE_TIMERFD]: Add environment variable to optionally
disabletimerfd-based timer.  Use TFD_NONBLOCK for timer descriptor.
parent bc1ce1df
2014-08-01 Dmitry Antipov <dmantipov@yandex.ru>
* atimer.c (toplevel) [HAVE_TIMERFD]: Include errno.h.
(timerfd_callback): Ignore weird events with no data. Add tight
assertions and comments.
(init_atimer) [HAVE_TIMERFD]: Add environment variable to optionally
disable timerfd-based timer. Use TFD_NONBLOCK for timer descriptor.
2014-08-01 Paul Eggert <eggert@cs.ucla.edu> 2014-08-01 Paul Eggert <eggert@cs.ucla.edu>
* frame.c (x_set_frame_parameters): Fix typo in previous patch. * frame.c (x_set_frame_parameters): Fix typo in previous patch.
......
...@@ -27,6 +27,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ ...@@ -27,6 +27,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <unistd.h> #include <unistd.h>
#ifdef HAVE_TIMERFD #ifdef HAVE_TIMERFD
#include <errno.h>
# include <sys/timerfd.h> # include <sys/timerfd.h>
#endif #endif
...@@ -399,14 +400,26 @@ handle_alarm_signal (int sig) ...@@ -399,14 +400,26 @@ handle_alarm_signal (int sig)
void void
timerfd_callback (int fd, void *arg) timerfd_callback (int fd, void *arg)
{ {
char buf[8];
ptrdiff_t nbytes; ptrdiff_t nbytes;
uint64_t expirations;
eassert (fd == timerfd); eassert (fd == timerfd);
nbytes = emacs_read (fd, buf, sizeof (buf)); nbytes = emacs_read (fd, &expirations, sizeof (expirations));
/* Just discard an expiration count for now. */
eassert (nbytes == sizeof (buf)); if (nbytes == sizeof (expirations))
do_pending_atimers (); {
/* Timer should expire just once. */
eassert (expirations == 1);
do_pending_atimers ();
}
else if (nbytes < 0)
/* For some not yet known reason, we may get weird event and no
data on timer descriptor. This can break Gnus at least, see:
http://lists.gnu.org/archive/html/emacs-devel/2014-07/msg00503.html. */
eassert (errno == EAGAIN);
else
/* I don't know what else can happen with this descriptor. */
emacs_abort ();
} }
#endif /* HAVE_TIMERFD */ #endif /* HAVE_TIMERFD */
...@@ -528,7 +541,9 @@ init_atimer (void) ...@@ -528,7 +541,9 @@ init_atimer (void)
{ {
#ifdef HAVE_ITIMERSPEC #ifdef HAVE_ITIMERSPEC
# ifdef HAVE_TIMERFD # ifdef HAVE_TIMERFD
timerfd = timerfd_create (CLOCK_REALTIME, TFD_CLOEXEC); /* Until this feature is considered stable, you can ask to not use it. */
timerfd = (egetenv ("EMACS_IGNORE_TIMERFD") ? -1 :
timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK | TFD_CLOEXEC));
# endif # endif
if (timerfd < 0) if (timerfd < 0)
{ {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment