2015-01-08 14:10 GMT+01:00 <ma...@apache.org>:

> @@ -766,32 +776,120 @@ public class Nio2Endpoint extends Abstra
>              this.writeCompletionHandler = new CompletionHandler<Integer,
> ByteBuffer>() {
>                  @Override
>                  public void completed(Integer nBytes, ByteBuffer
> attachment) {
> -                    if (nBytes.intValue() < 0) {
> -                        failed(new EOFException(), attachment);
> -                    } else if (attachment.hasRemaining()) {
> -                        getSocket().write(attachment, getTimeout(),
> -                                TimeUnit.MILLISECONDS, attachment,
> writeCompletionHandler);
> -                    } else {
> -                        writePending.release();
> -                        if (!Nio2Endpoint.isInline()) {
> -
> getEndpoint().processSocket(Nio2SocketWrapper.this,
> SocketStatus.OPEN_WRITE, false);
> +                    boolean notify = false;
> +                    synchronized (writeCompletionHandler) {
> +                        if (nBytes.intValue() < 0) {
> +                            failed(new
> EOFException(sm.getString("iob.failedwrite")), attachment);
> +                        } else if
> (Nio2SocketWrapper.this.bufferedWrites.size() > 0) {
> +                            // Continue writing data using a gathering
> write
> +                            ArrayList<ByteBuffer> arrayList = new
> ArrayList<>();
> +                            if (attachment.hasRemaining()) {
> +                                arrayList.add(attachment);
> +                            }
> +                            for (ByteBufferHolder buffer :
> Nio2SocketWrapper.this.bufferedWrites) {
> +                                buffer.flip();
> +                                arrayList.add(buffer.getBuf());
> +                            }
> +                            Nio2SocketWrapper.this.bufferedWrites.clear();
> +                            ByteBuffer[] array = arrayList.toArray(new
> ByteBuffer[arrayList.size()]);
> +
> Nio2SocketWrapper.this.getSocket().write(array, 0, array.length,
> +                                    Nio2SocketWrapper.this.getTimeout(),
> TimeUnit.MILLISECONDS,
> +                                    array,
> gatheringWriteCompletionHandler);
> +                        } else if (attachment.hasRemaining()) {
> +                            // Regular write
> +
> Nio2SocketWrapper.this.getSocket().write(attachment,
> Nio2SocketWrapper.this.getTimeout(),
> +                                    TimeUnit.MILLISECONDS, attachment,
> writeCompletionHandler);
> +                        } else {
> +                            // All data has been written
> +                            if (interest && !Nio2Endpoint.isInline()) {
> +                                interest = false;
> +                                notify = true;
> +                            }
> +                            writePending.release();
>                          }
>                      }
>
> There's a big deadlock risk if the recursion if incomplete and error
processing are inside the sync.

Rémy

Reply via email to