From afd67a0deb0a48b9ada53fde850ba102b214e0f2 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Wed, 15 Feb 2023 15:38:39 +0100 Subject: [PATCH] Fix DataBufferUtils::write AsynchronousFileChannel race condition See gh-29943 --- .../core/io/buffer/DataBufferUtils.java | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java b/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java index 17d131313050..c4a94bffd5dd 100644 --- a/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java +++ b/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java @@ -1159,23 +1159,22 @@ protected void hookOnComplete() { @Override public void completed(Integer written, Attachment attachment) { - this.writing.set(false); - attachment.iterator().close(); + DataBuffer.ByteBufferIterator iterator = attachment.iterator(); + iterator.close(); long pos = this.position.addAndGet(written); ByteBuffer byteBuffer = attachment.byteBuffer(); - DataBuffer.ByteBufferIterator iterator = attachment.iterator(); + if (byteBuffer.hasRemaining()) { - this.writing.set(true); this.channel.write(byteBuffer, pos, attachment, this); } else if (iterator.hasNext()) { ByteBuffer next = iterator.next(); - this.writing.set(true); this.channel.write(next, pos, attachment, this); } else { - sinkDataBuffer(attachment.dataBuffer()); + this.sink.next(attachment.dataBuffer()); + this.writing.set(false); Throwable throwable = this.error.get(); if (throwable != null) { @@ -1192,15 +1191,12 @@ else if (this.completed.get()) { @Override public void failed(Throwable exc, Attachment attachment) { - this.writing.set(false); attachment.iterator().close(); - sinkDataBuffer(attachment.dataBuffer()); - this.sink.error(exc); - } + this.sink.next(attachment.dataBuffer()); + this.writing.set(false); - private void sinkDataBuffer(DataBuffer dataBuffer) { - this.sink.next(dataBuffer); + this.sink.error(exc); } @Override