c1fb3625ae
(write): Removed diagnostic trace. * gnu/java/nio/natSelectorImplPosix.cc: Added includes for java.lang.Thread and java.io.InterruptedIOException. (helper_put_filedescriptors): Don't put invalid file descriptors in select set. (helper_get_filedescriptors): Clear invalid file descriptors from select set. (helper_reset): New method for clearing our file descriptor array. (implSelect): Correctly calculate timeout if specified and legal. Intercept and deal with any java.io.InterruptedIOException thrown by _Jv_select(). From-SVN: r74537
128 lines
3.4 KiB
C++
128 lines
3.4 KiB
C++
// natSelectorImplPosix.cc
|
|
|
|
/* Copyright (C) 2002, 2003 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 <platform.h>
|
|
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
|
|
#include <gnu/java/nio/SelectorImpl.h>
|
|
#include <java/io/InterruptedIOException.h>
|
|
#include <java/io/IOException.h>
|
|
#include <java/lang/Thread.h>
|
|
|
|
static void
|
|
helper_put_filedescriptors (jintArray fdArray, fd_set& fds, int& max_fd)
|
|
{
|
|
jint* tmpFDArray = elements (fdArray);
|
|
|
|
for (int index = 0; index < JvGetArrayLength (fdArray); index++)
|
|
{
|
|
int fd = tmpFDArray [index];
|
|
if (fd > 0)
|
|
{
|
|
FD_SET (tmpFDArray [index], &fds);
|
|
|
|
if (tmpFDArray [index] > max_fd)
|
|
max_fd = tmpFDArray [index];
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
helper_get_filedescriptors (jintArray& fdArray, fd_set fds)
|
|
{
|
|
jint* tmpFDArray = elements (fdArray);
|
|
|
|
for (int index = 0; index < JvGetArrayLength (fdArray); index++)
|
|
{
|
|
int fd = tmpFDArray [index];
|
|
if (fd < 0 || !FD_ISSET (fd, &fds))
|
|
tmpFDArray [index] = 0;
|
|
}
|
|
}
|
|
|
|
static void
|
|
helper_reset (jintArray& fdArray)
|
|
{
|
|
jint* tmpFDArray = elements (fdArray);
|
|
|
|
for (int index = 0; index < JvGetArrayLength (fdArray); index++)
|
|
tmpFDArray [index] = 0;
|
|
}
|
|
|
|
jint
|
|
gnu::java::nio::SelectorImpl::implSelect (jintArray read, jintArray write,
|
|
jintArray except, jlong timeout)
|
|
{
|
|
jint result;
|
|
int max_fd = 0;
|
|
fd_set read_fds;
|
|
fd_set write_fds;
|
|
fd_set except_fds;
|
|
struct timeval real_time_data;
|
|
struct timeval *time_data = NULL;
|
|
|
|
// If a legal timeout value isn't given, use NULL.
|
|
// This means an infinite timeout. The specification
|
|
// also says that a zero timeout should be treated
|
|
// as infinite. Otherwise (if the timeout value is legal),
|
|
// fill our timeval struct and use it for the select.
|
|
if (timeout > 0)
|
|
{
|
|
real_time_data.tv_sec = timeout / 1000;
|
|
real_time_data.tv_usec = (timeout % 1000) * 1000;
|
|
time_data = &real_time_data;
|
|
}
|
|
|
|
// Reset all fd_set structures
|
|
FD_ZERO (&read_fds);
|
|
FD_ZERO (&write_fds);
|
|
FD_ZERO (&except_fds);
|
|
|
|
// Fill the fd_set data structures for the _Jv_select() call.
|
|
helper_put_filedescriptors (read, read_fds, max_fd);
|
|
helper_put_filedescriptors (write, write_fds, max_fd);
|
|
helper_put_filedescriptors (except, except_fds, max_fd);
|
|
|
|
// Actually do the select
|
|
try
|
|
{
|
|
result = _Jv_select (max_fd + 1, &read_fds, &write_fds,
|
|
&except_fds, time_data);
|
|
}
|
|
catch (::java::io::InterruptedIOException *e)
|
|
{
|
|
// The behavior of JRE 1.4.1 is that no exception is thrown
|
|
// when the thread is interrupted, but the thread's interrupt
|
|
// status is set. Clear all of our select sets and return 0,
|
|
// indicating that nothing was selected.
|
|
::java::lang::Thread::currentThread ()->interrupt ();
|
|
helper_reset (read);
|
|
helper_reset (write);
|
|
helper_reset (except);
|
|
return 0;
|
|
}
|
|
|
|
if (result < 0)
|
|
{
|
|
char* strerr = strerror (errno);
|
|
throw new ::java::io::IOException (JvNewStringUTF (strerr));
|
|
}
|
|
|
|
// Set the file descriptors according to the values returned from select().
|
|
helper_get_filedescriptors (read, read_fds);
|
|
helper_get_filedescriptors (write, write_fds);
|
|
helper_get_filedescriptors (except, except_fds);
|
|
|
|
return result;
|
|
}
|