I'm on OS X with the OpenJDK 1.7 port. I'm trying to run this simple test class and I'm getting an IllegalArgumentException in NIO:
scala> HawtDispatchTest.main(Array())
java.lang.IllegalArgumentException
at java.nio.channels.spi.AbstractSelectableChannel.register(AbstractSelectableChannel.java:196)
at java.nio.channels.SelectableChannel.register(SelectableChannel.java:277)
at org.fusesource.hawtdispatch.internal.NioDispatchSource$2.run(NioDispatchSource.java:190)
at org.fusesource.hawtdispatch.internal.pool.SimpleThread.run(SimpleThread.java:60)
Exception: java.lang.NullPointerException thrown from the UncaughtExceptionHandler in thread "hawtdispatch-DEFAULT-2"
java.lang.InterruptedException
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:996)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1303)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:236)
at HawtDispatchTest$.main(HawtDispatchTest.scala:68)
at .<init>(<console>:8)
at .<clinit>(<console>)
at .<init>(<console>:11)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
at java.lang.Thread.run(Thread.java:722)
Here's the test class:
object HawtDispatchTest {
def main(args: Array[String]) {
val latch = new CountDownLatch(1)
val channel = ServerSocketChannel.open()
channel.socket().bind(new InetSocketAddress(3080))
channel.configureBlocking(false)
val queue = createQueue("test")
val acceptSrc = createSource(channel, SelectionKey.OP_ACCEPT, queue)
acceptSrc.setEventHandler(new Runnable {
def run() {
val socket = channel.accept()
socket.configureBlocking(false)
val buff = ByteBuffer.allocateDirect(16 * 1024)
val req = createQueue("req")
val readSrc = createSource(channel, SelectionKey.OP_READ, req)
val writeSrc = createSource(channel, SelectionKey.OP_WRITE, req)
readSrc.onCancel(() => writeSrc.cancel())
writeSrc.onCancel(() => channel.close())
readSrc.setEventHandler(new Runnable {
def run() {
if (socket.read(buff) == -1) {
socket.close()
readSrc.cancel()
} else {
buff.flip()
if (buff.remaining() > 0) {
println("got buffer: " + buff.toString)
readSrc.suspend()
writeSrc.resume()
} else {
buff.clear()
}
}
}
})
writeSrc.setEventHandler(new Runnable {
def run() {
val buff = ByteBuffer.allocateDirect(12)
buff.put("Hello World!".getBytes)
buff.flip()
socket.write(buff)
writeSrc.suspend()
readSrc.resume()
latch.countDown()
}
})
readSrc.resume()
}
})
acceptSrc.resume()
latch.await()
channel.close()
}
}
When I hit CTL-C to kill this test, my CPU usage spiked to 100%. I thought it was because of the continuations. But I don't think that's actually it. I think there's something else going on. I only noticed this after starting to play with HawtDispatch.