diff options
author | Casey Marshall <csm@gnu.org> | 2006-09-20 21:39:41 +0000 |
---|---|---|
committer | Casey Marshall <csm@gnu.org> | 2006-09-20 21:39:41 +0000 |
commit | a67151b3017805e1d027f1b170777106a5804f60 (patch) | |
tree | 54ea95163787f564dd7e74bc0bb457e15629354d /native | |
parent | 084a2d68af18443b005a1c50a20edb588d1155cb (diff) | |
download | classpath-a67151b3017805e1d027f1b170777106a5804f60.tar.gz |
2006-09-20 Casey Marshall <csm@gnu.org>
* configure.ac (AC_CHECK_HEADERS): check for `sys/epoll.h.'
(AC_CHECK_FUNCS): check for `epoll_create.'
* gnu/java/nio/EpollSelectionKeyImpl.java: new file.
* gnu/java/nio/EpollSelectorImpl.java: new file.
* gnu/java/nio/SelectorProviderImpl.java (epoll_failed): new class
field.
(openSelector): return epoll selector if requested and available.
* include/Makefile.am (H_FILES): add gnu_java_nio_EpollSelectorImpl.h.
(gnu_java_nio_EpollSelectorImpl.h): new target.
* include/gnu_java_nio_EpollSelectorImpl.h: new file.
* native/jni/java-nio/Makefile.am (libjavanio_la_SOURCES): add
gnu_java_nio_EpollSelectorImpl.c.
* native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c: new file.
Diffstat (limited to 'native')
-rw-r--r-- | native/jni/java-nio/Makefile.am | 1 | ||||
-rw-r--r-- | native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c | 405 |
2 files changed, 406 insertions, 0 deletions
diff --git a/native/jni/java-nio/Makefile.am b/native/jni/java-nio/Makefile.am index c1d71ed7e..a4b830cd4 100644 --- a/native/jni/java-nio/Makefile.am +++ b/native/jni/java-nio/Makefile.am @@ -8,6 +8,7 @@ libjavanio_la_SOURCES = gnu_java_nio_VMPipe.c \ gnu_java_nio_channels_FileChannelImpl.c \ java_nio_MappedByteBufferImpl.c \ java_nio_VMDirectByteBuffer.c \ + gnu_java_nio_EpollSelectorImpl.c \ gnu_java_nio_KqueueSelectorImpl.c \ javanio.h diff --git a/native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c b/native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c new file mode 100644 index 000000000..b205d61f8 --- /dev/null +++ b/native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c @@ -0,0 +1,405 @@ +/* gnu_java_nio_EpollSelectorImpl.c -- + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at +your option) any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 +USA + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif /* HAVE_CONFIG_H */ + +#ifdef HAVE_SYS_EPOLL_H +#include <sys/epoll.h> +#endif /* HAVE_SYS_EPOLL_H */ + +#include <gnu_java_nio_EpollSelectorImpl.h> +#include <jcl.h> +#include <errno.h> +#include <string.h> + +#define IO_EXCEPTION "java/io/IOException" + +/* #define TRACE_EPOLL 1 */ + + +/* + * Class: gnu_java_nio_EpollSelectorImpl + * Method: epoll_supported + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL +Java_gnu_java_nio_EpollSelectorImpl_epoll_1supported (JNIEnv *e __attribute__((unused)), + jclass c __attribute__((unused))) +{ +#ifdef HAVE_EPOLL_CREATE + return JNI_TRUE; +#else + return JNI_FALSE; +#endif /* HAVE_EPOLL_CREATE */ +} + +/* + * Class: gnu_java_nio_EpollSelectorImpl + * Method: sizeof_struct + * Signature: ()I + */ +JNIEXPORT jint JNICALL +Java_gnu_java_nio_EpollSelectorImpl_sizeof_1struct (JNIEnv *env, + jclass c __attribute__((unused))) +{ +#ifdef HAVE_EPOLL_CREATE + (void) env; +#ifdef TRACE_EPOLL + fprintf (stderr, "%s: sizeof is %d\n", __FUNCTION__, sizeof (struct epoll_event)); +#endif /* TRACE_EPOLL */ + return sizeof (struct epoll_event); +#else + JCL_ThrowException (env, "java/lang/InternalError", "epoll support not available"); + return -1; +#endif /* HAVE_EPOLL_CREATE */ +} + +/* + * Class: gnu_java_nio_EpollSelectorImpl + * Method: epoll_create + * Signature: (I)I + */ +JNIEXPORT jint JNICALL +Java_gnu_java_nio_EpollSelectorImpl_epoll_1create (JNIEnv *env, + jclass c __attribute__((unused)), + jint size) +{ +#ifdef HAVE_EPOLL_CREATE + int fd = epoll_create (size); + +#ifdef TRACE_EPOLL + fprintf (stderr, "%s: epoll_create returns %d\n", __FUNCTION__, fd); +#endif /* TRACE_EPOLL */ + + if (fd == -1) + { + if (ENOSYS == errno) + JCL_ThrowException (env, "java/lang/InternalError", + strerror (errno)); + else + JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); + } + return fd; +#else + (void) size; + JCL_ThrowException (env, "java/lang/InternalError", "epoll support not available"); + return -1; +#endif /* HAVE_EPOLL_CREATE */ +} + +/* + * Class: gnu_java_nio_EpollSelectorImpl + * Method: epoll_add + * Signature: (III)V + */ +JNIEXPORT void JNICALL +Java_gnu_java_nio_EpollSelectorImpl_epoll_1add (JNIEnv *env, + jclass c __attribute__((unused)), + jint efd, jint fd, jint ops) +{ +#ifdef HAVE_EPOLL_CREATE + struct epoll_event event; + + memset (&event, 0, sizeof (struct epoll_event)); + + if ((ops & gnu_java_nio_EpollSelectorImpl_OP_ACCEPT) != 0 + || (ops & gnu_java_nio_EpollSelectorImpl_OP_READ) != 0) + event.events = EPOLLIN; + + if ((ops & gnu_java_nio_EpollSelectorImpl_OP_CONNECT) != 0 + || (ops & gnu_java_nio_EpollSelectorImpl_OP_WRITE) != 0) + event.events |= EPOLLOUT; + + event.data.fd = fd; + +#ifdef TRACE_EPOLL + fprintf (stderr, "%s: adding struct epoll_event { events: %o; data.fd: %d }\n", + __FUNCTION__, event.events, event.data.fd); +#endif /* TRACE_EPOLL */ + + if (epoll_ctl (efd, EPOLL_CTL_ADD, fd, &event) == -1) + { + if (ENOSYS == errno) + JCL_ThrowException (env, "java/lang/InternalError", + strerror (errno)); + else + JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); + } +#else + (void) efd; + (void) fd; + (void) ops; + JCL_ThrowException (env, "java/lang/InternalError", "epoll support not available"); +#endif /* HAVE_EPOLL_CREATE */ +} + + +/* + * Class: gnu_java_nio_EpollSelectorImpl + * Method: epoll_modify + * Signature: (III)V + */ +JNIEXPORT void JNICALL +Java_gnu_java_nio_EpollSelectorImpl_epoll_1modify (JNIEnv *env, + jclass c __attribute__((unused)), + jint efd, jint fd, jint ops) +{ +#ifdef HAVE_EPOLL_CREATE + struct epoll_event event; + + memset (&event, 0, sizeof (struct epoll_event)); + + if ((ops & gnu_java_nio_EpollSelectorImpl_OP_ACCEPT) != 0 + || (ops & gnu_java_nio_EpollSelectorImpl_OP_READ) != 0) + event.events = EPOLLIN; + + if ((ops & gnu_java_nio_EpollSelectorImpl_OP_CONNECT) != 0 + || (ops & gnu_java_nio_EpollSelectorImpl_OP_WRITE) != 0) + event.events |= EPOLLOUT; + + event.data.fd = fd; + +#ifdef TRACE_EPOLL + fprintf (stderr, "%s: modding struct epoll_event { events: %o; data.fd: %d }\n", + __FUNCTION__, event.events, event.data.fd); +#endif /* TRACE_EPOLL */ + + if (epoll_ctl (efd, EPOLL_CTL_MOD, fd, &event) == -1) + { + if (ENOSYS == errno) + JCL_ThrowException (env, "java/lang/InternalError", + strerror (errno)); + else + JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); + } +#else + (void) efd; + (void) fd; + (void) ops; + JCL_ThrowException (env, "java/lang/InternalError", "epoll support not available"); +#endif /* HAVE_EPOLL_CREATE */ +} + + +/* + * Class: gnu_java_nio_EpollSelectorImpl + * Method: epoll_delete + * Signature: (II)V + */ +JNIEXPORT void JNICALL +Java_gnu_java_nio_EpollSelectorImpl_epoll_1delete (JNIEnv *env, + jclass c __attribute__((unused)), + jint efd, jint fd) +{ +#ifdef HAVE_EPOLL_CREATE + struct epoll_event event; + + memset (&event, 0, sizeof (struct epoll_event)); + event.data.fd = fd; + +#ifdef TRACE_EPOLL + fprintf (stderr, "%s: delete events on fd %d\n", __FUNCTION__, fd); +#endif /* TRACE_EPOLL */ + + /* Older kernel versions require a non-null `event' parameter, + * even though it is ignored by this call. + */ + if (epoll_ctl (efd, EPOLL_CTL_DEL, fd, &event) == -1) + { + if (ENOSYS == errno) + JCL_ThrowException (env, "java/lang/InternalError", + strerror (errno)); + else + JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); + } +#else + (void) efd; + (void) fd; + JCL_ThrowException (env, "java/lang/InternalError", "epoll support not available"); +#endif /* HAVE_EPOLL_CREATE */ +} + +/* + * Class: gnu_java_nio_EpollSelectorImpl + * Method: epoll_wait + * Signature: (ILjava/nio/ByteBuffer;II)I + */ +JNIEXPORT jint JNICALL +Java_gnu_java_nio_EpollSelectorImpl_epoll_1wait (JNIEnv *env, + jclass c __attribute__((unused)), + jint efd, jobject nstate, + jint num_events, jint timeout) +{ +#ifdef HAVE_EPOLL_CREATE + void *p = (*env)->GetDirectBufferAddress (env, nstate); + struct epoll_event *events = (struct epoll_event *) p; + int ret; + + if (p == NULL) + { + if (!(*env)->ExceptionCheck (env)) + JCL_ThrowException (env, IO_EXCEPTION, "getting native state failed"); + return -1; + } + +#ifdef TRACE_EPOLL + fprintf (stderr, "%s: events: %p; num_events: %d; timeout: %d\n", + __FUNCTION__, p, num_events, timeout); +#endif /* TRACE_EPOLL */ + + ret = epoll_wait (efd, events, num_events, timeout); + if (ret == -1) + { + if (ENOSYS == errno) + JCL_ThrowException (env, "java/lang/InternalError", + strerror (errno)); + else + JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); + } + +#ifdef TRACE_EPOLL + fprintf (stderr, " epoll_wait returns %d\n", ret); + { + int i; + for (i = 0; i < ret; i++) + { + fprintf (stderr, " [%4i]: events: %o; data.fd: %d\n", i, events[i].events, + events[i].data.fd); + } + } + fflush (stderr); +#endif /* TRACE_EPOLL */ + + return ret; +#else + (void) efd; + (void) nstate; + (void) num_events; + (void) timeout; + JCL_ThrowException (env, "java/lang/InternalError", "epoll support not available"); + return -1; +#endif /* HAVE_EPOLL_CREATE */ +} + + +/* + * Class: gnu_java_nio_EpollSelectorImpl + * Method: selected_fd + * Signature: (Ljava/nio/ByteBuffer;)I + */ +JNIEXPORT jint JNICALL +Java_gnu_java_nio_EpollSelectorImpl_selected_1fd (JNIEnv *env, + jclass c __attribute__((unused)), + jobject value) +{ +#ifdef HAVE_EPOLL_CREATE + void *p = (*env)->GetDirectBufferAddress (env, value); + struct epoll_event *event = (struct epoll_event *) p; + +#ifdef TRACE_EPOLL + fprintf (stderr, "%s: event: %p\n", __FUNCTION__, p); +#endif /* TRACE_EPOLL */ + + if (p == NULL) + { + if (!(*env)->ExceptionCheck (env)) + JCL_ThrowException (env, "java/lang/InternalError", + "getting native state failed"); + return -1; + } + +#ifdef TRACE_EPOLL + fprintf (stderr, " data.fd: %d\n", event->data.fd); + fflush (stderr); +#endif /* TRACE_EPOLL */ + + return event->data.fd; +#else + (void) value; + JCL_ThrowException (env, "java/lang/InternalError", "epoll support not available"); + return -1; +#endif /* HAVE_EPOLL_CREATE */ +} + + +/* + * Class: gnu_java_nio_EpollSelectorImpl + * Method: selected_ops + * Signature: (Ljava/nio/ByteBuffer;)I + */ +JNIEXPORT jint JNICALL +Java_gnu_java_nio_EpollSelectorImpl_selected_1ops (JNIEnv *env, + jclass c __attribute__((unused)), + jobject value) +{ +#ifdef HAVE_EPOLL_CREATE + void *p = (*env)->GetDirectBufferAddress (env, value); + struct epoll_event *event = (struct epoll_event *) p; + int ret = 0; + +#ifdef TRACE_EPOLL + fprintf (stderr, "%s: event: %p\n", __FUNCTION__, p); +#endif /* TRACE_EPOLL */ + + if (p == NULL) + { + if (!(*env)->ExceptionCheck (env)) + JCL_ThrowException (env, "java/lang/InternalError", + "getting native state failed"); + return -1; + } + + if ((event->events & EPOLLIN) != 0) + ret |= gnu_java_nio_EpollSelectorImpl_OP_ACCEPT | gnu_java_nio_EpollSelectorImpl_OP_READ; + if ((event->events & EPOLLOUT) != 0) + ret |= gnu_java_nio_EpollSelectorImpl_OP_CONNECT | gnu_java_nio_EpollSelectorImpl_OP_WRITE; + +#ifdef TRACE_EPOLL + fprintf (stderr, " events: %o\n", event->events); + fflush (stderr); +#endif /* TRACE_EPOLL */ + + return ret; +#else + (void) value; + JCL_ThrowException (env, "java/lang/InternalError", "epoll support not available"); + return -1; +#endif /* HAVE_EPOLL_CREATE */ +} |