ioloop.c revision c3ef0ca49561319d40095a4aefbec339683ea908
/* Copyright (c) 2002-2007 Timo Sirainen */
#include "lib.h"
#include "ioloop-internal.h"
#include <unistd.h>
/* If time moves backwards more than this, kill ourself instead of sleeping. */
#define IOLOOP_MAX_TIME_BACKWARDS_SLEEP 5
time_t ioloop_time = 0;
struct timeval ioloop_timeval;
struct timezone ioloop_timezone;
{
}
}
{
else
/* if we got here from an I/O handler callback, make sure we
don't try to handle this one next. */
}
{
/* make sure the callback doesn't get called anymore.
kqueue code relies on this. */
else {
}
}
{
struct timeout **t;
break;
}
*t = timeout;
}
{
i_fatal("gettimeofday(): %m");
} else {
}
/* we don't want microsecond accuracy or this function will be
called all the time - millisecond is more than enough */
}
}
void *context)
{
NULL : &ioloop_timeval);
return timeout;
}
{
}
{
/* no timeouts. give it INT_MAX msecs. */
return INT_MAX;
}
i_fatal("gettimeofday(): %m");
} else {
}
}
/* round wait times up to next millisecond */
}
/* no need to calculate the times again with this timeout */
return 0;
}
{
struct timeout *called_timeouts;
unsigned int t_id;
i_fatal("gettimeofday(): %m");
/* Don't bother comparing usecs. */
/* Note that this code is here only because this is the easiest
place to check for this. The I/O loop code itself could be
easily fixed to work with time moving backwards, but there's
really no point because there are a lot of other places
which may break in more or less bad ways, such as files'
timestamps moving backwards. */
if (diff > IOLOOP_MAX_TIME_BACKWARDS_SLEEP) {
i_fatal("Time just moved backwards by %ld seconds. "
"This might cause a lot of problems, "
"so I'll just kill myself now. "
(long)diff);
} else {
i_error("Time just moved backwards by %ld seconds. "
"I'll sleep now until we're back in present. "
(long)diff);
/* Sleep extra second to make sure usecs also grows. */
diff++;
/* don't use sleep()'s return value, because
it could get us to a long loop in case
interrupts just keep coming */
}
/* Try again. */
}
}
return;
if (t->destroyed) {
i_free(t);
continue;
}
if (!t->run_now) {
if (!t->run_now)
break;
}
/* move timeout to called_timeouts list */
t->next = called_timeouts;
called_timeouts = t;
i_panic("Leaked a t_pop() call in timeout handler %p",
(void *)t->callback);
}
}
/* move timeouts back to list so they get re-sorted again by next_run
time, or destroy them if timeout_remove() was called for them. */
while (called_timeouts != NULL) {
struct timeout *t = called_timeouts;
if (t->destroyed) {
called_timeouts = t->next;
i_free(t);
} else {
called_timeouts = t->next;
}
}
#ifdef DEBUG
struct timeout *t;
i_panic("broken timeout list");
}
}
#endif
}
{
}
{
}
{
}
{
}
struct ioloop *io_loop_create(void)
{
/* initialize time */
i_fatal("gettimeofday(): %m");
return ioloop;
}
{
}
}
/* ->prev won't work unless loops are destroyed in create order */
}