Bug #3496
closed
WritePendingException from TestGetAsyncThreadPool on Windows
Added by Anonymous over 8 years ago.
Updated over 8 years ago.
Description
On Windows 7 (in a Parallels virtual machine) I run the following commands
mvn install
cd examples
mvn test -DclassName=TestGetAsyncThreadPool
It gives the following output (partially truncated):
net.named_data.jndn.transport.AsyncTcpTransport$2 completed
SEVERE: null
java.nio.channels.WritePendingException
at sun.nio.ch.AsynchronousSocketChannelImpl.write(AsynchronousSocketChannelImpl.java:352)
at sun.nio.ch.AsynchronousSocketChannelImpl.write(AsynchronousSocketChannelImpl.java:387)
at net.named_data.jndn.transport.AsyncTcpTransport.send(AsyncTcpTransport.java:223)
at net.named_data.jndn.Node.expressInterestHelper(Node.java:542)
at net.named_data.jndn.Node.access$000(Node.java:49)
at net.named_data.jndn.Node$1.run(Node.java:117)
at net.named_data.jndn.Node$2.run(Node.java:133)
at net.named_data.jndn.transport.AsyncTcpTransport$2.completed(AsyncTcpTransport.java:180)
at net.named_data.jndn.transport.AsyncTcpTransport$2.completed(AsyncTcpTransport.java:175)
at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126)
at sun.nio.ch.Invoker$2.run(Invoker.java:218)
at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
Time out for interest /
Hi Andrew. The previous notes for AsyncTcpTransport.send said "write is already async, so no need to dispatch." But I think that's not quite right and is causing the problem. I updated to the following comment:
https://github.com/named-data/jndn/blob/8a0157b12b3dfc7aabccca1c85205a8935e8d297/src/net/named_data/jndn/transport/AsyncTcpTransport.java#L238
Each call to AsynchronousSocketChannel.write dispatches to one of its pool threads, but there's no way to know which one. I think we got unlucky with the Windows implementation that dispatches to different threads which try to simultaneously write which throws WritePendingException. (You'd think that the whole point of an asynchronous communication library would be to handle such things but....)
Do I have to implement a send queue? Any ideas?
- Status changed from New to In Progress
Hi again Andrew. I put some code in the issue/3496-WritePendingException branch which works for me:
https://github.com/named-data/jndn/commit/23dc1c67a28e866c9999f55a3cdf6d1fa0c36ee1
Since AsynchronousSocketChannel.write dispatches to another thread, we don't need a send queue. We only need calls to AsyncTcpTransport.send to wait until the other thread is finished writing. I used an isWriting_ flag and use wait() and notify() to coordinate with the write completion handler which clears the flag when done. I hope this is "Java-like."
Can you try pull the issue/3496-WritePendingException branch and try it?
I tried your fix and it seemed to work; the recommended practice in Java is to wrap wait()/notify() with one of the concurrency utilities. I used Lock; can I push a commit to this same branch demonstrating this and we can revert/rebase if necessary?
Yes, push a change to demonstrate it. The wait/notify is already inside "synchronized (writingLock_)". If there is yet another layer of locks, then is the synchronized necessary?
- Status changed from In Progress to Closed
Andrews pull request is tested and merged to master. Thanks!
Also available in: Atom
PDF