Skip to content

Commit 169051c

Browse files
author
Petri Louhelainen
committed
Fix sending multipart bodies through SocketChannel.
As per documentation, selector.select() returns only keys that have updated and therefore even if it return zero, it doesn't mean that selectedKeys wouldn't contain keys that are writable. See http://stackoverflow.com/questions/9939989/java-nio-selector-select-returns-0-although-channels-are-ready and http://docs.oracle.com/javase/7/docs/api/java/nio/channels/Selector.html#select() for more details. This commit utilizes the same maxSpin already used in FileChannel case for detecting that writing has stuck somewhere. A configurable timeout for select would be the obvious better solution.
1 parent 296e71c commit 169051c

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

src/main/java/com/ning/http/multipart/MultipartBody.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -578,18 +578,21 @@ private long writeToTarget(WritableByteChannel target, ByteArrayOutputStream byt
578578
final SocketChannel channel = (SocketChannel) target;
579579
channel.register(selector, SelectionKey.OP_WRITE);
580580

581-
while (written < byteWriter.size() && selector.select() != 0) {
581+
while (written < byteWriter.size()) {
582+
selector.select(1000);
583+
maxSpin++;
582584
final Set<SelectionKey> selectedKeys = selector.selectedKeys();
583585

584586
for (SelectionKey key : selectedKeys) {
585587
if (key.isWritable()) {
586588
written += target.write(message);
589+
maxSpin = 0;
587590
}
588591
}
589-
}
590592

591-
if (written < byteWriter.size()) {
592-
throw new IOException("Unable to write on channel " + target);
593+
if (maxSpin >= 10) {
594+
throw new IOException("Unable to write on channel " + target);
595+
}
593596
}
594597
} finally {
595598
selector.close();

0 commit comments

Comments
 (0)