gcc/libjava/posix.cc

105 lines
2.3 KiB
C++

// posix.cc -- Helper functions for POSIX-flavored OSs.
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
#include <config.h>
#include "posix.h"
#include <errno.h>
#if defined (ECOS)
extern "C" unsigned long long _clock (void);
#endif
// gettimeofday implementation.
void
_Jv_gettimeofday (struct timeval *tv)
{
#if defined (HAVE_GETTIMEOFDAY)
gettimeofday (tv, NULL);
#elif defined (HAVE_TIME)
tv->tv_sec = time (NULL);
tv->tv_usec = 0;
#elif defined (HAVE_FTIME)
struct timeb t;
ftime (&t);
tv->tv_sec = t.time;
tv->tv_usec = t.millitm * 1000;
#elif defined (ECOS)
// FIXME.
tv->tv_sec = _clock () / 1000;
tv->tv_usec = 0;
#else
// In the absence of any function, time remains forever fixed.
tv->tv_sec = 23;
tv->tv_usec = 0;
#endif
}
// A wrapper for select() which ignores EINTR.
int
_Jv_select (int n, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout)
{
#ifdef HAVE_SELECT
// If we have a timeout, compute the absolute ending time.
struct timeval end, delay;
if (timeout)
{
_Jv_gettimeofday (&end);
end.tv_usec += timeout->tv_usec;
if (end.tv_usec >= 1000000)
{
++end.tv_sec;
end.tv_usec -= 1000000;
}
end.tv_sec += timeout->tv_sec;
delay = *timeout;
}
else
{
// Placate compiler.
delay.tv_sec = delay.tv_usec = 0;
}
while (1)
{
int r = select (n, readfds, writefds, exceptfds,
timeout ? &delay : NULL);
if (r != -1 || errno != EINTR)
return r;
struct timeval after;
if (timeout)
{
_Jv_gettimeofday (&after);
// Now compute new timeout argument.
delay.tv_usec = end.tv_usec - after.tv_usec;
delay.tv_sec = end.tv_sec - after.tv_sec;
if (delay.tv_usec < 0)
{
--delay.tv_sec;
delay.tv_usec += 1000000;
}
if (delay.tv_sec < 0)
{
// We assume that the user wants a valid select() call
// more than precise timing. So if we get a series of
// EINTR we just keep trying with delay 0 until we get a
// valid result.
delay.tv_sec = 0;
}
}
}
#else /* HAVE_SELECT */
return 0;
#endif
}