Avoid unnecessary volatile reads
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientH2PrefaceHandler.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientH2PrefaceHandler.java
index 9730b3a..41d3800 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientH2PrefaceHandler.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientH2PrefaceHandler.java
@@ -104,7 +104,10 @@
ioSession.setEvent(SelectionKey.OP_WRITE);
}
- private void writeOutPreface(final IOSession session) throws IOException {
+ /**
+ * @return true if the entire preface has been written out
+ */
+ private boolean writeOutPreface(final IOSession session, final ByteBuffer preface) throws IOException {
if (preface.hasRemaining()) {
session.write(preface);
}
@@ -115,8 +118,9 @@
if (inBuf != null) {
inBuf.clear();
}
- preface = null;
+ return true;
}
+ return false;
}
@Override
@@ -131,8 +135,11 @@
if (initialized.compareAndSet(false, true)) {
initialize();
}
+ final ByteBuffer preface = this.preface;
if (preface != null) {
- writeOutPreface(session);
+ if (writeOutPreface(session, preface)) {
+ this.preface = null;
+ }
} else {
throw new ProtocolNegotiationException("Unexpected output");
}
@@ -146,8 +153,11 @@
}
inBuf.put(src);
}
+ final ByteBuffer preface = this.preface;
if (preface != null) {
- writeOutPreface(session);
+ if (writeOutPreface(session, preface)) {
+ this.preface = null;
+ }
} else {
throw new ProtocolNegotiationException("Unexpected input");
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/AbstractCharDataConsumer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/AbstractCharDataConsumer.java
index efd7a44..d89104a 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/AbstractCharDataConsumer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/AbstractCharDataConsumer.java
@@ -111,6 +111,7 @@
}
private CharsetDecoder getCharsetDecoder() {
+ CharsetDecoder charsetDecoder = this.charsetDecoder;
if (charsetDecoder == null) {
Charset charset = this.charset;
if (charset == null) {
@@ -120,6 +121,7 @@
charset = StandardCharsets.UTF_8;
}
charsetDecoder = charset.newDecoder();
+ this.charsetDecoder = charsetDecoder;
if (charCodingConfig.getMalformedInputAction() != null) {
charsetDecoder.onMalformedInput(charCodingConfig.getMalformedInputAction());
}
@@ -134,6 +136,7 @@
public final void consume(final ByteBuffer src) throws IOException {
final CharsetDecoder charsetDecoder = getCharsetDecoder();
while (src.hasRemaining()) {
+ ByteBuffer byteBuffer = this.byteBuffer;
if (byteBuffer != null && byteBuffer.position() > 0) {
// There are some left-overs from the previous input operation
final int n = byteBuffer.remaining();
@@ -159,6 +162,7 @@
// in case of input underflow src can be expected to be very small (one incomplete UTF8 char)
if (byteBuffer == null) {
byteBuffer = ByteBuffer.allocate(Math.max(src.remaining(), 1024));
+ this.byteBuffer = byteBuffer;
}
byteBuffer.put(src);
}