mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-10 22:00:20 +08:00
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>
|
||||
|
||||
* gnu/java/net/natPlainDatagramSocketImplPosix.cc
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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])
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user