/* Asynchronous timers.
- Copyright (C) 2000-2013 Free Software Foundation, Inc.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
This file is part of GNU Emacs.
/* Block/unblock SIGALRM. */
static void
-sigmask_atimers (int how)
+block_atimers (sigset_t *oldset)
{
sigset_t blocked;
sigemptyset (&blocked);
sigaddset (&blocked, SIGALRM);
- pthread_sigmask (how, &blocked, 0);
+ sigaddset (&blocked, SIGINT);
+ pthread_sigmask (SIG_BLOCK, &blocked, oldset);
}
static void
-block_atimers (void)
+unblock_atimers (sigset_t const *oldset)
{
- sigmask_atimers (SIG_BLOCK);
-}
-static void
-unblock_atimers (void)
-{
- sigmask_atimers (SIG_UNBLOCK);
+ pthread_sigmask (SIG_SETMASK, oldset, 0);
}
/* Function prototypes. */
to cancel_atimer; don't free it yourself. */
struct atimer *
-start_atimer (enum atimer_type type, EMACS_TIME timestamp, atimer_callback fn,
- void *client_data)
+start_atimer (enum atimer_type type, struct timespec timestamp,
+ atimer_callback fn, void *client_data)
{
struct atimer *t;
+ sigset_t oldset;
/* Round TIME up to the next full second if we don't have
itimers. */
#ifndef HAVE_SETITIMER
- if (EMACS_NSECS (timestamp) != 0
- && EMACS_SECS (timestamp) < TYPE_MAXIMUM (time_t))
- timestamp = make_emacs_time (EMACS_SECS (timestamp) + 1, 0);
+ if (timestamp.tv_nsec != 0 && timestamp.tv_sec < TYPE_MAXIMUM (time_t))
+ timestamp = make_timespec (timestamp.tv_sec + 1, 0);
#endif /* not HAVE_SETITIMER */
/* Get an atimer structure from the free-list, or allocate
t->fn = fn;
t->client_data = client_data;
- block_atimers ();
+ block_atimers (&oldset);
/* Compute the timer's expiration time. */
switch (type)
break;
case ATIMER_RELATIVE:
- t->expiration = add_emacs_time (current_emacs_time (), timestamp);
+ t->expiration = timespec_add (current_timespec (), timestamp);
break;
case ATIMER_CONTINUOUS:
- t->expiration = add_emacs_time (current_emacs_time (), timestamp);
+ t->expiration = timespec_add (current_timespec (), timestamp);
t->interval = timestamp;
break;
}
/* Insert the timer in the list of active atimers. */
schedule_atimer (t);
- unblock_atimers ();
+ unblock_atimers (&oldset);
/* Arrange for a SIGALRM at the time the next atimer is ripe. */
set_alarm ();
cancel_atimer (struct atimer *timer)
{
int i;
+ sigset_t oldset;
- block_atimers ();
+ block_atimers (&oldset);
for (i = 0; i < 2; ++i)
{
}
}
- unblock_atimers ();
+ unblock_atimers (&oldset);
}
void
stop_other_atimers (struct atimer *t)
{
- block_atimers ();
+ sigset_t oldset;
+ block_atimers (&oldset);
if (t)
{
stopped_atimers = append_atimer_lists (atimers, stopped_atimers);
atimers = t;
- unblock_atimers ();
+ unblock_atimers (&oldset);
}
{
struct atimer *t = atimers;
struct atimer *next;
+ sigset_t oldset;
- block_atimers ();
+ block_atimers (&oldset);
atimers = stopped_atimers;
stopped_atimers = NULL;
t = next;
}
- unblock_atimers ();
+ unblock_atimers (&oldset);
}
}
#ifdef HAVE_SETITIMER
struct itimerval it;
#endif
- EMACS_TIME now, interval;
+ struct timespec now, interval;
#ifdef HAVE_ITIMERSPEC
if (alarm_timer_ok)
/* Determine interval till the next timer is ripe.
Don't set the interval to 0; this disables the timer. */
- now = current_emacs_time ();
- interval = (EMACS_TIME_LE (atimers->expiration, now)
- ? make_emacs_time (0, 1000 * 1000)
- : sub_emacs_time (atimers->expiration, now));
+ now = current_timespec ();
+ interval = (timespec_cmp (atimers->expiration, now) <= 0
+ ? make_timespec (0, 1000 * 1000)
+ : timespec_sub (atimers->expiration, now));
#ifdef HAVE_SETITIMER
it.it_value = make_timeval (interval);
setitimer (ITIMER_REAL, &it, 0);
#else /* not HAVE_SETITIMER */
- alarm (max (EMACS_SECS (interval), 1));
+ alarm (max (interval.tv_sec, 1));
#endif /* not HAVE_SETITIMER */
}
}
struct atimer *a = atimers, *prev = NULL;
/* Look for the first atimer that is ripe after T. */
- while (a && EMACS_TIME_LT (a->expiration, t->expiration))
+ while (a && timespec_cmp (a->expiration, t->expiration) < 0)
prev = a, a = a->next;
/* Insert T in front of the atimer found, if any. */
static void
run_timers (void)
{
- EMACS_TIME now = current_emacs_time ();
+ struct timespec now = current_timespec ();
- while (atimers && EMACS_TIME_LE (atimers->expiration, now))
+ while (atimers && timespec_cmp (atimers->expiration, now) <= 0)
{
struct atimer *t = atimers;
atimers = atimers->next;
if (t->type == ATIMER_CONTINUOUS)
{
- t->expiration = add_emacs_time (now, t->interval);
+ t->expiration = timespec_add (now, t->interval);
schedule_atimer (t);
}
else
{
if (atimers)
{
- block_atimers ();
+ sigset_t oldset;
+ block_atimers (&oldset);
run_timers ();
- unblock_atimers ();
+ unblock_atimers (&oldset);
}
}
void
init_atimer (void)
{
- struct sigaction action;
#ifdef HAVE_ITIMERSPEC
struct sigevent sigev;
sigev.sigev_notify = SIGEV_SIGNAL;
alarm_timer_ok = timer_create (CLOCK_REALTIME, &sigev, &alarm_timer) == 0;
#endif
free_atimers = stopped_atimers = atimers = NULL;
- /* pending_signals is initialized in init_keyboard.*/
+
+ /* pending_signals is initialized in init_keyboard. */
+ struct sigaction action;
emacs_sigaction_init (&action, handle_alarm_signal);
sigaction (SIGALRM, &action, 0);
}