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}
- csr of
-
JDK-8358958 (aio) AsynchronousByteChannel.read/write should throw IAE if buffer is thread-confined
-
- Resolved
-