nio, channels, and OP_CONNECT trouble?

Brad Karp bkarp+ at cs.cmu.edu
Mon Jun 21 16:06:38 PDT 2004


I'm using ports/java/jdk14 on FreeBSD 4.9-RELEASE, built with JDK_VERSION
1.4.2 and JDK_PATCHSET_VERSION 5.

I'm running a rather large, complicated application (the Bamboo distributed
hash table, or DHT; if you're curious, http://www.bamboo-dht.org/) under
Java. I'm seeing behavior that seems very likely to be a bug in the FreeBSD
implementation of channels in java.nio. When I use OP_CONNECT to request
notification by selector.select() that a channel's connect() has completed,
the CPU utilization of the Java VM pegs at 100%, with top reporting over 30%
system time. A bit of poking around reveals that:

	1) the connect() actually completes, according to the server being
	   connected to
	2) in the client, select() is returning several times per millisecond,
	   but selector.selectedKeys() does *not* include the SelectionKey 
	   for the channel on which the connect() was called

So selector.select() is called over and over, and the CPU saturates. Has
anyone seen behavior anything like this? I can easily imagine that something
in the implementation of selecting on OP_CONNECT could be awry, given that
the underlying UNIX system call select(2) doesn't have any notion of
distinguishing "connect complete" from "writable."

More details follow, in case they are helpful.

nio supports nonblocking network connections with
SelectableChannels. I'm doing a nonblocking connect with:

            channel = SocketChannel.open();
            channel.configureBlocking(false);
            gateway = new InetSocketAddress(gnid.address(), gnid.port());
            channel.connect(gateway);

(Never mind about gnid; those address() and port() methods return what you
think they do.)

I'm then using a Selector and registering to be notified when the connect()
completes:

	SelectionKey skey =
	  channel.register(selector, SelectionKey.OP_CONNECT);

Thereafter, inside an event loop, I do:

	selector.select();
        Iterator i = selector.selectedKeys ().iterator ();
	while (i.hasNext ()) {
	    SelectionKey skey = (SelectionKey) i.next ();
	}

The selectedKeys returned do not include the SelectionKey returned in the
register() call above. It appears that the OP_CONNECT registration on channel
is causing a SelectionKey for a *different* channel to be returned.

Again, anyone seen similar behavior? If so, have a workaround or patch?

Many thanks,
-Brad, bkarp at cs.cmu.edu

P.S. One final note: I realize that there's a version 6 patchset, but after
reading the ChangeLog, I don't see any patches that since 5 that seem relevant
to the above.


More information about the freebsd-java mailing list