void stop_other_atimers (struct atimer *t) { sigset_t oldset; block_atimers (&oldset); if (t) { struct atimer *p, *prev; /* See if T is active. */ for (p = atimers, prev = NULL; p && p != t; prev = p, p = p->next) ; if (p == t) { if (prev) prev->next = t->next; else atimers = t->next; t->next = NULL; } else /* T is not active. Let's handle this like T == 0. */ t = NULL; } stopped_atimers = append_atimer_lists (atimers, stopped_atimers); atimers = t; unblock_atimers (&oldset); }
void cancel_atimer (struct atimer *timer) { int i; sigset_t oldset; block_atimers (&oldset); for (i = 0; i < 2; ++i) { struct atimer *t, *prev; struct atimer **list = i ? &stopped_atimers : &atimers; /* See if TIMER is active or stopped. */ for (t = *list, prev = NULL; t && t != timer; prev = t, t = t->next) ; /* 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) prev->next = t->next; else *list = t->next; t->next = free_atimers; free_atimers = t; break; } } unblock_atimers (&oldset); }
struct atimer * 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 (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 a new one. */ if (free_atimers) { t = free_atimers; free_atimers = t->next; } else t = xmalloc (sizeof *t); /* Fill the atimer structure. */ memset (t, 0, sizeof *t); t->type = type; t->fn = fn; t->client_data = client_data; block_atimers (&oldset); /* Compute the timer's expiration time. */ switch (type) { case ATIMER_ABSOLUTE: t->expiration = timestamp; break; case ATIMER_RELATIVE: t->expiration = timespec_add (current_timespec (), timestamp); break; case ATIMER_CONTINUOUS: 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 (&oldset); /* Arrange for a SIGALRM at the time the next atimer is ripe. */ set_alarm (); return t; }
void do_pending_atimers (void) { if (atimers) { block_atimers (); run_timers (); unblock_atimers (); } }
void do_pending_atimers (void) { if (atimers) { sigset_t oldset; block_atimers (&oldset); run_timers (); unblock_atimers (&oldset); } }
void run_all_atimers (void) { if (stopped_atimers) { struct atimer *t = atimers; struct atimer *next; block_atimers (); atimers = stopped_atimers; stopped_atimers = NULL; while (t) { next = t->next; schedule_atimer (t); t = next; } unblock_atimers (); } }