win32.cc (WSAEventWrapper): Implemented default constructor and init() methods.

* win32.cc (WSAEventWrapper): Implemented default
	constructor and init() methods.
	(_Jv_select): Removed.
	* gnu/java/nio/natSelectorImplWin32.cc
	(helper_put_filedescriptors): Removed.
	(helper_get_filedescriptors): Removed.
	(implSelect): Implemented in terms of WSAEventWrapper
	and WSAWaitForMultipleEvents instead of _Jv_select().
	Added support for thread interruption.
	* include/win32.h (WSAEventWrapper): Minor formatting
	changes; added default constructor declaration, init(),
	getFD() and getEventHandle() methods.
	(_Jv_select): Removed.

From-SVN: r74715
This commit is contained in:
Mohan Embar 2003-12-16 22:54:22 +00:00 committed by Mohan Embar
parent 027e655b6e
commit 5cd4d463f9
4 changed files with 122 additions and 94 deletions

View File

@ -1,3 +1,19 @@
2003-12-16 Mohan Embar <gnustuff@thisiscool.com>
* win32.cc (WSAEventWrapper): Implemented default
constructor and init() methods.
(_Jv_select): Removed.
* gnu/java/nio/natSelectorImplWin32.cc
(helper_put_filedescriptors): Removed.
(helper_get_filedescriptors): Removed.
(implSelect): Implemented in terms of WSAEventWrapper
and WSAWaitForMultipleEvents instead of _Jv_select().
Added support for thread interruption.
* include/win32.h (WSAEventWrapper): Minor formatting
changes; added default constructor declaration, init(),
getFD() and getEventHandle() methods.
(_Jv_select): Removed.
2003-12-16 Mohan Embar <gnustuff@thisiscool.com>
* gnu/java/net/natPlainDatagramSocketImplPosix.cc

View File

@ -11,81 +11,83 @@ details. */
#include <config.h>
#include <platform.h>
#include <errno.h>
#include <string.h>
#include <gnu/java/nio/SelectorImpl.h>
#include <java/io/IOException.h>
void
helper_put_filedescriptors (jintArray fdArray, fd_set& fds, int& max_fd)
{
jint* tmpFDArray = elements (fdArray);
for (int index = 0; index < JvGetArrayLength (fdArray); index++)
{
FD_SET (tmpFDArray [index], &fds);
if (tmpFDArray [index] > max_fd)
max_fd = tmpFDArray [index];
}
}
void
helper_get_filedescriptors (jintArray& fdArray, fd_set fds)
{
jint* tmpFDArray = elements (fdArray);
for (int index = 0; index < JvGetArrayLength (fdArray); index++)
if (!FD_ISSET (tmpFDArray [index], &fds))
tmpFDArray [index] = 0;
}
#include <java/lang/Thread.h>
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;
// FIXME: The API for implSelect is biased towards POSIX implementations.
jint* pReadFD = elements (read);
int nNbReadFDs = JvGetArrayLength (read);
real_time_data.tv_sec = 0;
real_time_data.tv_usec = timeout;
jint* pWriteFD = elements (write);
int nNbWriteFDs = JvGetArrayLength (write);
int nNbEvents = nNbReadFDs + nNbWriteFDs;
// Create and initialize our event wrapper array
// FIXME: We're creating fresh WSAEVENTs for each call.
// This is inefficient. It would probably be better to cache these
// in the Win32 socket implementation class.
WSAEventWrapper aArray[nNbEvents];
// If not legal timeout value is given, use NULL.
// This means an infinite timeout.
if (timeout >= 0)
int nCurIndex = 0;
for (int i=0; i < nNbReadFDs; ++i)
aArray[nCurIndex++].init(pReadFD[i], FD_ACCEPT | FD_READ);
for (int i=0; i < nNbWriteFDs; ++i)
aArray[nCurIndex++].init(pWriteFD[i], FD_WRITE);
// Build our array of WSAEVENTs to wait on. Also throw in our thread's
// interrupt event in order to detect thread interruption.
HANDLE arh[nNbEvents + 1];
for (int i=0; i < nNbEvents; ++i)
arh[i] = aArray[i].getEventHandle();
arh[nNbEvents] = _Jv_Win32GetInterruptEvent ();
// A timeout value of 0 needs to be treated as infinite.
if (timeout <= 0)
timeout = WSA_INFINITE;
// Do the select.
DWORD dwRet = WSAWaitForMultipleEvents (nNbEvents+1, arh, 0, timeout, false);
if (dwRet == WSA_WAIT_FAILED)
_Jv_ThrowIOException ();
// Before we do anything else, clear output file descriptor arrays.
memset(pReadFD, 0, sizeof(jint) * nNbReadFDs);
memset(pWriteFD, 0, sizeof(jint) * nNbWriteFDs);
memset(elements (except), 0, sizeof(jint) * JvGetArrayLength (except));
if (dwRet == DWORD(WSA_WAIT_EVENT_0 + nNbEvents))
{
time_data = &real_time_data;
// We were interrupted. Set the current thread's interrupt
// status and get out of here, with nothing selected..
::java::lang::Thread::currentThread ()->interrupt ();
return 0;
}
// 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
result = _Jv_select (max_fd + 1, &read_fds, &write_fds, &except_fds, time_data);
if (result < 0)
else if (dwRet < DWORD(WSA_WAIT_EVENT_0 + nNbEvents))
{
char* strerr = strerror (errno);
throw new ::java::io::IOException (JvNewStringUTF (strerr));
int nSelectedEventIndex = dwRet - WSA_WAIT_EVENT_0;
// Record the selected file descriptor.
// FIXME: This implementation only allows one file descriptor
// to be selected at a time. Remedy this by looping on
// WSAWaitForMultipleEvents 'til nothing more is selected.
jint fd = aArray[nSelectedEventIndex].getFD();
if (nSelectedEventIndex < nNbReadFDs)
pReadFD[0] = fd;
else
pWriteFD[0] = fd;
return 1;
}
// 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;
else
// None of the event objects was signalled, so nothing was
// selected.
return 0;
}

View File

@ -93,25 +93,36 @@ extern jstring _Jv_Win32NewString (LPCTSTR pcsz);
/* Useful helper classes and methods. */
/* A C++ wrapper around a WSAEVENT which closes the event
in its destructor. If dwSelFlags is non-zero, we also
issue an WSAEventSelect on the socket descriptor with
the given flags; this is undone by a corresponding call
to WSAEventSelect(fd, 0, 0) in our destructor. */
in its destructor. If dwSelFlags is non-zero, we also
issue an WSAEventSelect on the socket descriptor with
the given flags; this is undone by a corresponding call
to WSAEventSelect(fd, 0, 0) in our destructor. */
class WSAEventWrapper
{
public:
WSAEventWrapper(int fd, DWORD dwSelFlags);
~WSAEventWrapper();
// Default constructor. Call init() after this.
WSAEventWrapper();
WSAEventWrapper(int fd, DWORD dwSelFlags);
~WSAEventWrapper();
WSAEVENT getEventHandle()
{
return m_hEvent;
}
// Used for two-step initialization after calling
// default constructor.
void init(int fd, DWORD dwSelFlags);
int getFD()
{
return m_fd;
}
WSAEVENT getEventHandle()
{
return m_hEvent;
}
private:
WSAEVENT m_hEvent;
int m_fd;
DWORD m_dwSelFlags;
WSAEVENT m_hEvent;
int m_fd;
DWORD m_dwSelFlags;
};
// Error string text. The int argument is compatible
@ -141,7 +152,6 @@ _Jv_ThrowSocketException ();
extern void _Jv_platform_initialize (void);
extern void _Jv_platform_initProperties (java::util::Properties*);
extern jlong _Jv_platform_gettimeofday ();
extern int _Jv_select (int n, fd_set *, fd_set *, fd_set *, struct timeval *);
extern int _Jv_pipe (int filedes[2]);
extern void

View File

@ -143,11 +143,24 @@ _Jv_Win32TempString::~_Jv_Win32TempString()
}
// class WSAEventWrapper
WSAEventWrapper::WSAEventWrapper ():
m_hEvent(0),
m_fd(0),
m_dwSelFlags(0)
{}
WSAEventWrapper::WSAEventWrapper (int fd, DWORD dwSelFlags):
m_hEvent(0),
m_fd(fd),
m_dwSelFlags(dwSelFlags)
m_fd(0),
m_dwSelFlags(0)
{
init(fd, dwSelFlags);
}
void WSAEventWrapper::init(int fd, DWORD dwSelFlags)
{
m_fd = fd;
m_dwSelFlags = dwSelFlags;
m_hEvent = WSACreateEvent ();
if (dwSelFlags)
WSAEventSelect(fd, m_hEvent, dwSelFlags);
@ -445,19 +458,6 @@ backtrace (void **__array, int __size)
return i;
}
int
_Jv_select (int n, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout)
{
int r = ::select (n, readfds, writefds, exceptfds, timeout);
if (r == SOCKET_ERROR)
{
DWORD dwErrorCode = WSAGetLastError ();
throw new java::io::IOException (_Jv_WinStrError (dwErrorCode));
}
return r;
}
int
_Jv_pipe (int filedes[2])
{