OK. Hibbego.

I'm checking in my patch that I've been writing about recently. Again,
the patch itself is large, so I'll just post a link to it:

  <http://metastatic.org/source/io-nio-final.patch>

To summarize, this patch:

  * Implements most non-blocking operations "for real" -- that is, using
native function calls on file descriptors in non-blocking mode.
Blocking-IO APIs now defer to the NIO API, in blocking mode.

  * Refactors our code and the VM interfaces to keep no native state
(such as file descriptor integers) in core classes, but instead in VM
classes. A number of VM classes have, unfortunately, been modified to
support this, but I think in general these changes are for the best.

  * Implements NetworkInterface using getifaddrs.

  * Adds a Selector that uses kqueue, the preferred event notification
mechanism on OS X.

There is more work to do here. In particular, too much code in the core
classes knows about file descriptor integers; this too should be moved
to the VM classes. Also, an epoll-based selector for Linux would be nice
to have.

If this breaks anything at all (the Mauve tests I've run, on OS X and
Linux, seem to show that this code works well) please complain (fiercely
if you must ;-) to me about it. It's a little uncouth to check in such a
large patch, sure, but I think this is the good and correct way to
implement IO in Java.

I've updated NEWS to explain these changes.

The change log is also large, but detailed about lots of little changes:

2006-09-16  Casey Marshall  <[EMAIL PROTECTED]>

        * NEWS: updated.
        * configure.ac (AC_CHECK_HEADERS): check for `sys/event.h'.
        (AC_CHECK_FUNCS): add checks for readv, writev, getifaddrs,
        kqueue, and kevent.
        (HAVE_INET6): define if IPv6 is supported.
        * gnu/java/net/PlainDatagramSocketImpl.java (channel): new field.
        (native_fd): removed.
        (impl): new field.
        (<init>): throw IOException; initialize fields.
        (finalize): removed.
        (getNativeFD): removed.
        (bind): use `PlainSocketImpl.bind.'
        (create): use `PlainSocketImpl.initSocket.'
        (disconnect): use `PlainSocketImpl.disconnect.'
        (getLocalPort): new method.
        (send): use `VMChannel.send.'
        (receive): use `VMChannel.receive.'
        (setOption): use `PlainSocketImpl.setOption.'
        (getOption): use `PlainSocketImpl.getOption.'
        (close): use `VMChannel.State.close.'
        (join): use `PlainSocketImpl.join.'
        (leave): use `PlainSocketImpl.leave.'
        (joinGroup, leaveGroup): implemented.
        * gnu/java/net/PlainSocketImpl.java: make non-final.
        (native_fd): removed.
        (impl): new field.
        (channel): new field.
        (<init>): initialize `impl.'
        (finalize, getNativeFD): removed.
        (setOption): use `PlainSocketImpl.setOption.'
        (getOption): use `PlainSocketImpl.getOption.'
        (shutdownInput): use `PlainSocketImpl.shutdownInput.'
        (shutdownOutput): use `PlainSocketImpl.shutdownOutput.'
        (create): create `channel,' initialize `impl's native state.
        (connect): use `connect(SocketAddress, int).'
        (connect): use `SocketChannelImpl.connect;' initialize `address'
        and `port.'
        (bind): use `VMPlainSocketImpl.bind.'
        (listen): use `VMPlainSocketImpl.listen.'
        (accept): use `SocketChannelImpl.accept.'
        (available): use `VMChannel.available.'
        (close): use `PlainSocketImpl.close.'
        (sendUrgentData): use `PlainSocketImpl.sendUrgentData.'
        (getVMChannel, getInetAddress, getLocalPort, getLocalAddress,
        getPort): new methods.
        (SocketInputStream.read): use `VMChannel.read.'
        (SocketInputStream.read): use `SocketChannel.read.'
        (SocketOutputStream.write): use `VMChannel.write.'
        (SocketOutputStream.write): use `SocketChannel.write.'
        * gnu/java/nio/DatagramChannelImpl.java: implement VMChannel.
        (channel): new field.
        (<init>): initialize `channel.'
        (implCloseSelectableChannel): use `VMChannel.close.'
        (implConfigureBlocking): use `VMChannel.setBlocking.'
        (connect): use `VMChannel.connect.'
        (disconnect): use `VMChannel.disconnect.'
        (isConnected): use `VMChannel.getPeerAddress.'
        (write): use `VMChannel.write.'
        (write): use `VMChannel.writeGathering.'
        (read): use `VMChannel.read.'
        (read): use `VMChannel.readScattering.'
        (receive): use `VMChannel.receive.'
        (send): use `VMChannel.send.'
        (getVMChannel): new method.
        * gnu/java/nio/DatagramChannelSelectionKey.java (getNativeFD):
        access native FD through VMChannel.State.
        * gnu/java/nio/FileChannelImpl.java: moved from
        gnu/java/nio/channels/FileChannelImpl.java.
        * gnu/java/nio/FileLockImpl.java: fix imports.
        * gnu/java/nio/KqueueSelectionKeyImpl.java: new file.
        * gnu/java/nio/KqueueSelectorImpl.java: new file.
        * gnu/java/nio/NIOSocket.java (impl): removed.
        (channel): new field.
        (<init>): init superclass with a `NIOSocketImpl;' init `channel.'
        (getPlainSocketImpl, setChannel): removed.
        (isConnected): new method.
        * gnu/java/nio/NIOSocketImpl.java: new file.
        * gnu/java/nio/PipeImpl.java (SourceChannelImpl): implement
        `VMChannelOwner.'
        (SourceChannelImpl.native_fd): removed.
        (SourceChannelImpl.<init>): init with a `VMChannel.'
        (SourceChannelImpl.getNativeFD): removed.
        (SourceChannelImpl.getVMChannel): new method.
        (SourceChannelImpl.implCloseSelectableChannel): implement.
        (SinkChannelImpl): implement `VMChannelOwner.'
        (SinkChannelImpl.native_fd): removed.
        (SinkChannelImpl.<init>): init with a `VMChannel.'
        (SinkChannelImpl.implCloseSelectableChannel): implement.
        (SinkChannelImpl.getNativeFD): removed.
        (SinkChannelImpl.getVMChannel): new method.
        * gnu/java/nio/SelectionKeyImpl.java (getNativeFD): mark
        deprecated.
        * gnu/java/nio/SelectorProviderImpl.java (SELECTOR_IMPL_KQUEUE,
        SELECTOR_IMPL_EPOLL, SELECTOR_IMPL): new constants.
        (openSelector): return kqueue selector if available.
        * gnu/java/nio/ServerSocketChannelImpl.java: implement
        `VMChannelOwner.'
        (channel): new field.
        (<init>): init `channel.'
        (finalizer): check if the `VMChannel.State' is valid.
        (implCloseSelectableChannel): use `VMChannel.close.'
        (implConfigureBlocking): use `VMChannel.setBlocking.'
        (accept): use `VMChannel.accept.'
        (getVMChannel): new method.
        * gnu/java/nio/ServerSocketChannelSelectionKey.java (getNativeFD):
        access native FD through `VMChannel.State.'
        * gnu/java/nio/SocketChannelImpl.java: implement `VMChannelOwner.'
        (impl): removed.
        (channel, connected, connectAddress): new field.
        (<init>): new constructors.
        (getPlainSocketImpl): removed.
        (implCloseSelectableChannel): use `VMChannel.close.'
        (implConfigureBlocking): use `VMChannel.setBlocking.'
        (connect): use `connect(SocketAddress,int).'
        (connect): use `VMChannel.connect.'
        (finishConnect): don't use a selector.
        (isConnected): use `VMChannel.getPeerAddress.'
        (read): use `VMChannel.read.'
        (read): use `VMChannel.readScattering.'
        (write): use `VMChannel.write.'
        (write): use `VMChannel.writeGathering.'
        (getVMChannel): new method.
        * gnu/java/nio/SocketChannelSelectionKey.java (getNativeFD): get
        native FD from `VMChannel.State.'
        * gnu/java/nio/SocketChannelSelectionKeyImpl.java (getNativeFD):
        get native FD from `VMChannel.State.'
        * gnu/java/nio/VMChannelOwner.java: new file.
        * gnu/java/nio/channels/FileChannelImpl.java: removed.
        * include/Makefile.am: generate `gnu_java_nio_FileChannelImpl.h'
        and `gnu_java_nio_KqueueSelectorImpl.h;' don't generate
        `gnu_java_nio_channels_FileChannelImpl.h.'
        * include/gnu_java_net_VMPlainSocketImpl.h: regenerated.
        * include/gnu_java_nio_FileChannelImpl.h: new file.
        * include/gnu_java_nio_KqueueSelectorImpl.h: new file.
        * include/gnu_java_nio_VMChannel.h: regenerated.
        * include/gnu_java_nio_VMPipe.h: regenerated.
        * include/java_net_VMNetworkInterface.h: regenerated.
        * java/io/FileDescriptor.java: fix imports.
        * java/io/FileInputStream.java (<init>): handle exceptions.
        (read): wrap the destination arary.
        * java/io/FileOutputStream.java (<init>): handle exceptions.
        (write): wrap the source array.
        * java/io/RandomAccessFile.java (<init>): handle exceptions.
        * java/net/DatagramSocket.java (<init>): handle exceptions.
        (receive): handle length/port setting.
        (connect): bind to any address/port if the argument is null.
        * java/net/NetworkInterface.java (name, inetAddress): removed.
        (netif): new field.
        (<init>): make private.
        (getName): return `netif.name.'
        (getInetAddresses): access `netif.addresses.'
        (getDisplayName): return `netif.name.'
        (getByName, getByAddress): handle changes to `VMNetworkInterface.'
        (condense): removed.
        (getNetworkInterfaces): handle changes to `VMNetworkInterface.'
        (equals): compare `netif' fields.
        (hashCode): get hash codes from `netif.'
        (toString): use a StringBuffer.
        * java/net/ServerSocket.java (close): don't set `impl' to null.
        (isClosed): use `VMChannel.State.isClosed.'
        * java/net/Socket.java (getLocalAddress): don't use `getOption' if
        the `SocketImpl' is a `PlainSocketImpl.'
        (close): just close the `impl.'
        (toString): use `super.toString' in the value we return.
        (isConnected): just access `impl,' not `getImpl.'
        (isBound): use `PlainSocketImpl' methods if we can.
        (isClosed): look at `VMChannel.State.'
        * native/jni/classpath/jcl.c (JNI_OnLoad): new function.
        (JCL_NewRawDataObject): don't initialize cached fields here; throw
        an exception if they were not.
        (JCL_GetRawData): throw an exception if cached fields weren't
        created.
        * native/jni/java-lang/java_lang_VMProcess.c: handle
        FileChannelImpl move.
        * native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c
        (IO_EXCEPTION, SOCKET_EXCEPTION, BIND_EXCEPTION,
        THROW_NO_NETWORK): new macros.
        (Java_gnu_java_net_VMPlainSocketImpl_bind): reipmlemented.
        (Java_gnu_java_net_VMPlainSocketImpl_bind6): new function.
        (Java_gnu_java_net_VMPlainSocketImpl_listen): reimplemented.
        (java_sockopt): new enum.
        (Java_gnu_java_net_VMPlainSocketImpl_setOption): reimplemented.
        (Java_gnu_java_net_VMPlainSocketImpl_getOption): reimplemented.
        (Java_gnu_java_net_VMPlainSocketImpl_shutdownInput):
        reimplemented.
        (Java_gnu_java_net_VMPlainSocketImpl_shutdownOutput):
        reimplemented.
        (Java_gnu_java_net_VMPlainSocketImpl_sendUrgentData): new
        function.
        (Java_gnu_java_net_VMPlainSocketImpl_join): new function.
        (Java_gnu_java_net_VMPlainSocketImpl_join6): new function.
        (Java_gnu_java_net_VMPlainSocketImpl_read): removed.
        (Java_gnu_java_net_VMPlainSocketImpl_leave): new function.
        (Java_gnu_java_net_VMPlainSocketImpl_leave6): new function.
        (Java_gnu_java_net_VMPlainSocketImpl_joinGroup): new function.
        (Java_gnu_java_net_VMPlainSocketImpl_write): removed.
        (Java_gnu_java_net_VMPlainSocketImpl_joinGroup6): new function.
        (Java_gnu_java_net_VMPlainSocketImpl_leaveGroup): new function.
        (Java_gnu_java_net_VMPlainSocketImpl_leaveGroup6): new function.
        (getif_address): new function.
        (getif_index): new function.
        * native/jni/java-net/java_net_VMNetworkInterface.c
        (java_net_VMNetworkInterface_init,
        java_net_VMNetworkInterface_addAddress): new file-scope globals.
        (Java_java_net_VMNetworkInterface_initIds): new function.
        (struct netif_entry): new struct.
        (free_netif_list): new function.
        (Java_java_net_VMNetworkInterface_getInterfaces): removed.
        (Java_java_net_VMNetworkInterface_getVMInterfaces): new function.
        * native/jni/java-nio/Makefile.am (libjavanio_la_SOURCES): remove
        gnu_java_nio_channels_FileChannelImpl.c, add
        gnu_java_nio_KqueueSelectorImpl.c.
        * native/jni/java-nio/gnu_java_nio_KqueueSelectorImpl.c: new file.
        * native/jni/java-nio/gnu_java_nio_VMChannel.c
        (INTERRUPTED_IO_EXCEPTION, SOCKET_TIMEOUT_EXCEPTION, ALIGN_UP,
        ALIGN_DOWN): new macros.
        (JCL_init_buffer): get the address through GetDirectBufferAddress
        if possible.
        (Java_gnu_java_nio_VMChannel_stdin_1fd,
        Java_gnu_java_nio_VMChannel_stdout_1fd,
        Java_gnu_java_nio_VMChannel_stderr_1fd): new functions.
        (Java_gnu_java_nio_VMChannel_setBlocking): fix setting blocking
        value.
        (Java_gnu_java_nio_VMChannel_read): renamed...
        (Java_gnu_java_nio_VMChannel_read__ILjava_nio_ByteBuffer_2): to
        this; handle interrupted IO; add HAVE_READ check.
        (Java_gnu_java_nio_VMChannel_write): renamed...
        (Java_gnu_java_nio_VMChannel_write__ILjava_nio_ByteBuffer_2): to
        this; handle zero-length write; add HAVE_WRITE check.
        (Java_gnu_java_nio_VMChannel_receive): new function.
        (Java_gnu_java_nio_VMChannel_send): new function.
        (Java_gnu_java_nio_VMChannel_send6): new function.
        (Java_gnu_java_nio_VMChannel_read__I): new function.
        (Java_gnu_java_nio_VMChannel_write__II): new function.
        (Java_gnu_java_nio_VMChannel_socket): new function.
        (Java_gnu_java_nio_VMChannel_connect): new function.
        (Java_gnu_java_nio_VMChannel_connect6): new function.
        (Java_gnu_java_nio_VMChannel_getsockname): new function.
        (Java_gnu_java_nio_VMChannel_getpeername): new function.
        (Java_gnu_java_nio_VMChannel_accept): new function.
        (Java_gnu_java_nio_VMChannel_disconnect): new function.
        (Java_gnu_java_nio_VMChannel_close): new function.
        (Java_gnu_java_nio_VMChannel_available): new function.
        (FileChannel_mode): new enum.
        (Java_gnu_java_nio_VMChannel_open): new function.
        (Java_gnu_java_nio_VMChannel_position): new function.
        (Java_gnu_java_nio_VMChannel_seek): new function.
        (Java_gnu_java_nio_VMChannel_truncate): new funciton.
        (Java_gnu_java_nio_VMChannel_lock): new function.
        (Java_gnu_java_nio_VMChannel_unlock): new function.
        (Java_gnu_java_nio_VMChannel_size): new function.
        (Java_gnu_java_nio_VMChannel_map): new function.
        (Java_gnu_java_nio_VMChannel_flush): new function.
        * native/jni/java-nio/gnu_java_nio_VMPipe.c
        (Java_gnu_java_nio_VMPipe_init): removed.
        (Java_gnu_java_nio_VMPipe_pipe0): new function.
        * native/jni/java-nio/javanio.c: new file.
        * native/jni/java-nio/javanio.h: new file.
        * native/jni/native-lib/cpnet.c (cpnet_getHostByName): fix for
        systems without `gethostbyname_r.'
        * vm/reference/gnu/java/net/VMPlainSocketImpl.java (nfd): new
        field.
        (<init>, <init>): new constructors.
        (setOption, getOption): make instance methods; defer to native
        implementation.
        (connect): removed.
        (bind): make an instance method; defer to native methods.
        (accept): removed.
        (available): removed.
        (listen): make an instance method; defer to native method.
        (read): removed.
        (join, leave): new methods.
        (write): removed.
        (joinGroup, leaveGroup): new methods.
        (shutdownInput, shutdownOutput): make instance methods.
        (sendUrgentData): removed.
        (State): new class.
        * vm/reference/gnu/java/nio/VMChannel.java: make final.
        (fd): removed.
        (nfd): new field.
        (<init>): new, public constructors.
        (getVMChannel): methods removed.
        (getState, getStdin, getStdout, getStderr, stdin_fd, stdout_fd,
        stderr_fd): new methods.
        (setBlocking): make an instance method.
        (available): new method.
        (read): get native fd from `nfd.'
        (read): new single-byte read method.
        (readScattering): get native fd from `nfd.'
        (receive): new method.
        (write, writeGathering): get native fd from `nfd.'
        (send): new method.
        (write): new single-byte write method.
        (initSocket): new method.
        (connect): new method.
        (disconnect): new method.
        (getLocalAddress): new method.
        (getPeerAddress): new method.
        (accept): new method.
        (openFile): new method.
        (position): new method.
        (seek): new method.
        (truncate): new method.
        (lock): new method.
        (unlock): new method.
        (size): new method.
        (map): new method.
        (flush): new method.
        (close): new method.
        (State): new class.
        (Kind): new class.
        * vm/reference/gnu/java/nio/VMPipe.java (init): removed.
        (pipe, pipe0): new method.
        * vm/reference/java/net/VMNetworkInterface.java (name, addresses):
        new fields.
        (<clinit>): call `initIds.'
        (initIds): new method.
        (getInterfaces): removed.
        (getVMInterfaces): new method.
        (addAddress): new method.
        * vm/reference/java/nio/channels/VMChannels.java: fix imports.

Thanks.

Reply via email to