1 // natVMSelectorImplWin32.cc
2
3 /* Copyright (C) 2003, 2004, 2007 Free Software Foundation
4
5 This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
9 details. */
10
11 #include <config.h>
12 #include <platform.h>
13
14 #include <gnu/java/nio/VMSelector.h>
15 #include <java/lang/Thread.h>
16
17 jint
select(jintArray read,jintArray write,jintArray except,jlong timeout)18 gnu::java::nio::VMSelector::select (jintArray read, jintArray write,
19 jintArray except, jlong timeout)
20 {
21 // FIXME: The API for implSelect is biased towards POSIX implementations.
22 jint* pReadFD = elements (read);
23 int nNbReadFDs = JvGetArrayLength (read);
24
25 jint* pWriteFD = elements (write);
26 int nNbWriteFDs = JvGetArrayLength (write);
27
28 int nNbEvents = nNbReadFDs + nNbWriteFDs;
29
30 // Create and initialize our event wrapper array
31
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];
36
37 int nCurIndex = 0;
38 for (int i=0; i < nNbReadFDs; ++i)
39 aArray[nCurIndex++].init(pReadFD[i], FD_ACCEPT | FD_READ);
40
41 for (int i=0; i < nNbWriteFDs; ++i)
42 aArray[nCurIndex++].init(pWriteFD[i], FD_WRITE);
43
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 ();
50
51 // A timeout value of 0 needs to be treated as infinite.
52 if (timeout <= 0)
53 timeout = WSA_INFINITE;
54
55 // Do the select.
56 DWORD dwRet = WSAWaitForMultipleEvents (nNbEvents+1, arh, 0, timeout, false);
57
58 if (dwRet == WSA_WAIT_FAILED)
59 _Jv_ThrowIOException ();
60
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));
65
66 if (dwRet == DWORD(WSA_WAIT_EVENT_0 + nNbEvents))
67 {
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 ();
71 return 0;
72 }
73 else if (dwRet < DWORD(WSA_WAIT_EVENT_0 + nNbEvents))
74 {
75 int nSelectedEventIndex = dwRet - WSA_WAIT_EVENT_0;
76
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)
83 pReadFD[0] = fd;
84 else
85 pWriteFD[0] = fd;
86
87 return 1;
88 }
89 else
90 // None of the event objects was signalled, so nothing was
91 // selected.
92 return 0;
93 }
94