1eba9d1f8f
Fix for PR libgcj/1351: * posix.cc (_Jv_select): Throw InterruptedIOException if thread is interrupted. Include Thread.h and InterruptedIOException.h. From-SVN: r39639
113 lines
2.5 KiB
C++
113 lines
2.5 KiB
C++
// posix.cc -- Helper functions for POSIX-flavored OSs.
|
|
|
|
/* Copyright (C) 2000, 2001 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>
|
|
|
|
#include <jvm.h>
|
|
#include <java/lang/Thread.h>
|
|
#include <java/io/InterruptedIOException.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;
|
|
|
|
// Here we know we got EINTR.
|
|
if (java::lang::Thread::interrupted ())
|
|
throw new java::io::InterruptedIOException (JvNewStringLatin1 ("select interrupted"));
|
|
|
|
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
|
|
}
|