summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCasey Marshall <csm@gnu.org>2006-09-30 05:19:12 +0000
committerCasey Marshall <csm@gnu.org>2006-09-30 05:19:12 +0000
commit7c2fa5fc198d857672592740a91f30418ef32687 (patch)
tree0bfdbf45967a16cb5f73890c6716ae167160afe7
parent4bf4895593deadf01bc48466c8adf6d3dc90767a (diff)
downloadclasspath-7c2fa5fc198d857672592740a91f30418ef32687.tar.gz
2006-09-29 Casey Marshall <csm@gnu.org>
PR 29190 * gnu/java/nio/EpollSelectionKeyImpl.java: extend `AbstractSelectionKey.' (cancel, isValid): removed. * gnu/java/nio/EpollSelectorImpl.java (cancelledKeys): removed. (events): new field. (INITIAL_CAPACITY, MAX_DOUBLING_CAPACITY, CAPACITY_INCREMENT): new fields. (<clinit>): initialize those constants. (<init>): don't initialize `cancelledKeys;' initialize `events.' (doSelect): deregister cancelled keys; remove keys attached to closed channels; wrap `epoll_wait' in `begin' and `end' calls; use `events' buffer; reallocate `events' buffer if needed. (register): reallocate `events' buffer if needed. (reallocateBuffer): new method. (cancel): removed.
-rw-r--r--ChangeLog19
-rw-r--r--gnu/java/nio/EpollSelectionKeyImpl.java20
-rw-r--r--gnu/java/nio/EpollSelectorImpl.java86
3 files changed, 89 insertions, 36 deletions
diff --git a/ChangeLog b/ChangeLog
index ec4480a90..a0b3243db 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2006-09-29 Casey Marshall <csm@gnu.org>
+
+ PR 29190
+ * gnu/java/nio/EpollSelectionKeyImpl.java: extend
+ `AbstractSelectionKey.'
+ (cancel, isValid): removed.
+ * gnu/java/nio/EpollSelectorImpl.java (cancelledKeys): removed.
+ (events): new field.
+ (INITIAL_CAPACITY, MAX_DOUBLING_CAPACITY, CAPACITY_INCREMENT): new
+ fields.
+ (<clinit>): initialize those constants.
+ (<init>): don't initialize `cancelledKeys;' initialize `events.'
+ (doSelect): deregister cancelled keys; remove keys attached to
+ closed channels; wrap `epoll_wait' in `begin' and `end' calls; use
+ `events' buffer; reallocate `events' buffer if needed.
+ (register): reallocate `events' buffer if needed.
+ (reallocateBuffer): new method.
+ (cancel): removed.
+
2006-09-29 Roman Kennke <kennke@aicas.com>
PR 28929
diff --git a/gnu/java/nio/EpollSelectionKeyImpl.java b/gnu/java/nio/EpollSelectionKeyImpl.java
index e163e731d..11113f397 100644
--- a/gnu/java/nio/EpollSelectionKeyImpl.java
+++ b/gnu/java/nio/EpollSelectionKeyImpl.java
@@ -43,11 +43,12 @@ 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 (csm@gnu.org)
*/
-public class EpollSelectionKeyImpl extends SelectionKey
+public class EpollSelectionKeyImpl extends AbstractSelectionKey
{
final int fd;
private final EpollSelectorImpl selector;
@@ -67,15 +68,6 @@ public class EpollSelectionKeyImpl extends SelectionKey
}
/* (non-Javadoc)
- * @see java.nio.channels.SelectionKey#cancel()
- */
- public void cancel()
- {
- cancelled = true;
- selector.cancel(this);
- }
-
- /* (non-Javadoc)
* @see java.nio.channels.SelectionKey#channel()
*/
public SelectableChannel channel()
@@ -113,14 +105,6 @@ public class EpollSelectionKeyImpl extends SelectionKey
}
/* (non-Javadoc)
- * @see java.nio.channels.SelectionKey#isValid()
- */
- public boolean isValid()
- {
- return valid;
- }
-
- /* (non-Javadoc)
* @see java.nio.channels.SelectionKey#readyOps()
*/
public int readyOps()
diff --git a/gnu/java/nio/EpollSelectorImpl.java b/gnu/java/nio/EpollSelectorImpl.java
index c6016645d..2b3c9bbb1 100644
--- a/gnu/java/nio/EpollSelectorImpl.java
+++ b/gnu/java/nio/EpollSelectorImpl.java
@@ -42,6 +42,7 @@ 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;
@@ -75,8 +76,12 @@ public class EpollSelectorImpl extends AbstractSelector
private final HashMap keys;
private Set selectedKeys;
- private final Set cancelledKeys;
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
{
@@ -87,6 +92,10 @@ public class EpollSelectorImpl extends AbstractSelector
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)
@@ -96,7 +105,7 @@ public class EpollSelectorImpl extends AbstractSelector
epoll_fd = epoll_create(DEFAULT_EPOLL_SIZE);
keys = new HashMap();
selectedKeys = null;
- cancelledKeys = new HashSet();
+ events = ByteBuffer.allocateDirect(INITIAL_CAPACITY);
}
/* (non-Javadoc)
@@ -131,6 +140,7 @@ public class EpollSelectorImpl extends AbstractSelector
{
synchronized (keys)
{
+ Set cancelledKeys = cancelledKeys();
synchronized (cancelledKeys)
{
for (Iterator it = cancelledKeys.iterator(); it.hasNext(); )
@@ -140,25 +150,45 @@ public class EpollSelectorImpl extends AbstractSelector
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;
- ByteBuffer selected =
- ByteBuffer.allocateDirect(keys.size() * sizeof_struct_epoll_event);
-
- waitingThread = Thread.currentThread();
- int ret = epoll_wait(epoll_fd, selected, keys.size(), timeout);
- Thread.interrupted();
- waitingThread = null;
+ 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++)
{
- selected.position(i * sizeof_struct_epoll_event);
- ByteBuffer b = selected.slice();
+ events.position(i * sizeof_struct_epoll_event);
+ ByteBuffer b = events.slice();
int fd = selected_fd(b);
EpollSelectionKeyImpl key
= (EpollSelectionKeyImpl) keys.get(Integer.valueOf(fd));
@@ -167,6 +197,9 @@ public class EpollSelectorImpl extends AbstractSelector
key.selectedOps = selected_ops(b) & key.interestOps;
s.add(key);
}
+
+ reallocateBuffer();
+
selectedKeys = s;
return ret;
}
@@ -202,6 +235,7 @@ public class EpollSelectorImpl extends AbstractSelector
}
catch (NullPointerException npe)
{
+ // Ignored, thrown if we are not in a blocking op.
}
return this;
}
@@ -241,6 +275,7 @@ public class EpollSelectorImpl extends AbstractSelector
result.key = System.identityHashCode(result);
epoll_add(epoll_fd, result.fd, ops);
keys.put(Integer.valueOf(native_fd), result);
+ reallocateBuffer();
return result;
}
}
@@ -250,17 +285,32 @@ public class EpollSelectorImpl extends AbstractSelector
}
}
- void epoll_modify(EpollSelectionKeyImpl key, int ops) throws IOException
+ private void reallocateBuffer()
{
- epoll_modify(epoll_fd, key.fd, ops);
+ // 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 cancel(EpollSelectionKeyImpl key)
+ void epoll_modify(EpollSelectionKeyImpl key, int ops) throws IOException
{
- synchronized (cancelledKeys)
- {
- cancelledKeys.add(key);
- }
+ epoll_modify(epoll_fd, key.fd, ops);
}
/**