/* Asynchronous timers.
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005,
- 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
This file is part of GNU Emacs.
-GNU Emacs is free software; you can redistribute it and/or modify
+GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA. */
+along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <signal.h>
#include <stdio.h>
-#include <lisp.h>
-#include <syssignal.h>
-#include <systime.h>
-#include <blockinput.h>
-#include <atimer.h>
-
-#ifdef HAVE_UNISTD_H
+#include <setjmp.h>
+#include "lisp.h"
+#include "syssignal.h"
+#include "systime.h"
+#include "blockinput.h"
+#include "atimer.h"
#include <unistd.h>
-#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
/* Function prototypes. */
-static void set_alarm P_ ((void));
-static void schedule_atimer P_ ((struct atimer *));
-static struct atimer *append_atimer_lists P_ ((struct atimer *,
- struct atimer *));
-SIGTYPE alarm_signal_handler ();
+static void set_alarm (void);
+static void schedule_atimer (struct atimer *);
+static struct atimer *append_atimer_lists (struct atimer *,
+ struct atimer *);
+SIGTYPE alarm_signal_handler (int signo);
/* Start a new atimer of type TYPE. TIME specifies when the timer is
to cancel_atimer; don't free it yourself. */
struct atimer *
-start_atimer (type, time, fn, client_data)
- enum atimer_type type;
- EMACS_TIME time;
- atimer_callback fn;
- void *client_data;
+start_atimer (enum atimer_type type, EMACS_TIME time, atimer_callback fn,
+ void *client_data)
{
struct atimer *t;
t = (struct atimer *) xmalloc (sizeof *t);
/* Fill the atimer structure. */
- bzero (t, sizeof *t);
+ memset (t, 0, sizeof *t);
t->type = type;
t->fn = fn;
t->client_data = client_data;
/* Cancel and free atimer TIMER. */
void
-cancel_atimer (timer)
- struct atimer *timer;
+cancel_atimer (struct atimer *timer)
{
int i;
for (t = *list, prev = NULL; t && t != timer; prev = t, t = t->next)
;
- /* If it is, take it off the its list, and put in on the
- free-list. We don't bother to arrange for setting a
- different alarm time, since a too early one doesn't hurt. */
+ /* If it is, take it off its list, and put in on the free-list.
+ We don't bother to arrange for setting a different alarm time,
+ since a too early one doesn't hurt. */
if (t)
{
if (prev)
result list. */
static struct atimer *
-append_atimer_lists (list1, list2)
- struct atimer *list1, *list2;
+append_atimer_lists (struct atimer *list1, struct atimer *list2)
{
if (list1 == NULL)
return list2;
/* Stop all timers except timer T. T null means stop all timers. */
void
-stop_other_atimers (t)
- struct atimer *t;
+stop_other_atimers (struct atimer *t)
{
BLOCK_ATIMERS;
stop_other_atimers. */
void
-run_all_atimers ()
+run_all_atimers (void)
{
if (stopped_atimers)
{
/* A version of run_all_timers suitable for a record_unwind_protect. */
Lisp_Object
-unwind_stop_other_atimers (dummy)
- Lisp_Object dummy;
+unwind_stop_other_atimers (Lisp_Object dummy)
{
run_all_atimers ();
return Qnil;
/* Arrange for a SIGALRM to arrive when the next timer is ripe. */
static void
-set_alarm ()
+set_alarm (void)
{
-#if defined (USG) && !defined (POSIX_SIGNALS)
- /* USG systems forget handlers when they are used;
- must reestablish each time. */
- signal (SIGALRM, alarm_signal_handler);
-#endif /* USG */
-
if (atimers)
{
EMACS_TIME now, time;
EMACS_SET_USECS (time, 1000);
}
- bzero (&it, sizeof it);
+ memset (&it, 0, sizeof it);
it.it_value = time;
setitimer (ITIMER_REAL, &it, 0);
#else /* not HAVE_SETITIMER */
already. */
static void
-schedule_atimer (t)
- struct atimer *t;
+schedule_atimer (struct atimer *t)
{
struct atimer *a = atimers, *prev = NULL;
}
static void
-run_timers ()
+run_timers (void)
{
EMACS_TIME now;
t = atimers;
atimers = atimers->next;
-#ifndef MAC_OSX
t->fn (t);
-#endif
if (t->type == ATIMER_CONTINUOUS)
{
t->next = free_atimers;
free_atimers = t;
}
-#ifdef MAC_OSX
- /* Fix for Ctrl-G. Perhaps this should apply to all platforms. */
- t->fn (t);
-#endif
EMACS_GET_TIME (now);
}
+ if (! atimers)
+ pending_atimers = 0;
+
+#ifdef SYNC_INPUT
+ if (pending_atimers)
+ pending_signals = 1;
+ else
+ {
+ pending_signals = interrupt_input_pending;
+ set_alarm ();
+ }
+#else
if (! pending_atimers)
set_alarm ();
+#endif
}
SIGALRM. */
SIGTYPE
-alarm_signal_handler (signo)
- int signo;
+alarm_signal_handler (int signo)
{
- pending_atimers = 1;
#ifndef SYNC_INPUT
+ SIGNAL_THREAD_CHECK (signo);
+#endif
+
+ pending_atimers = 1;
+#ifdef SYNC_INPUT
+ pending_signals = 1;
+#else
run_timers ();
#endif
}
/* Call alarm_signal_handler for pending timers. */
void
-do_pending_atimers ()
+do_pending_atimers (void)
{
if (pending_atimers)
{
some systems like HPUX (see process.c). */
void
-turn_on_atimers (on)
- int on;
+turn_on_atimers (int on)
{
if (on)
{
void
-init_atimer ()
+init_atimer (void)
{
- free_atimers = atimers = NULL;
+ free_atimers = stopped_atimers = atimers = NULL;
pending_atimers = 0;
+ /* pending_signals is initialized in init_keyboard.*/
signal (SIGALRM, alarm_signal_handler);
}