Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8359125

(aio) AsynchronousByteChannel.read/write should throw IAE if buffer is thread-confined

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P4 P4
    • 26
    • core-libs
    • None
    • behavioral
    • minimal
    • The read/write methods of these classes cannot work with buffers that are thread confined. It seems unlikely that there is existing code that depends on the current behavior.
    • Java API
    • SE

      Summary

      Update the specification of the read/write methods defined by the java.nio.channels.AsynchronousXXX channels to throw IllegalArgumentException if called with a buffer that is a view of a memory segment allocated from a thread-confined arena.

      Problem

      Arena ofConfined() returns an arena that allocates memory segments that can only be accessed by the thread that created the arena. A ByteBuffer view of the memory is also thread-confined and would be nonsensical to use with an asynchronous channel.

      For AsynchronousSocketChannel, the current behavior is for the read/write methods to initiate an I/O operation and for it to fail/complete with an IOException and an IllegalStateException as cause.

      For AsynchronousFileChannel, the existing behavior is for the read/write methods to initiate an I/O operation that never completes (a thread in the channel groups terminates with a WrongThreadException).

      Solution

      Update the specification of the read/write methods defined by the following classes to throw IllegalArgumentException when called with a buffer that is a view of a memory segment allocated from a thread-confined arena.

      java.nio.channels.AsynchronousByteChannel
      java.nio.channels.AsynchronousSocketChannel
      java.nio.channels.AsynchronousFileChannel

      All read methods already specify IllegalArgumentException to be thrown if called with a read-only buffer. The read/write methods of AsynchronousFileChannel additionally specify IllegalArgumentException to be thrown when called with a negative file position.

      Specification

      Change to java.nio.channels.AsynchronousByteChannel :

            * @throws  IllegalArgumentException
      -     *          If the buffer is read-only
      +     *          If the buffer is read-only or a view of a {@link MemorySegment}
      +     *          allocated from a {@linkplain Arena#ofConfined() thread-confined arena}
            * @throws  ReadPendingException
            *          If the channel does not allow more than one read to be outstanding
            *          and a previous read has not completed
      @@ -128,7 +131,8 @@ <A> void read(ByteBuffer dst,
            * @return  A Future representing the result of the operation
            *
            * @throws  IllegalArgumentException
      -     *          If the buffer is read-only
      +     *          If the buffer is read-only or a view of a {@link MemorySegment}
      +     *          allocated from a {@linkplain Arena#ofConfined() thread-confined arena}
            * @throws  ReadPendingException
            *          If the channel does not allow more than one read to be outstanding
            *          and a previous read has not completed
      @@ -177,6 +181,9 @@ <A> void read(ByteBuffer dst,
            * @param   handler
            *          The completion handler object
            *
      +     * @throws  IllegalArgumentException
      +     *          If the buffer is a view of a {@link MemorySegment} allocated from a
      +     *          {@linkplain Arena#ofConfined() thread-confined arena}
            * @throws  WritePendingException
            *          If the channel does not allow more than one write to be outstanding
            *          and a previous write has not completed
      @@ -205,6 +212,9 @@ <A> void write(ByteBuffer src,
            *
            * @return A Future representing the result of the operation
            *
      +     * @throws  IllegalArgumentException
      +     *          If the buffer is a view of a {@link MemorySegment} allocated from a
      +     *          {@linkplain Arena#ofConfined() thread-confined arena}

      Change to java.nio.channels.AsynchronousSocketChannel :

            * @throws  IllegalArgumentException
      -     *          If the buffer is read-only
      +     *          If the buffer is read-only or a view of a {@link MemorySegment}
      +     *          allocated from a {@linkplain Arena#ofConfined() thread-confined arena}
            * @throws  ReadPendingException
            *          If a read operation is already in progress on this channel
            * @throws  NotYetConnectedException
      @@ -488,7 +491,8 @@ public final <A> void read(ByteBuffer dst,
            *          If the pre-conditions for the {@code offset}  and {@code length}
            *          parameter aren't met
            * @throws  IllegalArgumentException
      -     *          If the buffer is read-only
      +     *          If any of the buffers is read-only or a view of a {@link MemorySegment}
      +     *          allocated from a {@linkplain Arena#ofConfined() thread-confined arena}
            * @throws  ReadPendingException
            *          If a read operation is already in progress on this channel
            * @throws  NotYetConnectedException
      @@ -538,6 +542,9 @@ public abstract <A> void read(ByteBuffer[] dsts,
            * @param   handler
            *          The handler for consuming the result
            *
      +     * @throws  IllegalArgumentException
      +     *          If the buffer is a view of a {@link MemorySegment} allocated from
      +     *          a {@linkplain Arena#ofConfined() thread-confined arena}
            * @throws  WritePendingException
            *          If a write operation is already in progress on this channel
            * @throws  NotYetConnectedException
      @@ -552,6 +559,7 @@ public abstract <A> void write(ByteBuffer src,
                                          CompletionHandler<Integer,? super A> handler);
      
           /**
      +     * @throws  IllegalArgumentException       {@inheritDoc}
            * @throws  WritePendingException          {@inheritDoc}
            * @throws  NotYetConnectedException
            *          If this channel is not yet connected
      @@ -568,6 +576,7 @@ public final <A> void write(ByteBuffer src,
           }
      
           /**
      +     * @throws  IllegalArgumentException    {@inheritDoc}
            * @throws  WritePendingException       {@inheritDoc}
            * @throws  NotYetConnectedException
            *          If this channel is not yet connected
      @@ -638,6 +647,9 @@ public final <A> void write(ByteBuffer src,
            * @param   handler
            *          The handler for consuming the result
            *
      +     * @throws  IllegalArgumentException
      +     *          If any of the buffers is a view of a {@link MemorySegment}
      +     *          allocated from a {@linkplain Arena#ofConfined() thread-confined arena}

      Change to java.nio.channels.AsynchronousFileChannel :

            * @throws  IllegalArgumentException
      -     *          If the position is negative or the buffer is read-only
      +     *          If the position is negative, or the buffer is read-only or a view of a
      +     *          {@link MemorySegment} allocated from a {@linkplain Arena#ofConfined()
      +     *          thread-confined arena}
            * @throws  NonReadableChannelException
            *          If this channel was not opened for reading
            */
      @@ -728,7 +732,9 @@ public abstract <A> void read(ByteBuffer dst,
            * @return  A {@code Future} object representing the pending result
            *
            * @throws  IllegalArgumentException
      -     *          If the position is negative or the buffer is read-only
      +     *          If the position is negative, or the buffer is read-only or a view of a
      +     *          {@link MemorySegment} allocated from a {@linkplain Arena#ofConfined()
      +     *          thread-confined arena}
            * @throws  NonReadableChannelException
            *          If this channel was not opened for reading
            */
      @@ -759,7 +765,9 @@ public abstract <A> void read(ByteBuffer dst,
            *          The handler for consuming the result
            *
            * @throws  IllegalArgumentException
      -     *          If the position is negative
      +     *          If the position is negative or the buffer is a view of a {@link
      +     *          MemorySegment} allocated from a {@linkplain Arena#ofConfined()
      +     *          thread-confined arena}
            * @throws  NonWritableChannelException
            *          If this channel was not opened for writing
            */
      @@ -795,7 +803,9 @@ public abstract <A> void write(ByteBuffer src,
            * @return  A {@code Future} object representing the pending result
            *
            * @throws  IllegalArgumentException
      -     *          If the position is negative
      +     *          If the position is negative or the buffer is a view of a {@link
      +     *          MemorySegment} allocated from a {@linkplain Arena#ofConfined()
      +     *          thread-confined arena}

            alanb Alan Bateman
            alanb Alan Bateman
            Brian Burkhalter, Jaikiran Pai
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: