src/java.base/windows/native/libnio/ch/WindowsSelectorImpl.c
changeset 58999 6bc29ebe053e
parent 53312 ee7b0da99262
equal deleted inserted replaced
58998:9e2f184eac99 58999:6bc29ebe053e
    37 #include <winsock2.h>
    37 #include <winsock2.h>
    38 
    38 
    39 #include "jvm.h"
    39 #include "jvm.h"
    40 #include "jni.h"
    40 #include "jni.h"
    41 #include "jni_util.h"
    41 #include "jni_util.h"
       
    42 #include "nio.h"
    42 #include "sun_nio_ch_WindowsSelectorImpl.h"
    43 #include "sun_nio_ch_WindowsSelectorImpl.h"
    43 #include "sun_nio_ch_PollArrayWrapper.h"
    44 #include "sun_nio_ch_PollArrayWrapper.h"
    44 
    45 
    45 #include "nio_util.h" /* Needed for POLL* constants (includes "winsock2.h") */
    46 #include "nio_util.h" /* Needed for POLL* constants (includes "winsock2.h") */
    46 
    47 
    54 
    55 
    55 JNIEXPORT jint JNICALL
    56 JNIEXPORT jint JNICALL
    56 Java_sun_nio_ch_WindowsSelectorImpl_00024SubSelector_poll0(JNIEnv *env, jobject this,
    57 Java_sun_nio_ch_WindowsSelectorImpl_00024SubSelector_poll0(JNIEnv *env, jobject this,
    57                                    jlong pollAddress, jint numfds,
    58                                    jlong pollAddress, jint numfds,
    58                                    jintArray returnReadFds, jintArray returnWriteFds,
    59                                    jintArray returnReadFds, jintArray returnWriteFds,
    59                                    jintArray returnExceptFds, jlong timeout)
    60                                    jintArray returnExceptFds, jlong timeout, jlong fdsBuffer)
    60 {
    61 {
    61     DWORD result = 0;
    62     DWORD result = 0;
    62     pollfd *fds = (pollfd *) pollAddress;
    63     pollfd *fds = (pollfd *) pollAddress;
    63     int i;
    64     int i;
    64     FD_SET readfds, writefds, exceptfds;
    65     FD_SET *readfds = (FD_SET *) jlong_to_ptr(fdsBuffer);
       
    66     FD_SET *writefds = (FD_SET *) jlong_to_ptr(fdsBuffer + sizeof(FD_SET));
       
    67     FD_SET *exceptfds = (FD_SET *) jlong_to_ptr(fdsBuffer + sizeof(FD_SET) * 2);
    65     struct timeval timevalue, *tv;
    68     struct timeval timevalue, *tv;
    66     static struct timeval zerotime = {0, 0};
    69     static struct timeval zerotime = {0, 0};
    67     int read_count = 0, write_count = 0, except_count = 0;
    70     int read_count = 0, write_count = 0, except_count = 0;
    68 
    71 
    69 #ifdef _WIN64
    72 #ifdef _WIN64
    91     }
    94     }
    92 
    95 
    93     /* Set FD_SET structures required for select */
    96     /* Set FD_SET structures required for select */
    94     for (i = 0; i < numfds; i++) {
    97     for (i = 0; i < numfds; i++) {
    95         if (fds[i].events & POLLIN) {
    98         if (fds[i].events & POLLIN) {
    96            readfds.fd_array[read_count] = fds[i].fd;
    99            readfds->fd_array[read_count] = fds[i].fd;
    97            read_count++;
   100            read_count++;
    98         }
   101         }
    99         if (fds[i].events & (POLLOUT | POLLCONN))
   102         if (fds[i].events & (POLLOUT | POLLCONN))
   100         {
   103         {
   101            writefds.fd_array[write_count] = fds[i].fd;
   104            writefds->fd_array[write_count] = fds[i].fd;
   102            write_count++;
   105            write_count++;
   103         }
   106         }
   104         exceptfds.fd_array[except_count] = fds[i].fd;
   107         exceptfds->fd_array[except_count] = fds[i].fd;
   105         except_count++;
   108         except_count++;
   106     }
   109     }
   107 
   110 
   108     readfds.fd_count = read_count;
   111     readfds->fd_count = read_count;
   109     writefds.fd_count = write_count;
   112     writefds->fd_count = write_count;
   110     exceptfds.fd_count = except_count;
   113     exceptfds->fd_count = except_count;
   111 
   114 
   112     /* Call select */
   115     /* Call select */
   113     if ((result = select(0 , &readfds, &writefds, &exceptfds, tv))
   116     if ((result = select(0 , readfds, writefds, exceptfds, tv))
   114                                                              == SOCKET_ERROR) {
   117                                                              == SOCKET_ERROR) {
   115         /* Bad error - this should not happen frequently */
   118         JNU_ThrowIOExceptionWithLastError(env, "Select failed");
   116         /* Iterate over sockets and call select() on each separately */
   119         return IOS_THROWN;
   117         FD_SET errreadfds, errwritefds, errexceptfds;
       
   118         readfds.fd_count = 0;
       
   119         writefds.fd_count = 0;
       
   120         exceptfds.fd_count = 0;
       
   121         for (i = 0; i < numfds; i++) {
       
   122             /* prepare select structures for the i-th socket */
       
   123             errreadfds.fd_count = 0;
       
   124             errwritefds.fd_count = 0;
       
   125             if (fds[i].events & POLLIN) {
       
   126                errreadfds.fd_array[0] = fds[i].fd;
       
   127                errreadfds.fd_count = 1;
       
   128             }
       
   129             if (fds[i].events & (POLLOUT | POLLCONN))
       
   130             {
       
   131                 errwritefds.fd_array[0] = fds[i].fd;
       
   132                 errwritefds.fd_count = 1;
       
   133             }
       
   134             errexceptfds.fd_array[0] = fds[i].fd;
       
   135             errexceptfds.fd_count = 1;
       
   136 
       
   137             /* call select on the i-th socket */
       
   138             if (select(0, &errreadfds, &errwritefds, &errexceptfds, &zerotime)
       
   139                                                              == SOCKET_ERROR) {
       
   140                 /* This socket causes an error. Add it to exceptfds set */
       
   141                 exceptfds.fd_array[exceptfds.fd_count] = fds[i].fd;
       
   142                 exceptfds.fd_count++;
       
   143             } else {
       
   144                 /* This socket does not cause an error. Process result */
       
   145                 if (errreadfds.fd_count == 1) {
       
   146                     readfds.fd_array[readfds.fd_count] = fds[i].fd;
       
   147                     readfds.fd_count++;
       
   148                 }
       
   149                 if (errwritefds.fd_count == 1) {
       
   150                     writefds.fd_array[writefds.fd_count] = fds[i].fd;
       
   151                     writefds.fd_count++;
       
   152                 }
       
   153                 if (errexceptfds.fd_count == 1) {
       
   154                     exceptfds.fd_array[exceptfds.fd_count] = fds[i].fd;
       
   155                     exceptfds.fd_count++;
       
   156                 }
       
   157             }
       
   158         }
       
   159     }
   120     }
   160 
   121 
   161     /* Return selected sockets. */
   122     /* Return selected sockets. */
   162     /* Each Java array consists of sockets count followed by sockets list */
   123     /* Each Java array consists of sockets count followed by sockets list */
   163 
   124 
   164 #ifdef _WIN64
   125 #ifdef _WIN64
   165     resultbuf[0] = readfds.fd_count;
   126     resultbuf[0] = readfds->fd_count;
   166     for (i = 0; i < (int)readfds.fd_count; i++) {
   127     for (i = 0; i < (int)readfds->fd_count; i++) {
   167         resultbuf[i + 1] = (int)readfds.fd_array[i];
   128         resultbuf[i + 1] = (int)readfds->fd_array[i];
   168     }
   129     }
   169     (*env)->SetIntArrayRegion(env, returnReadFds, 0,
   130     (*env)->SetIntArrayRegion(env, returnReadFds, 0,
   170                               readfds.fd_count + 1, resultbuf);
   131                               readfds->fd_count + 1, resultbuf);
   171 
   132 
   172     resultbuf[0] = writefds.fd_count;
   133     resultbuf[0] = writefds->fd_count;
   173     for (i = 0; i < (int)writefds.fd_count; i++) {
   134     for (i = 0; i < (int)writefds->fd_count; i++) {
   174         resultbuf[i + 1] = (int)writefds.fd_array[i];
   135         resultbuf[i + 1] = (int)writefds->fd_array[i];
   175     }
   136     }
   176     (*env)->SetIntArrayRegion(env, returnWriteFds, 0,
   137     (*env)->SetIntArrayRegion(env, returnWriteFds, 0,
   177                               writefds.fd_count + 1, resultbuf);
   138                               writefds->fd_count + 1, resultbuf);
   178 
   139 
   179     resultbuf[0] = exceptfds.fd_count;
   140     resultbuf[0] = exceptfds->fd_count;
   180     for (i = 0; i < (int)exceptfds.fd_count; i++) {
   141     for (i = 0; i < (int)exceptfds->fd_count; i++) {
   181         resultbuf[i + 1] = (int)exceptfds.fd_array[i];
   142         resultbuf[i + 1] = (int)exceptfds->fd_array[i];
   182     }
   143     }
   183     (*env)->SetIntArrayRegion(env, returnExceptFds, 0,
   144     (*env)->SetIntArrayRegion(env, returnExceptFds, 0,
   184                               exceptfds.fd_count + 1, resultbuf);
   145                               exceptfds->fd_count + 1, resultbuf);
   185 #else
   146 #else
   186     (*env)->SetIntArrayRegion(env, returnReadFds, 0,
   147     (*env)->SetIntArrayRegion(env, returnReadFds, 0,
   187                               readfds.fd_count + 1, (jint *)&readfds);
   148                               readfds->fd_count + 1, (jint *)readfds);
   188 
   149 
   189     (*env)->SetIntArrayRegion(env, returnWriteFds, 0,
   150     (*env)->SetIntArrayRegion(env, returnWriteFds, 0,
   190                               writefds.fd_count + 1, (jint *)&writefds);
   151                               writefds->fd_count + 1, (jint *)writefds);
   191     (*env)->SetIntArrayRegion(env, returnExceptFds, 0,
   152     (*env)->SetIntArrayRegion(env, returnExceptFds, 0,
   192                               exceptfds.fd_count + 1, (jint *)&exceptfds);
   153                               exceptfds->fd_count + 1, (jint *)exceptfds);
   193 #endif
   154 #endif
   194     return 0;
   155     return 0;
   195 }
   156 }
   196 
   157 
   197 JNIEXPORT void JNICALL
   158 JNIEXPORT void JNICALL