|
From: <hag...@us...> - 2006-12-14 09:24:38
|
Revision: 2907
http://jnode.svn.sourceforge.net/jnode/?rev=2907&view=rev
Author: hagar-wize
Date: 2006-12-14 01:24:37 -0800 (Thu, 14 Dec 2006)
Log Message:
-----------
Classpath patches
Modified Paths:
--------------
trunk/core/src/classpath/gnu/gnu/java/nio/DatagramChannelImpl.java
trunk/core/src/classpath/gnu/gnu/java/nio/DatagramChannelSelectionKey.java
trunk/core/src/classpath/gnu/gnu/java/nio/FileLockImpl.java
trunk/core/src/classpath/gnu/gnu/java/nio/NIOSocket.java
Added Paths:
-----------
trunk/core/src/classpath/gnu/gnu/java/nio/EpollSelectionKeyImpl.java
trunk/core/src/classpath/gnu/gnu/java/nio/EpollSelectorImpl.java
trunk/core/src/classpath/gnu/gnu/java/nio/KqueueSelectionKeyImpl.java
trunk/core/src/classpath/gnu/gnu/java/nio/KqueueSelectorImpl.java
trunk/core/src/classpath/gnu/gnu/java/nio/NIOSocketImpl.java
Modified: trunk/core/src/classpath/gnu/gnu/java/nio/DatagramChannelImpl.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/nio/DatagramChannelImpl.java 2006-12-13 19:25:39 UTC (rev 2906)
+++ trunk/core/src/classpath/gnu/gnu/java/nio/DatagramChannelImpl.java 2006-12-14 09:24:37 UTC (rev 2907)
@@ -55,8 +55,10 @@
* @author Michael Koch
*/
public final class DatagramChannelImpl extends DatagramChannel
+ implements VMChannelOwner
{
private NIODatagramSocket socket;
+ private VMChannel channel;
/**
* Indicates whether this channel initiated whatever operation
@@ -64,6 +66,16 @@
*/
private boolean inChannelOperation;
+ protected DatagramChannelImpl (SelectorProvider provider)
+ throws IOException
+ {
+ super (provider);
+ socket = new NIODatagramSocket (new PlainDatagramSocketImpl(), this);
+ channel = new VMChannel();
+ channel.initSocket(false);
+ configureBlocking(true);
+ }
+
/**
* Indicates whether our datagram socket should ignore whether
* we are set to non-blocking mode. Certain operations on our
@@ -85,14 +97,6 @@
inChannelOperation = b;
}
- protected DatagramChannelImpl (SelectorProvider provider)
- throws IOException
- {
- super (provider);
- socket = new NIODatagramSocket (new PlainDatagramSocketImpl(), this);
- configureBlocking(true);
- }
-
public DatagramSocket socket ()
{
return socket;
@@ -101,13 +105,13 @@
protected void implCloseSelectableChannel ()
throws IOException
{
- socket.close ();
+ channel.close();
}
protected void implConfigureBlocking (boolean blocking)
throws IOException
{
- socket.setSoTimeout (blocking ? 0 : NIOConstants.DEFAULT_TIMEOUT);
+ channel.setBlocking(blocking);
}
public DatagramChannel connect (SocketAddress remote)
@@ -116,29 +120,43 @@
if (!isOpen())
throw new ClosedChannelException();
- socket.connect (remote);
+ try
+ {
+ channel.connect((InetSocketAddress) remote, 0);
+ }
+ catch (ClassCastException cce)
+ {
+ throw new IOException("unsupported socked address type");
+ }
return this;
}
public DatagramChannel disconnect ()
throws IOException
{
- socket.disconnect ();
+ channel.disconnect();
return this;
}
- public boolean isConnected ()
+ public boolean isConnected()
{
- return socket.isConnected ();
+ try
+ {
+ return channel.getPeerAddress() != null;
+ }
+ catch (IOException ioe)
+ {
+ return false;
+ }
}
-
+
public int write (ByteBuffer src)
throws IOException
{
if (!isConnected ())
throw new NotYetConnectedException ();
- return send (src, socket.getRemoteSocketAddress());
+ return channel.write(src);
}
public long write (ByteBuffer[] srcs, int offset, int length)
@@ -152,13 +170,11 @@
|| (length < 0)
|| (length > (srcs.length - offset)))
throw new IndexOutOfBoundsException();
-
- long result = 0;
- for (int index = offset; index < offset + length; index++)
- result += write (srcs [index]);
-
- return result;
+ /* We are connected, meaning we will write these bytes to
+ * the host we connected to, so we don't need to explicitly
+ * give the host. */
+ return channel.writeGathering(srcs, offset, length);
}
public int read (ByteBuffer dst)
@@ -167,9 +183,7 @@
if (!isConnected ())
throw new NotYetConnectedException ();
- int remaining = dst.remaining();
- receive (dst);
- return remaining - dst.remaining();
+ return channel.read(dst);
}
public long read (ByteBuffer[] dsts, int offset, int length)
@@ -184,12 +198,8 @@
|| (length > (dsts.length - offset)))
throw new IndexOutOfBoundsException();
- long result = 0;
-
- for (int index = offset; index < offset + length; index++)
- result += read (dsts [index]);
-
- return result;
+ /* Likewise, see the comment int write above. */
+ return channel.readScattering(dsts, offset, length);
}
public SocketAddress receive (ByteBuffer dst)
@@ -200,51 +210,14 @@
try
{
- DatagramPacket packet;
- int len = dst.remaining();
-
- if (dst.hasArray())
- {
- packet = new DatagramPacket (dst.array(),
- dst.arrayOffset() + dst.position(),
- len);
- }
- else
- {
- packet = new DatagramPacket (new byte [len], len);
- }
-
- boolean completed = false;
-
- try
- {
- begin();
- setInChannelOperation(true);
- socket.receive (packet);
- completed = true;
- }
- finally
- {
- end (completed);
- setInChannelOperation(false);
- }
-
- if (!dst.hasArray())
- {
- dst.put (packet.getData(), packet.getOffset(), packet.getLength());
- }
- else
- {
- dst.position (dst.position() + packet.getLength());
- }
-
- return packet.getSocketAddress();
+ begin();
+ return channel.receive(dst);
}
- catch (SocketTimeoutException e)
- {
- return null;
+ finally
+ {
+ end(true);
+ }
}
- }
public int send (ByteBuffer src, SocketAddress target)
throws IOException
@@ -252,46 +225,18 @@
if (!isOpen())
throw new ClosedChannelException();
- if (target instanceof InetSocketAddress
- && ((InetSocketAddress) target).isUnresolved())
+ if (!(target instanceof InetSocketAddress))
+ throw new IOException("can only send to inet socket addresses");
+
+ InetSocketAddress dst = (InetSocketAddress) target;
+ if (dst.isUnresolved())
throw new IOException("Target address not resolved");
- byte[] buffer;
- int offset = 0;
- int len = src.remaining();
-
- if (src.hasArray())
- {
- buffer = src.array();
- offset = src.arrayOffset() + src.position();
- }
- else
- {
- buffer = new byte [len];
- src.get (buffer);
+ return channel.send(src, dst);
}
-
- DatagramPacket packet = new DatagramPacket (buffer, offset, len, target);
-
- boolean completed = false;
- try
+
+ public VMChannel getVMChannel()
{
- begin();
- setInChannelOperation(true);
- socket.send(packet);
- completed = true;
- }
- finally
- {
- end (completed);
- setInChannelOperation(false);
- }
-
- if (src.hasArray())
- {
- src.position (src.position() + len);
- }
-
- return len;
+ return channel;
}
}
Modified: trunk/core/src/classpath/gnu/gnu/java/nio/DatagramChannelSelectionKey.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/nio/DatagramChannelSelectionKey.java 2006-12-13 19:25:39 UTC (rev 2906)
+++ trunk/core/src/classpath/gnu/gnu/java/nio/DatagramChannelSelectionKey.java 2006-12-14 09:24:37 UTC (rev 2907)
@@ -38,6 +38,7 @@
package gnu.java.nio;
+import java.io.IOException;
import java.nio.channels.spi.AbstractSelectableChannel;
/**
@@ -52,10 +53,16 @@
super (channel, selector);
}
+ // FIXME don't use file descriptor integers
public int getNativeFD()
{
- NIODatagramSocket socket =
- (NIODatagramSocket) ((DatagramChannelImpl) ch).socket();
- return socket.getPlainDatagramSocketImpl().getNativeFD();
+ try
+ {
+ return ((DatagramChannelImpl) ch).getVMChannel().getState().getNativeFD();
+ }
+ catch (IOException ioe)
+ {
+ throw new IllegalStateException(ioe);
+ }
}
}
Added: trunk/core/src/classpath/gnu/gnu/java/nio/EpollSelectionKeyImpl.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/nio/EpollSelectionKeyImpl.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/java/nio/EpollSelectionKeyImpl.java 2006-12-14 09:24:37 UTC (rev 2907)
@@ -0,0 +1,122 @@
+/* EpollSelectionKeyImpl.java -- selection key for the epoll selector.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is 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, 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; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, 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. */
+
+
+package gnu.java.nio;
+
+import java.io.IOException;
+import java.nio.channels.CancelledKeyException;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.spi.AbstractSelectionKey;
+
+/**
+ * @author Casey Marshall (cs...@gn...)
+ */
+public class EpollSelectionKeyImpl extends AbstractSelectionKey
+{
+ final int fd;
+ private final EpollSelectorImpl selector;
+ private final SelectableChannel channel;
+ int interestOps;
+ int selectedOps;
+ int key;
+ boolean valid;
+ boolean cancelled;
+
+ EpollSelectionKeyImpl(EpollSelectorImpl selector,
+ SelectableChannel channel, int fd)
+ {
+ this.selector = selector;
+ this.channel = channel;
+ this.fd = fd;
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.SelectionKey#channel()
+ */
+ public SelectableChannel channel()
+ {
+ return channel;
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.SelectionKey#interestOps()
+ */
+ public int interestOps()
+ {
+ return interestOps;
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.SelectionKey#interestOps(int)
+ */
+ public SelectionKey interestOps(int ops)
+ {
+ if (cancelled)
+ throw new CancelledKeyException();
+ if ((ops & ~(channel.validOps())) != 0)
+ throw new IllegalArgumentException("unsupported channel ops");
+ try
+ {
+ selector.epoll_modify(this, ops);
+ interestOps = ops;
+ }
+ catch (IOException ioe)
+ {
+ throw new IllegalArgumentException(ioe);
+ }
+ return this;
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.SelectionKey#readyOps()
+ */
+ public int readyOps()
+ {
+ return selectedOps;
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.SelectionKey#selector()
+ */
+ public Selector selector()
+ {
+ return selector;
+ }
+}
Added: trunk/core/src/classpath/gnu/gnu/java/nio/EpollSelectorImpl.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/nio/EpollSelectorImpl.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/java/nio/EpollSelectorImpl.java 2006-12-14 09:24:37 UTC (rev 2907)
@@ -0,0 +1,399 @@
+/* EpollSelectorImpl.java -- selector implementation using epoll
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is 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, 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; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, 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. */
+
+
+package gnu.java.nio;
+
+import gnu.classpath.Configuration;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.spi.AbstractSelectableChannel;
+import java.nio.channels.spi.AbstractSelector;
+import java.nio.channels.spi.SelectorProvider;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * An implementation of {@link Selector} that uses the epoll event
+ * notification mechanism on GNU/Linux.
+ *
+ * @author Casey Marshall (cs...@gn...)
+ */
+public class EpollSelectorImpl extends AbstractSelector
+{
+ // XXX is this reasonable? Does it matter?
+ private static final int DEFAULT_EPOLL_SIZE = 128;
+ private static final int sizeof_struct_epoll_event;
+
+ private static final int OP_ACCEPT = SelectionKey.OP_ACCEPT;
+ private static final int OP_CONNECT = SelectionKey.OP_CONNECT;
+ private static final int OP_READ = SelectionKey.OP_READ;
+ private static final int OP_WRITE = SelectionKey.OP_WRITE;
+
+ /** our epoll file descriptor. */
+ private int epoll_fd;
+
+ private final HashMap keys;
+ private Set selectedKeys;
+ private Thread waitingThread;
+ private ByteBuffer events;
+
+ private static final int INITIAL_CAPACITY;
+ private static final int MAX_DOUBLING_CAPACITY;
+ private static final int CAPACITY_INCREMENT;
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ System.loadLibrary("javanio");
+
+ if (epoll_supported())
+ sizeof_struct_epoll_event = sizeof_struct();
+ else
+ sizeof_struct_epoll_event = -1;
+
+ INITIAL_CAPACITY = 64 * sizeof_struct_epoll_event;
+ MAX_DOUBLING_CAPACITY = 1024 * sizeof_struct_epoll_event;
+ CAPACITY_INCREMENT = 128 * sizeof_struct_epoll_event;
+ }
+
+ public EpollSelectorImpl(SelectorProvider provider)
+ throws IOException
+ {
+ super(provider);
+ epoll_fd = epoll_create(DEFAULT_EPOLL_SIZE);
+ keys = new HashMap();
+ selectedKeys = null;
+ events = ByteBuffer.allocateDirect(INITIAL_CAPACITY);
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.Selector#keys()
+ */
+ public Set keys()
+ {
+ return new HashSet(keys.values());
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.Selector#select()
+ */
+ public int select() throws IOException
+ {
+ return doSelect(-1);
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.Selector#select(long)
+ */
+ public int select(long timeout) throws IOException
+ {
+ if (timeout > Integer.MAX_VALUE)
+ throw new IllegalArgumentException("timeout is too large");
+ if (timeout < 0)
+ throw new IllegalArgumentException("invalid timeout");
+ return doSelect((int) timeout);
+ }
+
+ private int doSelect(int timeout) throws IOException
+ {
+ synchronized (keys)
+ {
+ Set cancelledKeys = cancelledKeys();
+ synchronized (cancelledKeys)
+ {
+ for (Iterator it = cancelledKeys.iterator(); it.hasNext(); )
+ {
+ EpollSelectionKeyImpl key = (EpollSelectionKeyImpl) it.next();
+ epoll_delete(epoll_fd, key.fd);
+ key.valid = false;
+ keys.remove(Integer.valueOf(key.fd));
+ it.remove();
+ deregister(key);
+ }
+
+ // Clear out closed channels. The fds are removed from the epoll
+ // fd when closed, so there is no need to remove them manually.
+ for (Iterator it = keys.values().iterator(); it.hasNext(); )
+ {
+ EpollSelectionKeyImpl key = (EpollSelectionKeyImpl) it.next();
+ SelectableChannel ch = key.channel();
+ if (ch instanceof VMChannelOwner)
+ {
+ if (!((VMChannelOwner) ch).getVMChannel().getState().isValid())
+ it.remove();
+ }
+ }
+
+ // Don't bother if we have nothing to select.
+ if (keys.isEmpty())
+ return 0;
+
+ int ret;
+ try
+ {
+ begin();
+ waitingThread = Thread.currentThread();
+ ret = epoll_wait(epoll_fd, events, keys.size(), timeout);
+ }
+ finally
+ {
+ Thread.interrupted();
+ waitingThread = null;
+ end();
+ }
+
+ HashSet s = new HashSet(ret);
+ for (int i = 0; i < ret; i++)
+ {
+ events.position(i * sizeof_struct_epoll_event);
+ ByteBuffer b = events.slice();
+ int fd = selected_fd(b);
+ EpollSelectionKeyImpl key
+ = (EpollSelectionKeyImpl) keys.get(Integer.valueOf(fd));
+ if (key == null)
+ throw new IOException("fd was selected, but no key found");
+ key.selectedOps = selected_ops(b) & key.interestOps;
+ s.add(key);
+ }
+
+ reallocateBuffer();
+
+ selectedKeys = s;
+ return ret;
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.Selector#selectedKeys()
+ */
+ public Set selectedKeys()
+ {
+ if (selectedKeys == null)
+ return Collections.EMPTY_SET;
+ return selectedKeys;
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.Selector#selectNow()
+ */
+ public int selectNow() throws IOException
+ {
+ return doSelect(0);
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.Selector#wakeup()
+ */
+ public Selector wakeup()
+ {
+ try
+ {
+ waitingThread.interrupt();
+ }
+ catch (NullPointerException npe)
+ {
+ // Ignored, thrown if we are not in a blocking op.
+ }
+ return this;
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.spi.AbstractSelector#implCloseSelector()
+ */
+ protected void implCloseSelector() throws IOException
+ {
+ VMChannel.close(epoll_fd);
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.spi.AbstractSelector#register(java.nio.channels.spi.AbstractSelectableChannel, int, java.lang.Object)
+ */
+ protected SelectionKey register(AbstractSelectableChannel ch, int ops, Object att)
+ {
+ if (!(ch instanceof VMChannelOwner))
+ throw new IllegalArgumentException("unsupported channel type");
+
+ VMChannel channel = ((VMChannelOwner) ch).getVMChannel();
+ try
+ {
+ int native_fd = channel.getState().getNativeFD();
+ synchronized (keys)
+ {
+ if (keys.containsKey(Integer.valueOf(native_fd)))
+ throw new IllegalArgumentException("channel already registered");
+ EpollSelectionKeyImpl result =
+ new EpollSelectionKeyImpl(this, ch, native_fd);
+ if ((ops & ~(ch.validOps())) != 0)
+ throw new IllegalArgumentException("invalid ops for channel");
+ result.interestOps = ops;
+ result.selectedOps = 0;
+ result.valid = true;
+ result.attach(att);
+ result.key = System.identityHashCode(result);
+ epoll_add(epoll_fd, result.fd, ops);
+ keys.put(Integer.valueOf(native_fd), result);
+ reallocateBuffer();
+ return result;
+ }
+ }
+ catch (IOException ioe)
+ {
+ throw new IllegalArgumentException(ioe);
+ }
+ }
+
+ private void reallocateBuffer()
+ {
+ // Ensure we have enough space for all potential events that may be
+ // returned.
+ if (events.capacity() < keys.size() * sizeof_struct_epoll_event)
+ {
+ int cap = events.capacity();
+ if (cap < MAX_DOUBLING_CAPACITY)
+ cap <<= 1;
+ else
+ cap += CAPACITY_INCREMENT;
+ events = ByteBuffer.allocateDirect(cap);
+ }
+ // Ensure that the events buffer is not too large, given the number of
+ // events registered.
+ else if (events.capacity() > keys.size() * sizeof_struct_epoll_event * 2 + 1
+ && events.capacity() > INITIAL_CAPACITY)
+ {
+ int cap = events.capacity() >>> 1;
+ events = ByteBuffer.allocateDirect(cap);
+ }
+ }
+
+ void epoll_modify(EpollSelectionKeyImpl key, int ops) throws IOException
+ {
+ epoll_modify(epoll_fd, key.fd, ops);
+ }
+
+ /**
+ * Tell if epoll is supported by this system, and support was compiled in.
+ *
+ * @return True if this system supports event notification with epoll.
+ */
+ public static native boolean epoll_supported();
+
+
+ /**
+ * Returns the size of `struct epoll_event'.
+ *
+ * @return The size of `struct epoll_event'.
+ */
+ private static native int sizeof_struct();
+
+
+ /**
+ * Open a new epoll file descriptor.
+ *
+ * @param size The size hint for the new epoll descriptor.
+ * @return The new file descriptor integer.
+ * @throws IOException If allocating a new epoll descriptor fails.
+ */
+ private static native int epoll_create(int size) throws IOException;
+
+ /**
+ * Add a file descriptor to this selector.
+ *
+ * @param efd The epoll file descriptor.
+ * @param fd The file descriptor to add (or modify).
+ * @param ops The interest opts.
+ */
+ private static native void epoll_add(int efd, int fd, int ops)
+ throws IOException;
+
+ /**
+ * Modify the interest ops of the key selecting for the given FD.
+ *
+ * @param efd The epoll file descriptor.
+ * @param fd The file descriptor to modify.
+ * @param ops The ops.
+ * @throws IOException
+ */
+ private static native void epoll_modify(int efd, int fd, int ops)
+ throws IOException;
+
+ /**
+ * Remove a file descriptor from this selector.
+ *
+ * @param efd The epoll file descriptor.
+ * @param fd The file descriptor.
+ * @throws IOException
+ */
+ private static native void epoll_delete(int efd, int fd) throws IOException;
+
+ /**
+ * Select events.
+ *
+ * @param efd The epoll file descriptor.
+ * @param state The buffer to hold selected events.
+ * @param n The number of events that may be put in `state'.
+ * @param timeout The timeout.
+ * @return The number of events selected.
+ * @throws IOException
+ */
+ private static native int epoll_wait(int efd, ByteBuffer state, int n, int timeout)
+ throws IOException;
+
+ /**
+ * Fetch the fd value from a selected struct epoll_event.
+ *
+ * @param struct The direct buffer holding the struct.
+ * @return The fd value.
+ */
+ private static native int selected_fd(ByteBuffer struct);
+
+ /**
+ * Fetch the enabled operations from a selected struct epoll_event.
+ *
+ * @param struct The direct buffer holding the struct.
+ * @return The selected operations.
+ */
+ private static native int selected_ops(ByteBuffer struct);
+}
Modified: trunk/core/src/classpath/gnu/gnu/java/nio/FileLockImpl.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/nio/FileLockImpl.java 2006-12-13 19:25:39 UTC (rev 2906)
+++ trunk/core/src/classpath/gnu/gnu/java/nio/FileLockImpl.java 2006-12-14 09:24:37 UTC (rev 2907)
@@ -38,8 +38,6 @@
package gnu.java.nio;
-import gnu.java.nio.channels.FileChannelImpl;
-
import java.io.IOException;
import java.nio.channels.FileLock;
Added: trunk/core/src/classpath/gnu/gnu/java/nio/KqueueSelectionKeyImpl.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/nio/KqueueSelectionKeyImpl.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/java/nio/KqueueSelectionKeyImpl.java 2006-12-14 09:24:37 UTC (rev 2907)
@@ -0,0 +1,189 @@
+/* KqueueSelectionKeyImpl.java -- selection key for kqueue/kevent.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is 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, 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; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, 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. */
+
+
+package gnu.java.nio;
+
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.spi.AbstractSelectionKey;
+
+/**
+ * @author Casey Marshall (cs...@gn...)
+ */
+public class KqueueSelectionKeyImpl extends AbstractSelectionKey
+{
+ int interestOps;
+ int readyOps;
+ int activeOps = 0;
+ int key;
+ int fd;
+
+ /** The selector we were created for. */
+ private final KqueueSelectorImpl selector;
+
+ /** The channel we are attached to. */
+ private final SelectableChannel channel;
+
+ private final VMChannelOwner natChannel;
+
+ public KqueueSelectionKeyImpl(KqueueSelectorImpl selector,
+ SelectableChannel channel)
+ {
+ this.selector = selector;
+ this.channel = channel;
+ natChannel = (VMChannelOwner) channel;
+ interestOps = 0;
+ readyOps = 0;
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.SelectionKey#channel()
+ */
+ //@Override
+ public SelectableChannel channel()
+ {
+ return channel;
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.SelectionKey#interestOps()
+ */
+ //@Override
+ public int interestOps()
+ {
+ return interestOps;
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.SelectionKey#interestOps(int)
+ */
+ //@Override
+ public SelectionKey interestOps(int ops)
+ {
+ if (!isValid())
+ throw new IllegalStateException("key is invalid");
+ if ((ops & ~channel.validOps()) != 0)
+ throw new IllegalArgumentException("channel does not support all operations");
+
+ selector.setInterestOps(this, ops);
+ return this;
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.SelectionKey#readyOps()
+ */
+ //@Override
+ public int readyOps()
+ {
+ return readyOps;
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.SelectionKey#selector()
+ */
+ //@Override
+ public Selector selector()
+ {
+ return selector;
+ }
+
+ public String toString()
+ {
+ if (!isValid())
+ return super.toString() + " [ fd: " + fd + " <<invalid>> ]";
+ return super.toString() + " [ fd: " + fd + " interest ops: {"
+ + ((interestOps & OP_ACCEPT) != 0 ? " OP_ACCEPT" : "")
+ + ((interestOps & OP_CONNECT) != 0 ? " OP_CONNECT" : "")
+ + ((interestOps & OP_READ) != 0 ? " OP_READ" : "")
+ + ((interestOps & OP_WRITE) != 0 ? " OP_WRITE" : "")
+ + " }; ready ops: {"
+ + ((readyOps & OP_ACCEPT) != 0 ? " OP_ACCEPT" : "")
+ + ((readyOps & OP_CONNECT) != 0 ? " OP_CONNECT" : "")
+ + ((readyOps & OP_READ) != 0 ? " OP_READ" : "")
+ + ((readyOps & OP_WRITE) != 0 ? " OP_WRITE" : "")
+ + " } ]";
+ }
+
+ public int hashCode()
+ {
+ return fd;
+ }
+
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof KqueueSelectionKeyImpl))
+ return false;
+ KqueueSelectionKeyImpl that = (KqueueSelectionKeyImpl) o;
+ return that.fd == this.fd && that.channel.equals(this.channel);
+ }
+
+
+ boolean isReadActive()
+ {
+ return (activeOps & (OP_READ | OP_ACCEPT)) != 0;
+ }
+
+ boolean isReadInterested()
+ {
+ return (interestOps & (OP_READ | OP_ACCEPT)) != 0;
+ }
+
+ boolean isWriteActive()
+ {
+ return (activeOps & (OP_WRITE | OP_CONNECT)) != 0;
+ }
+
+ boolean isWriteInterested()
+ {
+ return (interestOps & (OP_WRITE | OP_CONNECT)) != 0;
+ }
+
+ boolean needCommitRead()
+ {
+ return isReadActive() == (!isReadInterested());
+ }
+
+ boolean needCommitWrite()
+ {
+ return isWriteActive() == (!isWriteInterested());
+ }
+}
Added: trunk/core/src/classpath/gnu/gnu/java/nio/KqueueSelectorImpl.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/nio/KqueueSelectorImpl.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/java/nio/KqueueSelectorImpl.java 2006-12-14 09:24:37 UTC (rev 2907)
@@ -0,0 +1,527 @@
+/* KqueueSelectorImpl.java -- Selector for systems with kqueue event notification.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is 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, 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; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, 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. */
+
+
+package gnu.java.nio;
+
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.ClosedSelectorException;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.spi.AbstractSelectableChannel;
+import java.nio.channels.spi.AbstractSelector;
+import java.nio.channels.spi.SelectorProvider;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A {@link Selector} implementation that uses the <code>kqueue</code>
+ * event notification facility.
+ *
+ * @author Casey Marshall (cs...@gn...)
+ */
+public class KqueueSelectorImpl extends AbstractSelector
+{
+ // Prepended underscore to field name to make it distinct
+ // from the method with the similar name.
+ private static final int _sizeof_struct_kevent;
+
+ private static final int MAX_DOUBLING_CAPACITY = 16384;
+ private static final int CAP_INCREMENT = 1024;
+ private static final int INITIAL_CAPACITY;
+
+ static
+ {
+ try
+ {
+ System.loadLibrary("javanio");
+ }
+ catch (Exception x)
+ {
+ x.printStackTrace();
+ }
+
+ if (kqueue_supported ())
+ _sizeof_struct_kevent = sizeof_struct_kevent();
+ else
+ _sizeof_struct_kevent = -1;
+ INITIAL_CAPACITY = 16 * _sizeof_struct_kevent;
+ }
+
+ /**
+ * Tell if kqueue-based selectors are supported on this system.
+ *
+ * @return True if this system has kqueue support, and support for it was
+ * compiled in to Classpath.
+ */
+ public static native boolean kqueue_supported();
+
+ /* Our native file descriptor. */
+ private int kq;
+
+ private HashMap/*<Integer,KqueueSelectionKeyImpl>*/ keys;
+ private HashSet/*<KqueueSelectionKeyImpl>*/ selected;
+ private Thread blockedThread;
+ private ByteBuffer events;
+
+ private static final int OP_ACCEPT = SelectionKey.OP_ACCEPT;
+ private static final int OP_CONNECT = SelectionKey.OP_CONNECT;
+ private static final int OP_READ = SelectionKey.OP_READ;
+ private static final int OP_WRITE = SelectionKey.OP_WRITE;
+
+ public KqueueSelectorImpl(SelectorProvider provider) throws IOException
+ {
+ super(provider);
+ kq = implOpen();
+ keys = new HashMap/*<KqueueSelectionKeyImpl>*/();
+ events = ByteBuffer.allocateDirect(INITIAL_CAPACITY);
+ }
+
+ protected void implCloseSelector() throws IOException
+ {
+ implClose(kq);
+ kq = -1;
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.Selector#keys()
+ */
+ public Set keys()
+ {
+ if (!isOpen())
+ throw new ClosedSelectorException();
+
+ return new HashSet(keys.values());
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.Selector#select()
+ */
+ public int select() throws IOException
+ {
+ return doSelect(-1);
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.Selector#select(long)
+ */
+ public int select(long timeout) throws IOException
+ {
+ if (timeout == 0)
+ timeout = -1;
+ return doSelect(timeout);
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.Selector#selectedKeys()
+ */
+ public Set selectedKeys()
+ {
+ if (!isOpen())
+ throw new ClosedSelectorException();
+
+ return selected;
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.Selector#selectNow()
+ */
+ public int selectNow() throws IOException
+ {
+ return doSelect(0);
+ }
+
+ /* (non-Javadoc)
+ * @see java.nio.channels.Selector#wakeup()
+ */
+ public Selector wakeup()
+ {
+ if (blockedThread != null)
+ blockedThread.interrupt();
+ return this;
+ }
+
+ public String toString()
+ {
+ return super.toString() + " [ fd: " + kq + " ]";
+ }
+
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof KqueueSelectorImpl))
+ return false;
+
+ return ((KqueueSelectorImpl) o).kq == kq;
+ }
+
+ int doSelect(long timeout) throws IOException
+ {
+ Set cancelled = cancelledKeys();
+ synchronized (cancelled)
+ {
+ synchronized (keys)
+ {
+ for (Iterator it = cancelled.iterator(); it.hasNext(); )
+ {
+ KqueueSelectionKeyImpl key = (KqueueSelectionKeyImpl) it.next();
+ key.interestOps = 0;
+ }
+
+ int events_size = (2 * _sizeof_struct_kevent) * keys.size();
+ int num_events = 0;
+
+ for (Iterator it = keys.entrySet().iterator(); it.hasNext(); )
+ {
+ Map.Entry e = (Map.Entry) it.next();
+ KqueueSelectionKeyImpl key = (KqueueSelectionKeyImpl) e.getValue();
+
+ SelectableChannel ch = key.channel();
+ if (ch instanceof VMChannelOwner)
+ {
+ if (!((VMChannelOwner) ch).getVMChannel().getState().isValid())
+ {
+ // closed channel; removed from kqueue automatically.
+ it.remove();
+ continue;
+ }
+ }
+
+ // If this key is registering a read filter, add it to the buffer.
+ if (key.needCommitRead())
+ {
+ kevent_set(events, num_events, key.fd,
+ key.interestOps & (OP_READ | OP_ACCEPT),
+ key.activeOps & (OP_READ | OP_ACCEPT), key.key);
+ num_events++;
+ }
+
+ // If this key is registering a write filter, add it to the buffer.
+ if (key.needCommitWrite())
+ {
+ kevent_set(events, num_events, key.fd,
+ key.interestOps & (OP_WRITE | OP_CONNECT),
+ key.activeOps & (OP_WRITE | OP_CONNECT), key.key);
+ num_events++;
+ }
+ }
+ events.rewind().limit(events.capacity());
+
+ //System.out.println("dump of keys to select:");
+ //dump_selection_keys(events.duplicate());
+
+ int n = 0;
+ try
+ {
+ //System.out.println("[" + kq + "] kevent enter selecting from " + keys.size());
+ begin();
+ blockedThread = Thread.currentThread();
+ if (blockedThread.isInterrupted())
+ timeout = 0;
+ n = kevent(kq, events, num_events,
+ events.capacity() / _sizeof_struct_kevent, timeout);
+ }
+ finally
+ {
+ end();
+ blockedThread = null;
+ Thread.interrupted();
+ //System.out.println("[" + kq + "kevent exit selected " + n);
+ }
+
+ //System.out.println("dump of keys selected:");
+ //dump_selection_keys((ByteBuffer) events.duplicate().limit(n * _sizeof_struct_kevent));
+
+ // Commit the operations we've just added in the call to kevent.
+ for (Iterator it = keys.values().iterator(); it.hasNext(); )
+ {
+ KqueueSelectionKeyImpl key = (KqueueSelectionKeyImpl) it.next();
+ key.activeOps = key.interestOps;
+ }
+
+ selected = new HashSet/*<KqueueSelectionKeyImpl>*/(n);
+ int x = 0;
+ for (int i = 0; i < n; i++)
+ {
+ events.position(x).limit(x + _sizeof_struct_kevent);
+ x += _sizeof_struct_kevent;
+ int y = fetch_key(events.slice());
+ KqueueSelectionKeyImpl key =
+ (KqueueSelectionKeyImpl) keys.get(new Integer(y));
+
+ if (key == null)
+ {
+ System.out.println("WARNING! no key found for selected key " + y);
+ continue;
+ }
+ // Keys that have been cancelled may be returned here; don't
+ // add them to the selected set.
+ if (!key.isValid())
+ continue;
+ key.readyOps = ready_ops(events.slice(), key.interestOps);
+ selected.add(key);
+ }
+
+ // Finally, remove the cancelled keys.
+ for (Iterator it = cancelled.iterator(); it.hasNext(); )
+ {
+ KqueueSelectionKeyImpl key = (KqueueSelectionKeyImpl) it.next();
+ keys.remove(new Integer(key.key));
+ deregister(key);
+ it.remove();
+ }
+
+ reallocateBuffer();
+
+ return selected.size();
+ }
+ }
+ }
+
+ protected SelectionKey register(AbstractSelectableChannel channel,
+ int interestOps,
+ Object attachment)
+ {
+ int native_fd = -1;
+ try
+ {
+ if (channel instanceof VMChannelOwner)
+ native_fd = ((VMChannelOwner) channel).getVMChannel()
+ .getState().getNativeFD();
+ else
+ throw new IllegalArgumentException("cannot handle channel type " +
+ channel.getClass().getName());
+ }
+ catch (IOException ioe)
+ {
+ throw new IllegalArgumentException("channel is closed or invalid");
+ }
+
+ KqueueSelectionKeyImpl result = new KqueueSelectionKeyImpl(this, channel);
+ result.interestOps = interestOps;
+ result.attach(attachment);
+ result.fd = native_fd;
+ result.key = System.identityHashCode(result);
+ synchronized (keys)
+ {
+ while (keys.containsKey(new Integer(result.key)))
+ result.key++;
+ keys.put(new Integer(result.key), result);
+ reallocateBuffer();
+ }
+ return result;
+ }
+
+ void setInterestOps(KqueueSelectionKeyImpl key, int ops)
+ {
+ synchronized (keys)
+ {
+ key.interestOps = ops;
+ }
+ }
+
+ /**
+ * Reallocate the events buffer. This is the destination buffer for
+ * events returned by kevent. This method will:
+ *
+ * * Grow the buffer if there is insufficent space for all registered
+ * events.
+ * * Shrink the buffer if it is more than twice the size needed.
+ *
+ */
+ private void reallocateBuffer()
+ {
+ synchronized (keys)
+ {
+ if (events.capacity() < (2 * _sizeof_struct_kevent) * keys.size())
+ {
+ int cap = events.capacity();
+ if (cap >= MAX_DOUBLING_CAPACITY)
+ cap += CAP_INCREMENT;
+ else
+ cap = cap << 1;
+
+ events = ByteBuffer.allocateDirect(cap);
+ }
+ else if (events.capacity() > 4 * (_sizeof_struct_kevent) * keys.size() + 1
+ && events.capacity() > INITIAL_CAPACITY)
+ {
+ int cap = events.capacity();
+ cap = cap >>> 1;
+ events = ByteBuffer.allocateDirect(cap);
+ }
+ }
+ }
+
+ //synchronized void updateOps(KqueueSelectionKeyImpl key, int interestOps)
+ //{
+ // updateOps(key, interestOps, 0, false);
+ //}
+
+ /*void updateOps(KqueueSelectionKeyImpl key, int interestOps,
+ int activeOps, int fd)
+ {
+ //System.out.println(">> updating kqueue selection key:");
+ //dump_selection_keys(key.nstate.duplicate());
+ //System.out.println("<<");
+ synchronized (keys)
+ {
+ kevent_set(key.nstate, fd, interestOps, activeOps, key.key);
+ }
+ //System.out.println(">> updated kqueue selection key:");
+ //dump_selection_keys(key.nstate.duplicate());
+ //System.out.println("<<");
+ }*/
+
+ private void dump_selection_keys(ByteBuffer keys)
+ {
+ // WARNING! This method is not guaranteed to be portable! This works
+ // on darwin/x86, but the sizeof and offsetof these fields may be
+ // different on other platforms!
+ int i = 0;
+ keys.order(ByteOrder.nativeOrder());
+ while (keys.hasRemaining())
+ {
+ System.out.println("struct kevent { ident: "
+ + Integer.toString(keys.getInt())
+ + " filter: "
+ + Integer.toHexString(keys.getShort() & 0xFFFF)
+ + " flags: "
+ + Integer.toHexString(keys.getShort() & 0xFFFF)
+ + " fflags: "
+ + Integer.toHexString(keys.getInt())
+ + " data: "
+ + Integer.toHexString(keys.getInt())
+ + " udata: "
+ + Integer.toHexString(keys.getInt())
+ + " }");
+ }
+ }
+
+ /**
+ * Return the size of a <code>struct kevent</code> on this system.
+ *
+ * @return The size of <code>struct kevent</code>.
+ */
+ private static native int sizeof_struct_kevent();
+
+ /**
+ * Opens a kqueue descriptor.
+ *
+ * @return The new kqueue descriptor.
+ * @throws IOException If opening fails.
+ */
+ private static native int implOpen() throws IOException;
+
+ /**
+ * Closes the kqueue file descriptor.
+ *
+ * @param kq The kqueue file descriptor.
+ * @throws IOException
+ */
+ private static native void implClose(int kq) throws IOException;
+
+ /**
+ * Initialize the specified native state for the given interest ops.
+ *
+ * @param nstate The native state structures; in this buffer should be
+ * the <code>struct kevent</code>s created for a key.
+ * @param fd The file descriptor. If 0, the native FD is unmodified.
+ * @param interestOps The operations to enable.
+ * @param key A unique key that will reference the associated key later.
+ * @param delete Set to true if this event should be deleted from the
+ * kqueue (if false, this event is added/updated).
+ */
+ private static native void kevent_set(ByteBuffer nstate, int i, int fd,
+ int interestOps, int activeOps, int key);
+
+ /**
+ * Poll for events. The source events are stored in <code>events</code>,
+ * which is also where polled events will be placed.
+ *
+ * @param events The events to poll. This buffer is also the destination
+ * for events read from the queue.
+ * @param nevents The number of events to poll (that is, the number of
+ * events in the <code>events</code> buffer).
+ * @param nout The maximum number of events that may be returned.
+ * @param timeout The timeout. A timeout of -1 returns immediately; a timeout
+ * of 0 waits indefinitely.
+ * @return The number of events read.
+ */
+ private static native int kevent(int kq, ByteBuffer events, int nevents,
+ int nout, long timeout);
+
+ /**
+ * Fetch a polled key from a native state buffer. For each kevent key we
+ * create, we put the native state info (one or more <code>struct
+ * kevent</code>s) in that key's {@link KqueueSelectionKeyImpl#nstate}
+ * buffer, and place the pointer of the key in the <code>udata</code> field
+ * of that structure. This method fetches that pointer from the given
+ * buffer (assumed to be a <code>struct kqueue</code>) and returns it.
+ *
+ * @param nstate The buffer containing the <code>struct kqueue</code> to read.
+ * @return The key object.
+ */
+ private static native int fetch_key(ByteBuffer nstate);
+
+ /**
+ * Fetch the ready ops of the associated native state. That is, this
+ * inspects the first argument as a <code>struct kevent</code>, looking
+ * at its operation (the input is assumed to have been returned via a
+ * previous call to <code>kevent</code>), and translating that to the
+ * appropriate Java bit set, based on the second argument.
+ *
+ * @param nstate The native state.
+ * @param interestOps The enabled operations for the key.
+ * @return The bit set representing the ready operations.
+ */
+ private static native int ready_ops(ByteBuffer nstate, int interestOps);
+
+ /**
+ * Check if kevent returned EV_EOF for a selection key.
+ *
+ * @param nstate The native state.
+ * @return True if the kevent call returned EOF.
+ */
+ private static native boolean check_eof(ByteBuffer nstate);
+}
Modified: trunk/core/src/classpath/gnu/gnu/java/nio/NIOSocket.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/nio/NIOSocket.java 2006-12-13 19:25:39 UTC (rev 2906)
+++ trunk/core/src/classpath/gnu/gnu/java/nio/NIOSocket.java 2006-12-14 09:24:37 UTC (rev 2907)
@@ -48,30 +48,33 @@
*/
public final class NIOSocket extends Socket
{
- private PlainSocketImpl impl;
private SocketChannelImpl channel;
- protected NIOSocket (PlainSocketImpl impl, SocketChannelImpl channel)
+ protected NIOSocket (SocketChannelImpl channel)
throws IOException
{
- super (impl);
- this.impl = impl;
+ super (new NIOSocketImpl(channel));
this.channel = channel;
}
- public final PlainSocketImpl getPlainSocketImpl()
- {
- return impl;
- }
+ //public final PlainSocketImpl getPlainSocketImpl()
+ //{
+ // return impl;
+ //}
- final void setChannel (SocketChannelImpl channel)
- {
- this.impl = channel.getPlainSocketImpl();
- this.channel = channel;
- }
+ //final void setChannel (SocketChannelImpl channel)
+ //{
+ // this.impl = channel.getPlainSocketImpl();
+ // this.channel = channel;
+ //}
public final SocketChannel getChannel()
{
return channel;
}
+
+ public boolean isConnected()
+ {
+ return channel.isConnected();
+ }
}
Added: trunk/core/src/classpath/gnu/gnu/java/nio/NIOSocketImpl.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/nio/NIOSocketImpl.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/java/nio/NIOSocketImpl.java 2006-12-14 09:24:37 UTC (rev 2907)
@@ -0,0 +1,110 @@
+/* NIOSocketImpl.java -- subclass of PlainSocketImpl for NIO.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is 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, 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; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, 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. */
+
+
+package gnu.java.nio;
+
+import gnu.java.net.PlainSocketImpl;
+
+import java.io.IOException;
+import java.net.InetAddress;
+
+/**
+ * @author Casey Marshall (cs...@gn...)
+ */
+public class NIOSocketImpl extends PlainSocketImpl
+{
+
+ private final SocketChannelImpl channel;
+
+ NIOSocketImpl(SocketChannelImpl channel) throws IOException
+ {
+ this.channel = channel;
+ impl.getState().setChannelFD(channel.getVMChannel().getState());
+ }
+
+ /* (non-Javadoc)
+ * @see java.net.SocketImpl#getInetAddress()
+ */
+ //@Override
+ protected InetAddress getInetAddress()
+ {
+ try
+ {
+ return channel.getVMChannel().getPeerAddress().getAddress();
+ }
+ catch (IOException ioe)
+ {
+ return null;
+ }
+ catch (NullPointerException npe)
+ {
+ // Socket is not connected yet.
+ return null;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see java.net.SocketImpl#getPort()
+ */
+ //@Override
+ protected int getPort()
+ {
+ try
+ {
+ return channel.getVMChannel().getPeerAddress().getPort();
+ }
+ catch (IOException ioe)
+ {
+ return -1;
+ }
+ catch (NullPointerException npe)
+ {
+ // Socket is not connected yet.
+ return -1;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see gnu.java.net.PlainSocketImpl#create(boolean)
+ */
+ //@Override
+ protected synchronized void create(boolean stream)
+ {
+ // Ignored; the socket has already been created.
+ }
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|