|
25 | 25 | import java.io.InputStream;
|
26 | 26 | import java.io.RandomAccessFile;
|
27 | 27 | import java.nio.ByteBuffer;
|
28 |
| -import java.nio.channels.FileChannel; |
29 |
| -import java.nio.channels.WritableByteChannel; |
| 28 | +import java.nio.channels.*; |
30 | 29 | import java.util.ArrayList;
|
31 | 30 | import java.util.List;
|
| 31 | +import java.util.Set; |
32 | 32 |
|
33 | 33 | public class MultipartBody implements RandomAccessBody {
|
34 | 34 |
|
@@ -569,22 +569,47 @@ private long writeToTarget(WritableByteChannel target, ByteArrayOutputStream byt
|
569 | 569 | int maxSpin = 0;
|
570 | 570 | synchronized (byteWriter) {
|
571 | 571 | ByteBuffer message = ByteBuffer.wrap(byteWriter.toByteArray());
|
572 |
| - while ((target.isOpen()) && (written < byteWriter.size())) { |
573 |
| - long nWrite = target.write(message); |
574 |
| - written += nWrite; |
575 |
| - if (nWrite == 0 && maxSpin++ < 10) { |
576 |
| - logger.info("Waiting for writing..."); |
577 |
| - try { |
578 |
| - byteWriter.wait(1000); |
579 |
| - } catch (InterruptedException e) { |
580 |
| - logger.trace(e.getMessage(), e); |
581 |
| - } |
582 |
| - } else { |
583 |
| - if (maxSpin >= 10) { |
584 |
| - throw new IOException("Unable to write on channel " + target); |
585 |
| - } |
586 |
| - maxSpin = 0; |
587 |
| - } |
| 572 | + |
| 573 | + if (target instanceof SocketChannel) { |
| 574 | + final Selector selector = Selector.open(); |
| 575 | + try { |
| 576 | + final SocketChannel channel = (SocketChannel) target; |
| 577 | + channel.register(selector, SelectionKey.OP_WRITE); |
| 578 | + |
| 579 | + while(written < byteWriter.size() && selector.select() != 0) { |
| 580 | + final Set<SelectionKey> selectedKeys = selector.selectedKeys(); |
| 581 | + |
| 582 | + for (SelectionKey key : selectedKeys) { |
| 583 | + if (key.isWritable()) { |
| 584 | + written += target.write(message); |
| 585 | + } |
| 586 | + } |
| 587 | + } |
| 588 | + |
| 589 | + if (written < byteWriter.size()) { |
| 590 | + throw new IOException("Unable to write on channel " + target); |
| 591 | + } |
| 592 | + } finally { |
| 593 | + selector.close(); |
| 594 | + } |
| 595 | + } else { |
| 596 | + while ((target.isOpen()) && (written < byteWriter.size())) { |
| 597 | + long nWrite = target.write(message); |
| 598 | + written += nWrite; |
| 599 | + if (nWrite == 0 && maxSpin++ < 10) { |
| 600 | + logger.info("Waiting for writing..."); |
| 601 | + try { |
| 602 | + byteWriter.wait(1000); |
| 603 | + } catch (InterruptedException e) { |
| 604 | + logger.trace(e.getMessage(), e); |
| 605 | + } |
| 606 | + } else { |
| 607 | + if (maxSpin >= 10) { |
| 608 | + throw new IOException("Unable to write on channel " + target); |
| 609 | + } |
| 610 | + maxSpin = 0; |
| 611 | + } |
| 612 | + } |
588 | 613 | }
|
589 | 614 | }
|
590 | 615 | return written;
|
|
0 commit comments