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:
parent
027e655b6e
commit
5cd4d463f9
|
@ -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>
|
2003-12-16 Mohan Embar <gnustuff@thisiscool.com>
|
||||||
|
|
||||||
* gnu/java/net/natPlainDatagramSocketImplPosix.cc
|
* gnu/java/net/natPlainDatagramSocketImplPosix.cc
|
||||||
|
|
|
@ -11,81 +11,83 @@ details. */
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <gnu/java/nio/SelectorImpl.h>
|
#include <gnu/java/nio/SelectorImpl.h>
|
||||||
#include <java/io/IOException.h>
|
#include <java/lang/Thread.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
jint
|
jint
|
||||||
gnu::java::nio::SelectorImpl::implSelect (jintArray read, jintArray write,
|
gnu::java::nio::SelectorImpl::implSelect (jintArray read, jintArray write,
|
||||||
jintArray except, jlong timeout)
|
jintArray except, jlong timeout)
|
||||||
{
|
{
|
||||||
jint result;
|
// FIXME: The API for implSelect is biased towards POSIX implementations.
|
||||||
int max_fd = 0;
|
jint* pReadFD = elements (read);
|
||||||
fd_set read_fds;
|
int nNbReadFDs = JvGetArrayLength (read);
|
||||||
fd_set write_fds;
|
|
||||||
fd_set except_fds;
|
|
||||||
struct timeval real_time_data;
|
|
||||||
struct timeval *time_data = NULL;
|
|
||||||
|
|
||||||
real_time_data.tv_sec = 0;
|
jint* pWriteFD = elements (write);
|
||||||
real_time_data.tv_usec = timeout;
|
int nNbWriteFDs = JvGetArrayLength (write);
|
||||||
|
|
||||||
// If not legal timeout value is given, use NULL.
|
int nNbEvents = nNbReadFDs + nNbWriteFDs;
|
||||||
// This means an infinite timeout.
|
|
||||||
if (timeout >= 0)
|
// 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))
|
||||||
{
|
{
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
else if (dwRet < DWORD(WSA_WAIT_EVENT_0 + nNbEvents))
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
char* strerr = strerror (errno);
|
int nSelectedEventIndex = dwRet - WSA_WAIT_EVENT_0;
|
||||||
throw new ::java::io::IOException (JvNewStringUTF (strerr));
|
|
||||||
|
// 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
|
||||||
// Set the file descriptors according to the values returned from select().
|
// None of the event objects was signalled, so nothing was
|
||||||
helper_get_filedescriptors (read, read_fds);
|
// selected.
|
||||||
helper_get_filedescriptors (write, write_fds);
|
return 0;
|
||||||
helper_get_filedescriptors (except, except_fds);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,25 +93,36 @@ extern jstring _Jv_Win32NewString (LPCTSTR pcsz);
|
||||||
/* Useful helper classes and methods. */
|
/* Useful helper classes and methods. */
|
||||||
|
|
||||||
/* A C++ wrapper around a WSAEVENT which closes the event
|
/* A C++ wrapper around a WSAEVENT which closes the event
|
||||||
in its destructor. If dwSelFlags is non-zero, we also
|
in its destructor. If dwSelFlags is non-zero, we also
|
||||||
issue an WSAEventSelect on the socket descriptor with
|
issue an WSAEventSelect on the socket descriptor with
|
||||||
the given flags; this is undone by a corresponding call
|
the given flags; this is undone by a corresponding call
|
||||||
to WSAEventSelect(fd, 0, 0) in our destructor. */
|
to WSAEventSelect(fd, 0, 0) in our destructor. */
|
||||||
class WSAEventWrapper
|
class WSAEventWrapper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WSAEventWrapper(int fd, DWORD dwSelFlags);
|
// Default constructor. Call init() after this.
|
||||||
~WSAEventWrapper();
|
WSAEventWrapper();
|
||||||
|
WSAEventWrapper(int fd, DWORD dwSelFlags);
|
||||||
|
~WSAEventWrapper();
|
||||||
|
|
||||||
WSAEVENT getEventHandle()
|
// Used for two-step initialization after calling
|
||||||
{
|
// default constructor.
|
||||||
return m_hEvent;
|
void init(int fd, DWORD dwSelFlags);
|
||||||
}
|
|
||||||
|
int getFD()
|
||||||
|
{
|
||||||
|
return m_fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
WSAEVENT getEventHandle()
|
||||||
|
{
|
||||||
|
return m_hEvent;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WSAEVENT m_hEvent;
|
WSAEVENT m_hEvent;
|
||||||
int m_fd;
|
int m_fd;
|
||||||
DWORD m_dwSelFlags;
|
DWORD m_dwSelFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Error string text. The int argument is compatible
|
// Error string text. The int argument is compatible
|
||||||
|
@ -141,7 +152,6 @@ _Jv_ThrowSocketException ();
|
||||||
extern void _Jv_platform_initialize (void);
|
extern void _Jv_platform_initialize (void);
|
||||||
extern void _Jv_platform_initProperties (java::util::Properties*);
|
extern void _Jv_platform_initProperties (java::util::Properties*);
|
||||||
extern jlong _Jv_platform_gettimeofday ();
|
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 int _Jv_pipe (int filedes[2]);
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
|
|
|
@ -143,11 +143,24 @@ _Jv_Win32TempString::~_Jv_Win32TempString()
|
||||||
}
|
}
|
||||||
|
|
||||||
// class WSAEventWrapper
|
// class WSAEventWrapper
|
||||||
|
WSAEventWrapper::WSAEventWrapper ():
|
||||||
|
m_hEvent(0),
|
||||||
|
m_fd(0),
|
||||||
|
m_dwSelFlags(0)
|
||||||
|
{}
|
||||||
|
|
||||||
WSAEventWrapper::WSAEventWrapper (int fd, DWORD dwSelFlags):
|
WSAEventWrapper::WSAEventWrapper (int fd, DWORD dwSelFlags):
|
||||||
m_hEvent(0),
|
m_hEvent(0),
|
||||||
m_fd(fd),
|
m_fd(0),
|
||||||
m_dwSelFlags(dwSelFlags)
|
m_dwSelFlags(0)
|
||||||
{
|
{
|
||||||
|
init(fd, dwSelFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WSAEventWrapper::init(int fd, DWORD dwSelFlags)
|
||||||
|
{
|
||||||
|
m_fd = fd;
|
||||||
|
m_dwSelFlags = dwSelFlags;
|
||||||
m_hEvent = WSACreateEvent ();
|
m_hEvent = WSACreateEvent ();
|
||||||
if (dwSelFlags)
|
if (dwSelFlags)
|
||||||
WSAEventSelect(fd, m_hEvent, dwSelFlags);
|
WSAEventSelect(fd, m_hEvent, dwSelFlags);
|
||||||
|
@ -445,19 +458,6 @@ backtrace (void **__array, int __size)
|
||||||
return i;
|
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
|
int
|
||||||
_Jv_pipe (int filedes[2])
|
_Jv_pipe (int filedes[2])
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue