Index: native/jni/java-nio/gnu_java_nio_VMSelector.c =================================================================== RCS file: /cvsroot/classpath/classpath/native/jni/java-nio/gnu_java_nio_VMSelector.c,v retrieving revision 1.6 diff -u -r1.6 gnu_java_nio_VMSelector.c --- native/jni/java-nio/gnu_java_nio_VMSelector.c 29 Mar 2005 18:06:05 -0000 1.6 +++ native/jni/java-nio/gnu_java_nio_VMSelector.c 3 Apr 2005 16:42:55 -0000 @@ -57,140 +57,137 @@ /* Amount of characters in the error message buffer for strerror_r. */ #define BUF_SIZE 250 -void -helper_put_filedescriptors(JNIEnv *, jintArray, fd_set *, int *); +void helper_put_filedescriptors (JNIEnv *, jintArray, fd_set *, int *); -void -helper_get_filedescriptors (JNIEnv *, jintArray*, fd_set *); +void helper_get_filedescriptors (JNIEnv *, jintArray *, fd_set *); -void -helper_reset (JNIEnv *, jintArray*); +void helper_reset (JNIEnv *, jintArray *); int helper_select (JNIEnv *, jclass, jmethodID, - int, fd_set *, fd_set *, fd_set *, - struct timeval *); + int, fd_set *, fd_set *, fd_set *, struct timeval *); void -helper_put_filedescriptors(JNIEnv *env, jintArray fdArray, fd_set *fds, int *max_fd) +helper_put_filedescriptors (JNIEnv * env, jintArray fdArray, fd_set * fds, + int *max_fd) { - jint *tmpFDArray = (*env)->GetIntArrayElements(env, fdArray, 0); - int size = (*env)->GetArrayLength(env, fdArray); - int index, fd; - - for( index = 0; index < size; index++) + jint *tmpFDArray = (*env)->GetIntArrayElements (env, fdArray, 0); + int size = (*env)->GetArrayLength (env, fdArray); + int index, fd; + + for (index = 0; index < size; index++) + { + fd = tmpFDArray[index]; + + if (fd > 0) { - fd = tmpFDArray [index]; - - if (fd > 0) - { - FD_SET (tmpFDArray [index], fds); - - if (tmpFDArray [index] > (*max_fd)) - (*max_fd) = tmpFDArray [index]; - } + FD_SET (tmpFDArray[index], fds); + + if (tmpFDArray[index] > (*max_fd)) + (*max_fd) = tmpFDArray[index]; + } } } void -helper_get_filedescriptors (JNIEnv *env, jintArray* fdArray, fd_set *fds) +helper_get_filedescriptors (JNIEnv * env, jintArray * fdArray, fd_set * fds) { - jint *tmpFDArray = (*env)->GetIntArrayElements(env, fdArray, 0); - int size = (*env)->GetArrayLength(env, fdArray); - int index, fd; + jint *tmpFDArray = (*env)->GetIntArrayElements (env, fdArray, 0); + int size = (*env)->GetArrayLength (env, fdArray); + int index, fd; - for (index = 0; index < size; index++) + for (index = 0; index < size; index++) { - fd = tmpFDArray [index]; + fd = tmpFDArray[index]; if (fd < 0 || !FD_ISSET (fd, fds)) - tmpFDArray [index] = 0; + tmpFDArray[index] = 0; } } void -helper_reset (JNIEnv *env, jintArray* fdArray) +helper_reset (JNIEnv * env, jintArray * fdArray) { - jint* tmpFDArray = (*env)->GetIntArrayElements(env, fdArray, 0); - int size = (*env)->GetArrayLength(env, fdArray); - int index; + jint *tmpFDArray = (*env)->GetIntArrayElements (env, fdArray, 0); + int size = (*env)->GetArrayLength (env, fdArray); + int index; - for (index = 0; index < size; index++) - tmpFDArray [index] = 0; + for (index = 0; index < size; index++) + tmpFDArray[index] = 0; } /* A wrapper for select() which ignores EINTR. * Taken from gclib's posix.cc */ int -helper_select (JNIEnv *env, jclass thread_class, jmethodID thread_interrupted, - int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, - struct timeval *timeout) +helper_select (JNIEnv * env, jclass thread_class, + jmethodID thread_interrupted, int n, fd_set * readfds, + fd_set * writefds, fd_set * exceptfds, struct timeval *timeout) { #ifdef HAVE_SYS_SELECT_H - /* If we have a timeout, compute the absolute ending time. */ - struct timeval end, delay, after; - int r; - - if (timeout) + /* If we have a timeout, compute the absolute ending time. */ + struct timeval end, delay, after; + int r; + + if (timeout) + { + gettimeofday (&end, NULL); + + end.tv_usec += timeout->tv_usec; + + if (end.tv_usec >= 1000000) { - gettimeofday (&end, NULL); - - end.tv_usec += timeout->tv_usec; - - if (end.tv_usec >= 1000000) - { - ++end.tv_sec; - end.tv_usec -= 1000000; - } - - end.tv_sec += timeout->tv_sec; - delay = *timeout; + ++end.tv_sec; + end.tv_usec -= 1000000; } - else + + end.tv_sec += timeout->tv_sec; + delay = *timeout; + } + else + { + /* Placate compiler. */ + delay.tv_sec = delay.tv_usec = 0; + } + + while (1) + { + r = select (n, readfds, writefds, exceptfds, timeout ? &delay : NULL); + + if (r != -1 || errno != EINTR) + return r; + + /* Here we know we got EINTR. */ + if ((*env)-> + CallStaticBooleanMethod (env, thread_class, thread_interrupted)) { - /* Placate compiler. */ - delay.tv_sec = delay.tv_usec = 0; + return EINTR; } - while (1) + if (timeout) { - r = select (n, readfds, writefds, exceptfds, - timeout ? &delay : NULL); - - if (r != -1 || errno != EINTR) - return r; - - /* Here we know we got EINTR. */ - if ( (*env)->CallStaticBooleanMethod(env, thread_class, thread_interrupted) ) - { - return EINTR; - } - - if (timeout) - { - gettimeofday (&after, NULL); - - /* Now compute new timeout argument. */ - delay.tv_usec = end.tv_usec - after.tv_usec; - delay.tv_sec = end.tv_sec - after.tv_sec; - - if (delay.tv_usec < 0) - { - --delay.tv_sec; - delay.tv_usec += 1000000; - } - - if (delay.tv_sec < 0) - { - /* We assume that the user wants a valid select() call - * more than precise timing. So if we get a series of - * EINTR we just keep trying with delay 0 until we get a - * valid result. - */ - delay.tv_sec = 0; - } - } + gettimeofday (&after, NULL); + + /* Now compute new timeout argument. */ + delay.tv_usec = end.tv_usec - after.tv_usec; + delay.tv_sec = end.tv_sec - after.tv_sec; + + if (delay.tv_usec < 0) + { + --delay.tv_sec; + delay.tv_usec += 1000000; + } + + if (delay.tv_sec < 0) + { + /* We assume that the user wants a valid select() call + * more than precise timing. So if we get a series of + * EINTR we just keep trying with delay 0 until we get a + * valid result. + */ + delay.tv_sec = 0; + } } + } #else /* HAVE_SYS_SELECT_H */ return 0; #endif @@ -198,91 +195,97 @@ } JNIEXPORT jint JNICALL -Java_gnu_java_nio_VMSelector_select (JNIEnv *env, +Java_gnu_java_nio_VMSelector_select (JNIEnv * env, jclass obj __attribute__ ((__unused__)), jintArray read, jintArray write, - jintArray except, - jlong timeout) + jintArray except, jlong timeout) { - jint result; - jclass thread_class = (*env)->FindClass(env, "java/lang/Thread"); - jmethodID thread_current_thread = (*env)->GetStaticMethodID(env, thread_class, "currentThread", "()Ljava/lang/Thread;"); - jmethodID thread_interrupt = (*env)->GetMethodID(env, thread_class, "interrupt", "()V"); - jmethodID thread_interrupted = (*env)->GetStaticMethodID(env, thread_class, "interrupted", "()Z"); - jobject current_thread; - 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; - char message_buf[BUF_SIZE+1]; - - /* If a legal timeout value isn't given, use NULL. - * This means an infinite timeout. The specification - * also says that a zero timeout should be treated - * as infinite. Otherwise (if the timeout value is legal), - * fill our timeval struct and use it for the select. - */ - if (timeout > 0) + jint result; + jclass thread_class = (*env)->FindClass (env, "java/lang/Thread"); + jmethodID thread_current_thread = + (*env)->GetStaticMethodID (env, thread_class, "currentThread", + "()Ljava/lang/Thread;"); + jmethodID thread_interrupt = + (*env)->GetMethodID (env, thread_class, "interrupt", "()V"); + jmethodID thread_interrupted = + (*env)->GetStaticMethodID (env, thread_class, "interrupted", "()Z"); + jobject current_thread; + 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; + char message_buf[BUF_SIZE + 1]; + + /* If a legal timeout value isn't given, use NULL. + * This means an infinite timeout. The specification + * also says that a zero timeout should be treated + * as infinite. Otherwise (if the timeout value is legal), + * fill our timeval struct and use it for the select. + */ + if (timeout > 0) + { + real_time_data.tv_sec = timeout / 1000; + real_time_data.tv_usec = (timeout % 1000) * 1000; + time_data = &real_time_data; + } + + /* 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 (env, read, &read_fds, &max_fd); + helper_put_filedescriptors (env, write, &write_fds, &max_fd); + helper_put_filedescriptors (env, except, &except_fds, &max_fd); + + /* Actually do the select */ + result = + helper_select (env, thread_class, thread_interrupted, max_fd + 1, + &read_fds, &write_fds, &except_fds, time_data); + + if (result == EINTR) + { + /* The behavior of JRE 1.4.1 is that no exception is thrown + * when the thread is interrupted, but the thread's interrupt + * status is set. Clear all of our select sets and return 0, + * indicating that nothing was selected. + */ + current_thread = + (*env)->CallStaticObjectMethod (env, thread_class, + thread_current_thread); + (*env)->CallVoidMethod (env, current_thread, thread_interrupt); + + helper_reset (env, read); + helper_reset (env, write); + helper_reset (env, except); + + return 0; + } + + if (result < 0) + { + if (strerror_r (errno, message_buf, BUF_SIZE)) { - real_time_data.tv_sec = timeout / 1000; - real_time_data.tv_usec = (timeout % 1000) * 1000; - time_data = &real_time_data; + /* This would mean that message_buf was to small + * to hold the error message. + */ + JCL_ThrowException (env, "java/lang/InternalError", + "Not enough space in message buffer."); + 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 (env, read, &read_fds, &max_fd); - helper_put_filedescriptors (env, write, &write_fds, &max_fd); - helper_put_filedescriptors (env, except, &except_fds, &max_fd); - - /* Actually do the select */ - result = helper_select (env, thread_class, thread_interrupted, max_fd + 1, &read_fds, &write_fds, - &except_fds, time_data); - - if( result == EINTR ) { - /* The behavior of JRE 1.4.1 is that no exception is thrown - * when the thread is interrupted, but the thread's interrupt - * status is set. Clear all of our select sets and return 0, - * indicating that nothing was selected. - */ - current_thread = (*env)->CallStaticObjectMethod(env, thread_class, thread_current_thread); - (*env)->CallVoidMethod(env, current_thread, thread_interrupt); - - helper_reset (env, read); - helper_reset (env, write); - helper_reset (env, except); - - return 0; - } - - if (result < 0) - { - if( strerror_r(errno, message_buf, BUF_SIZE) ) - { - /* This would mean that message_buf was to small - * to hold the error message. - */ - JCL_ThrowException(env, "java/lang/InternalError", - "Not enough space in message buffer."); - return 0; - } - - JCL_ThrowException (env, "java/io/IOException", message_buf); - return 0; - } - - /* Set the file descriptors according to the values returned from select(). */ - helper_get_filedescriptors (env, read, &read_fds); - helper_get_filedescriptors (env, write, &write_fds); - helper_get_filedescriptors (env, except, &except_fds); + JCL_ThrowException (env, "java/io/IOException", message_buf); + return 0; + } - return result; -} + /* Set the file descriptors according to the values returned from select(). */ + helper_get_filedescriptors (env, read, &read_fds); + helper_get_filedescriptors (env, write, &write_fds); + helper_get_filedescriptors (env, except, &except_fds); + return result; +}