1 // natSelectorImplWin32.cc
3 /* Copyright (C) 2003, 2004 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
14 #include <gnu/java/nio/VMSelector.h>
15 #include <java/lang/Thread.h>
18 gnu::java::nio::VMSelector::select (jintArray read
, jintArray write
,
19 jintArray except
, jlong timeout
)
21 // FIXME: The API for implSelect is biased towards POSIX implementations.
22 jint
* pReadFD
= elements (read
);
23 int nNbReadFDs
= JvGetArrayLength (read
);
25 jint
* pWriteFD
= elements (write
);
26 int nNbWriteFDs
= JvGetArrayLength (write
);
28 int nNbEvents
= nNbReadFDs
+ nNbWriteFDs
;
30 // Create and initialize our event wrapper array
32 // FIXME: We're creating fresh WSAEVENTs for each call.
33 // This is inefficient. It would probably be better to cache these
34 // in the Win32 socket implementation class.
35 WSAEventWrapper aArray
[nNbEvents
];
38 for (int i
=0; i
< nNbReadFDs
; ++i
)
39 aArray
[nCurIndex
++].init(pReadFD
[i
], FD_ACCEPT
| FD_READ
);
41 for (int i
=0; i
< nNbWriteFDs
; ++i
)
42 aArray
[nCurIndex
++].init(pWriteFD
[i
], FD_WRITE
);
44 // Build our array of WSAEVENTs to wait on. Also throw in our thread's
45 // interrupt event in order to detect thread interruption.
46 HANDLE arh
[nNbEvents
+ 1];
47 for (int i
=0; i
< nNbEvents
; ++i
)
48 arh
[i
] = aArray
[i
].getEventHandle();
49 arh
[nNbEvents
] = _Jv_Win32GetInterruptEvent ();
51 // A timeout value of 0 needs to be treated as infinite.
53 timeout
= WSA_INFINITE
;
56 DWORD dwRet
= WSAWaitForMultipleEvents (nNbEvents
+1, arh
, 0, timeout
, false);
58 if (dwRet
== WSA_WAIT_FAILED
)
59 _Jv_ThrowIOException ();
61 // Before we do anything else, clear output file descriptor arrays.
62 memset(pReadFD
, 0, sizeof(jint
) * nNbReadFDs
);
63 memset(pWriteFD
, 0, sizeof(jint
) * nNbWriteFDs
);
64 memset(elements (except
), 0, sizeof(jint
) * JvGetArrayLength (except
));
66 if (dwRet
== DWORD(WSA_WAIT_EVENT_0
+ nNbEvents
))
68 // We were interrupted. Set the current thread's interrupt
69 // status and get out of here, with nothing selected..
70 ::java::lang::Thread::currentThread ()->interrupt ();
73 else if (dwRet
< DWORD(WSA_WAIT_EVENT_0
+ nNbEvents
))
75 int nSelectedEventIndex
= dwRet
- WSA_WAIT_EVENT_0
;
77 // Record the selected file descriptor.
78 // FIXME: This implementation only allows one file descriptor
79 // to be selected at a time. Remedy this by looping on
80 // WSAWaitForMultipleEvents 'til nothing more is selected.
81 jint fd
= aArray
[nSelectedEventIndex
].getFD();
82 if (nSelectedEventIndex
< nNbReadFDs
)
90 // None of the event objects was signalled, so nothing was