gcc/libjava/gnu/java/nio/natSelectorImplWin32.cc
Mohan Embar 5cd4d463f9 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
2003-12-16 22:54:22 +00:00

94 lines
2.9 KiB
C++

// natSelectorImplWin32.cc
/* Copyright (C) 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 <gnu/java/nio/SelectorImpl.h>
#include <java/lang/Thread.h>
jint
gnu::java::nio::SelectorImpl::implSelect (jintArray read, jintArray write,
jintArray except, jlong timeout)
{
// FIXME: The API for implSelect is biased towards POSIX implementations.
jint* pReadFD = elements (read);
int nNbReadFDs = JvGetArrayLength (read);
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];
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))
{
// 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;
}
else if (dwRet < DWORD(WSA_WAIT_EVENT_0 + nNbEvents))
{
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;
}
else
// None of the event objects was signalled, so nothing was
// selected.
return 0;
}